0

I have set up an async query in javascript. I am able to send a list item and get the column values back. However, is there any way to send the webpart object itself or an entire list object so that I can process multiple items.

Here is what I have that works;

<script type="text/javascript">

function clickMethod_Mailto() {

  var ctx = SP.ClientContext.get_current();
  var listId = SP.ListOperation.Selection.getSelectedList(ctx); //selected list Id
  var items = SP.ListOperation.Selection.getSelectedItems(ctx); //selected Items Ids
  var list = ctx.get_web().get_lists().getById(listId);

  var i;

  mailto ='';
   for (i in items)
   {
     targetListItem = list.getItemById(items[i].id);
     ctx.load(targetListItem);
     ctx.executeQueryAsync(Function.createDelegate(this, this.OnSuccess), Function.createDelegate(this, this.OnFailure));
  }

}

function OnSuccess() {
  alert(targetListItem.get_item('Mailto'));  
}

function OnFailure() {
 alert('Request failed. \nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
}


</script>

<input id="clickMe" type="button" value="E-Mail Selected" onclick="clickMethod_Mailto();" />

However, I run into the problem that the async query will run multiple times. I want to put the loop part inside the async call using something like;

ctx.load(ctx);

But this fails.

So what can I pass to an async call? Are there any limits on what can or can't be passed via the .load method.

This is related to a my previous question here but using a different approach to the one I requested help on.

Any help gratefully appreciated.

unibod50
  • 270
  • 1
  • 9
  • Please check here link Hope this helps. – Anupam Jagatdeo May 14 '18 at 11:18
  • @AnupamJagatdeo this looks just what I need but I am struggling with its implementation. I have a button that calls my javascript. <input id="clickMe" type="button" value="E-Mail Selected" onclick="clickMethod_Mailto();" /> How do I call the getSelectedItems().then(function(items){..}? – unibod50 May 14 '18 at 13:37
  • 1
    Try building a CAML query in the for loop and then using that to get all the items you need in a single executeQueryAsync. Alternatively, try using REST instead of JSOM. Building the $filter would be a lot more simple than a CAML query. – wjervis May 14 '18 at 15:00

2 Answers2

1

I have managed to get it all working by some trial and error and a trawl of the web.

<script type="text/javascript">
function getMailto() {

      var ctx = SP.ClientContext.get_current();
      var splist = ctx.get_web().get_lists().getByTitle("LU_Mailto");
      var items = SP.ListOperation.Selection.getSelectedItems(ctx); //selected Items Ids

      var i;

      //Construct the CAML query using ids of items selected
      var qryString ="<View><Query><Where><In><FieldRef Name='ID' /><Values>";
      for (i in items)
      {
        qryString = qryString + "<Value Type='Integer'>" + items[i].id + "</Value>";
      }
      qryString = qryString + "</Values></In></Where></Query></View>"

      //Generate the CAML query
      var query = new SP.CamlQuery();
      query.set_viewXml(qryString);
      this.qryItems = splist.getItems(query);

      //Load CAML query and run Async
      ctx.load(qryItems);
      ctx.executeQueryAsync(Function.createDelegate(this, OnSuccess), Function.createDelegate(this, OnError));

    }

    function OnSuccess() {

      //Construct the mailto string from caml query results
      mailto = '';
      for (var j = 0; j < qryItems.get_count(); j++) {
         mailto = mailto + qryItems.itemAt(j).get_item('Mailto') + ';';
      }
      //Open the outlook application with the To = mailto          
      window.location.href = "mailto:" + mailto;
    }

    function OnError() {
    alert("Failure");
    }

    </script>

    <input id="clickMe" type="button" value="E-Mail Selected" onclick="getMailto();" />
unibod50
  • 270
  • 1
  • 9
0

I guess something like this should work:

function clickMethod_Mailto(){
var dfd = $.Deferred(function () {
   var context = SP.ClientContext.get_current();
   var listId = SP.ListOperation.Selection.getSelectedList();
   var selectedItemIds = SP.ListOperation.Selection.getSelectedItems(context);
   var list = context.get_web().get_lists().getById(listId);
   var listItems = [];
   for (idx in selectedItemIds)
   {
      var item = list.getItemById(parseInt(selectedItemIds[idx].id));
      listItems.push(item);
      context.load(item);
   }
   context.executeQueryAsync(
     function() {
        dfd.resolve(listItems);
     },
     function (sender, args) {
           dfd.reject(args.get_message());
     }
   ); 
});return dfd.promise();
}
clickMethod_Mailto().then(function(items){
var mailTo;
for (var i =0 ; i < items.length;i++)
{
 mailTo += items[i].get_item('Title') + ";";
}
}); 

Have a try and let me know