My intent is to dynamically create a grouping of EditControlBlock (List Item Menu) custom actions for two different list view pages.
Upon loading the Active page, all custom actions are destroyed, and only those necessary for the Active view of this particular library are recreated. Meaning, only items marked as active appear in this list view, so I want the custom actions available to be only those relating to an active item.
The same would happen on the Inactive page but only custom actions related to Inactive items would appear in this list.
The issue I'm facing is that quite often, executeQueryAsync fails to run either success or failure functions as the method call suggests it should. The query is executed and the request seems to go off into infinity never to return (I know, I know not quite).
I've verified this erratic through a number of page-reloads. Every time the page reloads the code is executed again, with the desired result to see all the Active custom actions added to the ECB.
About 50% of the time I see all of them. The other 50% of the time I see between 3 and 7 of the items I've attempted to add.
This code is in a script linked to the master page:
function createTendersCustomActions(action) {
var siteUrl = L_Menu_BaseUrl;
var context = new SP.ClientContext.get_current();
this.listRef = context.get_web().get_lists().getByTitle('Tenders');
var collUserCustomAction = listRef.get_userCustomActions();
var oUserCustomAction = collUserCustomAction.add();
oUserCustomAction.set_location('EditControlBlock');
oUserCustomAction.set_sequence(action.sequence);
oUserCustomAction.set_title(action.title);
oUserCustomAction.set_url('javascript:alert(' + action.workflow +')');
oUserCustomAction.update();
context.load(listRef, 'Title' ,'UserCustomActions');
context.executeQueryAsync(Function.createDelegate(this, onQuerySucceeded), Function.createDelegate(this, onQueryFailed));
function onQuerySucceeded() {
console.log('Custom action ' + action.title + ' created for ' + this.listRef.get_title());
}
function onQueryFailed(sender, args) {
console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
}
function deleteTendersCustomActions() {
var siteUrl = L_Menu_BaseUrl;
var context = new SP.ClientContext.get_current();
this.listRef = context.get_web().get_lists().getByTitle('Tenders');
this.collUserCustomActions = listRef.get_userCustomActions();
//delete all Custom Actions
collUserCustomActions.clear();
context.load(collUserCustomActions);
context.executeQueryAsync(Function.createDelegate(this, onQuerySucceeded), Function.createDelegate(this, onQueryFailed));
function onQuerySucceeded() {
}
function onQueryFailed(sender, args) {
console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}
}
var tendersCustomActions_Active =
[
{ "workflow" : "Assign To", "title" : "Assign To", "sequence" : "0" },
{ "workflow" : "Log Check In", "title" : "Log Check In", "sequence" : "1" },
{ "workflow" : "Log Check Out", "title" : "Log Check Out", "sequence" : "2" },
{ "workflow" : "Mark as Issued", "title" : "Issue", "sequence" : "3" },
{ "workflow" : "Mark as Closed", "title" : "Mark as closed", "sequence" : "4" },
{ "workflow" : "Make Inactive", "title" : "Make Inactive", "sequence" : "5" },
{ "workflow" : "Mark as Cancelled", "title" : "Cancel", "sequence" : "6" },
{ "workflow" : "Mark as On Hold", "title" : "Mark as On Hold", "sequence" : "7" },
];
var tendersCustomActions_Inactive =
[
{ "workflow" : "Make Active", "title" : "Assign To", "sequence" : "0" },
];
function addTendersCustomItems_Active() {
for (var i = 0; i < tendersCustomActions_Active.length-1; i = i+1) {
createTendersCustomActions(tendersCustomActions_Active[i]);
}
}
function addTendersCustomItems_Inactive() {
for (var i = 0; i < tendersCustomActions_Inactive.length-1; i = i+1) {
createTendersCustomActions(tendersCustomActions_Inactive[i]);
}
}
And in the webpage in a hidden WebPart; executes every time this particular page loads:
<script type="text/javascript">
ExecuteOrDelayUntilScriptLoaded(deleteTendersCustomActions, "sp.js");
ExecuteOrDelayUntilScriptLoaded(addTendersCustomItems_Active, "sp.js");
</script>
I have read multiple cases of similar sort of behavior and yet I have also heard of others successfully using the SharePoint JavaScript Object Model to execute multiple asynchronous queries without a hitch.
I should let it be known I'm using IE8, the current standard in the organization.
I've been told, by a SharePoint system admin here, that using JavaScript to work with SharePoint objects is unreliable and is not to be trusted.
This might be so, but I would really like to know: What explains this erratic behavior? Is the server configured to throttle the queries coming through the JavaScript object model? Are the requests getting lost within network traffic?