0

I am using a JavaScript button to set a Field-2 on each selected list item from "false" to "true". It first checks if Field-1 is empty, and if it is, sets Field-2 to true. The relevant code is as follows:

function ApproveAllSelected() {
this.context = SP.ClientContext.get_current();
var selectedItems = SP.ListOperation.Selection.getSelectedItems(context);
var list = context.get_web().get_lists().getByTitle("List Title Here");
this.items = [];
var item;
for (item in selectedItems) {
var approvalItem = list.getItemById(selectedItems[item].id);
items.push(approvalItem);
context.load(approvalItem, "Field1", "Field2");
}
context.executeQueryAsync(Function.createDelegate(this, this.OnSuccess), OnFailed);
window.location = document.location;
window.location.href = window.location;
}

function OnSuccess(sender, args) {
for (var j = 0; j < this.items.length; j++) {
    var value = this.items[j].get_item("Field2");
    if (value == null)
        {
        this.items[j].set_item("Field1", 1);
        this.items[j].update();
        this.context.executeQueryAsync();
        }
    }
}

The strange thing is, this code is successful, but seems to only be successful on 4-5 list items at once. If I select 20 list items and then hit the button, only 4-5 have Field-2 set successfully, and the other list items act as if nothing happened. Other times, nothing in the list changes. I am refreshing the list between tries as well.

There are no errors thrown from either On-failed or in my SharePoint ULS logs. I see no JavaScript errors on the page in my browser debugger, either.

If I continuously re-select the items and press the approval button over and over, the items will eventually all be marked as "true".

  • 1
    First off, you should not use the for..in looping construct to iterate collections in JavaScript. It does not do what you think it does. Use a plain old for loop instead. – Derek Gusoff Jun 11 '14 at 15:52
  • Thank you for your input. I do not have much experience with Javascript and I guess it shows here. It looks like for...in has a very specific use. I will switch it to a regular for loop. – user11457 Jun 11 '14 at 22:55
  • 1
    @DerekGusoff I had the same thought, but the SP.ListOperation.Selection.getSelectedItems(context); actually returns a map so that is actually the appropriate way to iterate the items. – onzur Jun 13 '14 at 20:33
1

In the OnSuccess function, the final call to executequeryasync should be after the for loop.

Otherwise your code seems okay, this might also be a logic issue. Why do you check if your value == null? can it be undefined? You can use if(value) instead.

if(!value){ //code here }
  • I will try swapping the positioning of the executeQueryAsync tomorrow. The if statement check is actually for a different field. I am conditionally setting field 1 to true if field 2 is blank. – user11457 Jun 11 '14 at 22:57
  • This actually solved the issue. It seems that running multiple "executequeryasync" so quickly caused issues on the server side and locked things up. Thanks, I appreciate the help. – user11457 Jun 12 '14 at 14:24
1

Have you tried giving out the for-loop index? often there's the problem that the loop continues while your editing hasn't completed and then the next update is with a index a few higher than what you would think it should be.

That's because javascript is working async and not waiting for anything to finish until the loop goes into the next step.

  • I will try printing out the index and make sure it hits everything--I am assuming this is what you mean. – user11457 Jun 11 '14 at 22:58
  • yes this is what I mean, if every update is really executed and not only some of them. – Gwny Jun 12 '14 at 6:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for?Browse other questions tagged or ask your own question.