Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

In visual studio I have added lookup field (SubMenuItemIdRefTitle) to list definition listA that references ListB. I have also added

 <ViewFields>
      <FieldRef Name="Attachments"></FieldRef>
      <FieldRef Name="LinkTitle"></FieldRef>
      <!--  here is our lookup field-->
      <FieldRef Name="SubMenuItemIdRefTitle"> </FieldRef>

      <!-- additional  fields held in ListB obtained via the lookup  -->
      <FieldRef Name="SubMenuItemIcon"> </FieldRef> 
    </ViewFields>

OK... I can even go to the edit item properties in an item (in ListA) and automagically all the other fields in List B appear as a result of my additional ViewField entry ( well I assume this the mechanism).

Now my issue... In csom I can pull in Title from ListA but

  while (enumerator.moveNext()) 
    {
        var listItem = enumerator.get_current();

        // useful to list output here.

        markup += 'Item Title: ' + listItem.get_item('Title') + '<br>';

       // next we determine if the lookup field is held in a referenced spitem object
       var listBItem listItem.get_item('SubMenuItemIdRefTitle');
       Object.prototype.toString.call(listBItem) // this shows we have an [Object Object]


        /// Now what!!!!!!!!!!!!!!!!!!!
        I have tried ListBItem.get_item('Title') 
        TypeError: listBItem.get_item is not a function
       [Break On This Error]    

I am tempted to break the lookup and do a caml join on both lists ... seems so much less risky

share|improve this question

2 Answers 2

In your example you use list B and list A which are difficult to follow in the code examples. In my example I'll use these two fictional lists:

  • List Project (Title, ProductOwner)
  • List TimeReport (Hours, Date, Project:Title)

One can load a time report and see the corresponding Project Title. Say, we want to load the whole lookup item and see even ProductOwner of the Project for a particular TimeReport.

This gets all the context and lists:

var ctx = SP.ClientContext.get_current();
var web = ctx.get_web();
var lists = web.get_lists();
var listTimeReport = lists.getByTitle("TimeReport");
var listProject = lists.getByTitle("Project");

//just get the first item
var timereport1 = listTimeReport.getItemById(1);
ctx.load(timereport1);
ctx.executeQueryAsync();

Lookup Field in JSOM

A lookup field in a JSOM SP.ListItem is an object (that's why toString() outputs [Object Object]), which contains different fields:

var lookupField = timereport1.get_item("Project");

To get the actual value of the lookup field, the function called get_lookupValue has to be invoked. This gets the lookup field: the field from the other list, in many cases just Title, but it can be anything.

var lookupTitle = lookupField.get_lookupValue();

enter image description here

Other fields from the lookup item in JSOM

Maybe only the lookup field isn't enough. In the standard listviews we can click on the lookup field to open the list item from the lookup list. To do so in JSOM, we have to load this lookup item separately. There we the have the lookup id:

var lookupId = lookupField.get_lookupId();

With this id we can load the whole item. Of couse, we can use the CAML to get only fields we want. We can even load a bunch of lookup items at the same time. But in this simple example we load only one item:

var projectItem = listProject.getItemById(lookupId);
ctx.load(projectItem)
ctx.executeQueryAsync()

When we have loaded the the whole or parts of the corresponding project item, we can get all the fields from the project information, e.g. ProductOwner:

var productOwner = projectItem.get_item("ProductOwner");

The original code example

Here is an example of getting the title of the lookup field and the whole lookup item (with all fields):

Here is the original code example with List A and List B:

var ctx = SP.ClientContext.get_current();
var web = ctx.get_web();
var lists = web.get_lists();
var listB = lists.getByTitle("ListB");
var listA = lists.getByTitle("ListA");

//just get the first item
var listBItem = listB.getItemById(1);
ctx.load(listBItem)
ctx.executeQueryAsync(function() {
    var listAItem = item.get_item("SubMenuItemIdRefTitle");
    var listAItemId = listAItem.get_lookupId();
    var title = listAItem.get_lookupValue();
    alert(title);
    var fullListAItem = listA.getItemById(listAItemId)
    ctx.load(fullListAItem)
    ctx.executeQueryAsync({
        var modified = fullListAItem.get_item("Modified");
        alert("Success. For example, we can get the Modified field of the lookup field: "
             + modified);
    }); 
});

No error handling is provided for brevity. The id of the first item is hardcoded (1) just to simplify the example.

share|improve this answer
    
thanks very much for this I stared a long time at your code then figured you had got your list A Item and list B Items around the wrong way - which is very easily done I might add so –  westerdaled Mar 11 '13 at 14:51
3  
ListA or ListB. These are the details which are not relevant in this answer. You could have asked me for adjusting my answer instead of reposting me. Check out SharePoint stackexchange faq –  Anatoly Mironov Mar 11 '13 at 22:51
    
apologies for not requesting you adjust your answer. I did however, try to make it clear that the overall success was a result of your input as without I would not have moved on with project. –  westerdaled Mar 12 '13 at 8:49
    
It is allright! You are welcome to SharePoint StackExchange. It the beginning it is hard to know, how questions and answers work here. It is a big difference to forums. It is better to edit an answer so that the people in the future can benefit and find answers. –  Anatoly Mironov Mar 12 '13 at 9:10

@Anatoly. Here is the final code which now thanks to your help brings back one or more field values. I figured you were on the right lines but had got the ListA item and list B item around the wrong way. To prove this theory I code up a real function "testAnatolyCode(user)" which I referenced in a link in the master page. Below is most of it.

    var listA = context.get_web().get_lists().getByTitle('ListA');

    // the lookeduplist
    var listB = context.get_web().get_lists().getByTitle('ListB');


    //Create a new CAML query
    var caml = new SP.CamlQuery();

    // get the first entry in our user favourites list aka ListA
    var listAItem = listA.getItemById(1);
    context.load(listAItem);


   context.executeQueryAsync(function() { 

        var listBItem =  listAItem.get_item('SubMenuItemIdRefTitle');

        // both the id and the  value of the lookup field
        var listBItemId = listBItem.get_lookupId();
        var listBItemValue = listBItem.get_lookupValue()

         markup += "Lookup Item Id (Title) " + listBItemId + '<br>';
         markup += "ID value " + listBItemValue + '<br>';

         // now bring in all the fields from list B
         var fullListBItem = listB.getItemById(listBItemId);
         context.load(fullListBItem)
         context.executeQueryAsync(function() { 
             // instead of 'Modified' I used the field needed to impress the project manager ;-)
            var subMenuItemIcon = fullListBItem.get_item('SubMenuItemIcon');
              markup += "submenuIcon from List B " + subMenuItemIcon
               + '<br>';
                displayDiv.innerHTML = markup; 

         });
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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