5

I am trying to extract the ListItem ID of a List which I am currently NOT in based on a field value in that List. I cant find anything that explains how to do this.

So, to explain. I have a Custom List called 'Department'. I have another Custom List called 'Article'. I have a field in the 'Article' List which is a Lookup to the 'Title' field in the 'Department' List

I have some JavaScript which reads the DispForm of an 'Article' in the 'Article List' and pulls out the Department as a text string. Now using this text string I want to use JavaScript to look in the 'Department' List, find the 'Title' field value which matches the text string (e.g. Finance) and return the Item ID of this List Item.

All solutions I can find on the web connect to the List using the 'getItemById' method, but I don't know the ID as that is what i'm trying to return (e.g. below)

var ctx = SP.ClientContext.get_current();
this.web = ctx.get_web();
this.list = web.get_lists().getByTitle("Department");
this.listItem = list.getItemById(x);

Can anyone point me in the right direction on how I would go about doing this?

4

Step 1: If you haven't got SPServices, get it -- it's free and it'll make your life easier. http://spservices.codeplex.com/

Step 2: Here's what I've used to get the ID (assuming Title is unique):

// Define a lookup query that will pull only the records where the Title field is the one we are looking for
var queryLookup = "<Query><Where><Eq><FieldRef Name='Title'/><Value Type='Text'>"+projectNumber +"</Value></Eq></Where></Query>";
var itemID="";

// Call GetListItems to return the ID
$().SPServices({
    operation: "GetListItems",
    async: false,
    listName: "My Listname",
    CAMLViewFields: "<ViewFields><FieldRef Name='ID'/></ViewFields>",
    CAMLQuery: queryLookup,
    completefunc: function(xData,Status) { 
        itemID = $(xData.responseXML.xml).find("z\\:row").attr("ows_ID");
      } 
   });

   // Now itemID contains the ID of the matching record
  alert("itemID="+itemID);

If Title is not unique, use a query that is guaranteed to produce a unique answer or add an each() function inside the completefunc.

If you can't get SPServices for some reason, you can make a direct call to GetListItems, doing essentially the same thing, but more work on your part: https://msdn.microsoft.com/en-us/library/lists.lists.getlistitems.aspx

  • Now this is cool and I do have SPServices but I cant get it to execute for some reason. Ive added into my solution file and referenced it in the Element.xml but it doesnt seem to run! – Rick Lister Feb 26 '15 at 14:20
  • 1
    Ok.. I can get this to run on any page BUT the DispForm.aspx.. Any ideas why this is??? – Rick Lister Feb 26 '15 at 15:07
  • 1
    I'm kinda new at this, and I have to admit I don't know what Element.xml is. What I do is the List/Library Tools -> Form Web Parts -> Default Display Form, add a Content Editor Web part that points to a file in a Code library on my site. This has worked for me. – Francoise Becker Feb 26 '15 at 17:13
3

One thing you can do is use SP.List.getItems(query) to query the 'Department' list for the item with the Title value you want. Once you get the list item, you can get its ID. (Keep in mind that the getItems(query) method will return a list item collection, even though that collection may only contain one item.)

Your CAML query would look something like

<View>
    <Query>
        <Where>
            <Eq>
                <FieldRef Name='Title'/>
                <Value Type='Text'>your title string</Value>
            </Eq>
        </Where>
    </Query>
</View>

However, if it's a lookup field on the 'Article' item, wouldn't that already have the ListItemID of the 'Department' item?

3

Based on your question, i understand that you want to get ID of Department item which is referenced in Article list. Correct me if i am wrong.

To get ID of lookup list item, include following in you code(Assuming field name of lookup field from Department is "Department" in article list :

var childIdField = listItem["Department"] as FieldLookupValue;

if (childIdField != null)
{
    var childId_Value = childIdField.LookupValue;
    var childId_Id = childIdField.LookupId;
}

If Field is MultiLookup, include following code:

var childIdField = listItem["Department"] as FieldLookupValue[];

if (childIdField != null)
{
    foreach(var lookupValue in childIdField)
    {
        var childId_Value = lookupValue.LookupValue;
        var childId_Id = lookupValue.LookupId;
    }
}

You will have Item ID of Department List in variable childId_Id

Using Javascript

//Get LookupField value

var childIdField = listItem.get_item('Department');
var catLabel = childIdField.get_lookupValue();
var childId_Id = childIdField.get_lookupId();

//Multiple Lookup

var childIdField  = listItem.get_item('Department'); 

for(var i = 0; i < childIdField.length; i++) {

  var categoryValue = childIdField[i];
  var catLabel = categoryValue.get_lookupValue();
   var childId_Id = categoryValue.get_lookupId();

}
  • 2
    This looks suspiciously like C#, and the OP is asking for an answer in JavaScript. :) – Dylan Cristy Feb 25 '15 at 18:26
2

Ok, thanks for all the help everyone. It was a good insight into how to go about doing what I wanted. The closest way I could get to 'almost' work was Francoise Becker's idea using SPServices jQuery library, however I think ive discovered that in the DISPFORM.aspx, the code behind is different to other pages as I couldnt get the code to run when the DispForm.aspx was loaded.

So, I began to look into another method of doing it from an idea I had seen to grab the general text from a DispForm.aspx.

What I did was I created a variable and a command to search the <h3> tag on your page, to get the enclosing <td> tag and store it in the variable:

deptString = $('h3:contains("Department")').closest('td').next('td').html();

Then I ran the javascript 'SubString' method on the captured html to get the ID=x& of the root Department lookup:

deptString = deptString.substring(deptString.indexOf('ID='), 1 + deptString.lastIndexOf('&'));

Lastly I used the 'slice' method to extract just the ID value from the string that was left:

myDept = deptString.slice(3, 4);

This leaves me with the ID!

Maybe not the cleanest of quickest method, but it works for me. Hope this and the other methods help anyone else who may require this functionality.

  • Doing something similar and this worked. It seems like there should be a more direct and easier way to do it. – Rothrock Feb 26 '15 at 21:08
1

The lookup field in SharePoint internally always looks like

ID;#Value

example

10;#ItTeam

So in field 'Article' You already have ID of target element in 'Department'. So You should parse it using jQuery getter(or see how Your existing JS function does it), and query ListItem element by this Id.

1

As Dylan Cristy suggested, you'll need to execute a CAML query to pull back just the items where the Title field is equal to the value you're looking for.

Here's the syntax for doing that in the JavaScript client side object model:

var title = "My Item Title"; // the title of the item you're looking for
var ctx = SP.ClientContext.get_current();
this.web = ctx.get_web();
this.list = web.get_lists().getByTitle("Department");
var camlQuery = new SP.CamlQuery();
camlQuery.set_viewXml("<View><Query><Where><Eq><FieldRef Name='Title' /><Value Type='Text'>"+title+"</Value></Eq></Where></View>");
var items = list.getItems(camlQuery);
ctx.load(items);
clientContext.executeQueryAsync(Function.createDelegate(this,function(){ 
    var itemEnumerator = items.getEnumerator();
    while(itemEnumerator.moveNext()){
        var item = itemEnumerator.get_current();
        // You now have the item you were looking for!
    }
},Function.createDelegate(this,function(sender, args){alert(args.get_message());}));
  • 1
    Ive tried this verion bu for some reason i get [object Object] errors on the camlQuery variable. I dont think its connecting to the Client Object. The button Im writing to execute the code is on the Display Page Ribbon of the Article item. That shouldnt make a difference should it? – Rick Lister Feb 26 '15 at 14:22
  • If it were executing on page load, you'd need to wrap it all up in ExecuteOrDelayUntilScriptLoaded(function{ /*your code*/},"SP.JS");, but if it's only running on button-click, the SP library should already be loaded. Can you run the F12 developer tools in Internet Explorer and try running the above code in the console? – Thriggle Feb 26 '15 at 15:33
0

There might be quite a lot of people still searching for the answer....I spend many hours, let this be useful for someone... It worked for me :)



$(function () 
{ SP.SOD.executeFunc('sp.js', 'SP.ClientContext', retrieveListItems); 
}); 

/*
Title string to be passed to search Announcment Title column
*/

var Items="";
var itemtitle = ""; 

function retrieveListItems() 
{ 

     itemtitle = "Value1";
     var clientContext = new SP.ClientContext(); 
     var targetList = clientContext.get_web().get_lists().getByTitle('Announcements');


//Below Query string will fetch the Title column or Any subcolumns based on the string you pass in itemtitle

     var camlQuery = new SP.CamlQuery();
     camlQuery.set_viewXml(""+itemtitle+"");



Items = targetList.getItems(camlQuery);
clientContext.load(Items);



     clientContext.executeQueryAsync(Function.createDelegate(this, this.onQuerySucceeded), Function.createDelegate(this, this.onQueryFailed));
}

function onQuerySucceeded() {

       var itemEnumerator = Items.getEnumerator();
    while(itemEnumerator.moveNext()){
        //The below item will fetch the correct item title from Announcment list
        var item = itemEnumerator.get_current();
        // You can also fetch a second column from the same item
         alert(item.get_item("SubColumn"));

    }



   }

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





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.