Question

So here's the javascript I use to display item name of selected item from an external list:

    <script type="text/javascript">
      var targetListItem;
      function ShowSelectedItems() {
      var ctx = SP.ClientContext.get_current();
      var selectedItems = SP.ListOperation.Selection.getSelectedItems(ctx);
      var key;
      for (key in selectedItems) {
         var clientContext = new SP.ClientContext(); 
         var targetList = clientContext.get_web().get_lists().getByTitle('CBSA List');
         targetListItem = targetList.getItemById(selectedItems[key].id);
         clientContext.load(targetListItem, 'Item');
         clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
       }
    }
       function onQuerySucceeded() {

           alert('Request succeeded. \n\nRetrieved Item is: ' + targetListItem.get_item('Item'));

       }

       function onQueryFailed(sender, args) {
         alert('Request failed. \nError: ' + args.get_message() + '\nStackTrace: ' + args.get_stackTrace());
       } 
    </script>
    <a href="#" onclick="javascript:ShowSelectedItems();">Show Items</a>

It works fine if I only select one item, but if I select multiple items it will only display the first item and print this error in console:

SCRIPT5022: The property or field has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested. sp.js, line 2 character 158961

Can someone please help me to troubleshoot this problem?

UPDATE: Here's updated version of the code, unfortunately I'm still getting same error:

<script type="text/javascript">
function ShowSelectedItems() {
    var ctx = SP.ClientContext.get_current();
    var selectedItems = SP.ListOperation.Selection.getSelectedItems(ctx);
    var key, targetListItems = [],index =0;
    for (key in selectedItems) {
       var clientContext = new SP.ClientContext(); 
       var targetList = clientContext.get_web().get_lists().getByTitle('CBSA List');
       var targetListItem = targetList.getItemById(selectedItems[key].id);
       targetListItems[index] = targetListItem;
       clientContext.load(targetListItems[index], 'Item');//load listitem
       index++;
     }
    clientContext.executeQueryAsync(function(){
      var i;
      for(i in targetListItems){
         alert('Request succeeded. \n\nRetrieved Item is: ' + targetListItems[i].get_item('Item'));
      }
    }, function(s,a){alert(a.get_messgae());});
}
    </script>
    <a href="#" onclick="javascript:ShowSelectedItems();">Show Items</a>
Était-ce utile?

La solution

You cannot use executeQueryAsync in a loop, the loop execution does not wait for the execute Query call completion(it is async). So try to load all items once and call 'executeQueryAsync' outside of the loop and also we should not create the clientContext and list objects inside the loop(if so, only the last object inside the loop will have correct context association). Move those statements to top of for loop

    var ctx = SP.ClientContext.get_current();
    var selectedItems = SP.ListOperation.Selection.getSelectedItems(ctx);
    var key, targetListItems = [],index =0;
    var clientContext = new SP.ClientContext(); 
    var targetList = clientContext.get_web().get_lists().getByTitle('CBSA List');
    for (key in selectedItems) {
       var targetListItem = targetList.getItemById(selectedItems[key].id);
       targetListItems[index] = targetListItem;
       clientContext.load(targetListItems[index], 'Item');//load listitem
       index++;
    }
    clientContext.executeQueryAsync(function(){
      //access the 'targetListItems' here. it is an array of SP.ListItem objects,loop through it
    }, function(s,a){alert(a.get_messgae());});

Another workaround

if you are Showing the 'Item' column value on the listview webpart, There is no need to load items from server. Use the following snippet to get the values of 'Item' column

var data = ctx.ListData.Row;// could be ctx2 or ctx3 in your case
var selectedids = SP.ListOperation.Selection.getSelectedItems();

var IdMap = {};

$.map(data,function(item,index){IdMap[item.ID] = item.Item})
var selectedvalues = $.map(selectedids,function(item,index){return IdMap[item.id]})

The 'selectedvalues' returns an array of the 'Item' column values

Licencié sous: CC-BY-SA avec attribution
Non affilié à sharepoint.stackexchange
scroll top