1

So I'm creating display templates for SharePoint and I'm having trouble getting the context as I'll need it for accessing different lists and their items, etc. One way to do it that I've seen while searching is this:

var context = Srch.ScriptApplicationManager.get_clientRuntimeContext();

The problem is I don't know how to access the contents from this object. Everytime I'm getting an error that the context is undefined or empty or I print out it's literal function. In other programs (not display templates), I would just use:

var context = new ClientContext(); 

or

var context = new SP.ClientContext();

or some variant, but in this case, I can't find any documentation or examples of using the first. Just (mostly) blogs saying you can use it to get the context.

The code I have is mostly commented out for now. I'm just trying to figure out this context right now. Thanks in advance.

Edit:

This is the whole (item display template) file:

<html lang="en" xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>

    <title>Marketing Page Item Template</title>

    <!--[if gte mso 9]><xml>
    <mso:CustomDocumentProperties>
    <mso:TemplateHidden msdt:dt="string">0</mso:TemplateHidden>
    <mso:MasterPageDescription msdt:dt="string">This is the item display template for the Marketing Page tasks.  This will organize list/items under its practice.</mso:MasterPageDescription>
    <mso:ContentTypeId msdt:dt="string">0x0101002039C03B61C64EC4A04F5361F385106603</mso:ContentTypeId>
    <mso:TargetControlType msdt:dt="string">;#SearchResults;#;#Content Web Parts;#</mso:TargetControlType>
    <mso:HtmlDesignAssociated msdt:dt="string">1</mso:HtmlDesignAssociated>
    <mso:ManagedPropertyMapping msdt:dt="string">'Title'{Title}:'Title','Assigned To'{Assigned To}:'AssignedTo','Due Date'{Due Date}:'DueDateOWSDATE;DueDate','URL'{URL}:'URL'</mso:ManagedPropertyMapping msdt:dt="string">
    </mso:CustomDocumentProperties>
    </xml><![endif]-->

</head>
<body>
    <div>
        <!--#_


        var siteURL = _spPageContextInfo.siteAbsoluteUrl;
        var title = $getItemValue(ctx, "Title");
        var assignedTo = $getItemValue(ctx, "Assigned To");
        var dueDate = $getItemValue(ctx, "Due Date");
        var listUrl = $getItemValue(ctx, "URL");


        SP.SOD.executeFunc('SP.js', 'SP.ClientContext', function() {

            var context = Srch.ScriptApplicationManager.get_clientRuntimeContext();

            var reqCtx = SP.RequestContext.getCurrent(context);
            var web = reqCtx.get_web();

            var pagesListId = SP.PageContextInfo.get_pageListId();
            var list = web.get_lists().getById(pagesListId);
            var items = list.getItems(SP.CamlQuery.createAllItemsQuery());

            context.load(items);

            context.executeQueryAsync(
               function(){
                   items.get_data().forEach(function(item){
                       console.log(item.get_item('FileRef')); 
                   });
               },
            function(sender,args){
              console.log(args.get_message()); 
            });
        });


        _#-->

            <li>

                <div style="background-color: honeydew; margin: 5px; padding: 5px;">

                <!--#_
                    if (!title.isEmpty)
                    {
                _#-->

                    <h3 style="color: coral;">Title: _#= $htmlEncode(title) =#_</h3>
                    <!--<p>_#= $htmlEncode(ctx.CurrentItem.Title) =#_</p>-->

                    <p>URL: _#= $htmlEncode(listUrl) =#_</p>
                    <p>URL: _#= $htmlEncode(typeof reqCtx) =#_</p>


                <!--#_
                    }

                    if (!assignedTo.isEmpty)
                    {
                _#-->

                        <p style="color: goldenrod;">Assigned To: _#= $htmlEncode(assignedTo) =#_</p>
                        <!--<p>_#= $htmlEncode(ctx.CurrentItem.AssignedTo) =#_</p>-->

                <!--#_
                    }

                    else
                    {
                _#-->

                        <p>There is no assigned person!</p>

                <!--#_
                    }

                    if (!dueDate.isEmpty)
                    {
                _#-->

                        <p style="color: rosybrown;">Due Date: _#= $htmlEncode(dueDate) =#_</p>
                        <!--<p>_#= $htmlEncode(ctx.CurrentItem.DueDateOWSDATE) =#_</p>-->

                <!--#_
                    }

                    else
                    {
                _#-->

                            <p>There is no due date!</p>

                <!--#_
                    }
                _#-->

             </div>

            </li>
    </div>
</body>
</html>
LaLaLottie
  • 393
  • 1
  • 4
  • 17

1 Answers1

2

Srch.ScriptApplicationManager.get_clientRuntimeContext function returns SP.ClientRuntimeContext object which represents the runtime context for accessing data from and invoking methods on remote objects

The following example demonstrates how to retrieve list items and print page urls in display template:

var context = Srch.ScriptApplicationManager.get_clientRuntimeContext();

var reqCtx = SP.RequestContext.getCurrent(context);
var web = reqCtx.get_web();

var pagesListId = SP.PageContextInfo.get_pageListId(); //Pages List Id
var list = web.get_lists().getById(pagesListId);
var items = list.getItems(SP.CamlQuery.createAllItemsQuery());
context.load(items);
context.executeQueryAsync(
   function(){
       items.get_data().forEach(function(item){
           console.log(item.get_item('FileRef')); 
       });
   },
   function(sender,args){
      console.log(args.get_message()); 
   });

To ensure SP.ClientRuntimeContext object is loaded you could utilize SP.SOD.executeFunc function, for example:

SP.SOD.executeFunc('SP.js', 'SP.ClientContext', function() {

    var context = Srch.ScriptApplicationManager.get_clientRuntimeContext();

    //the remaining code goes here...


});   

Option 2. Using SP.ClientContext class

The following example demonstrates how to utilize SP.ClientContext class in display template:

 SP.SOD.executeFunc('SP.js', 'SP.ClientContext', function() {

        var context = SP.ClientContext.get_current();
        var web = context.get_web();

        var pagesListId = SP.PageContextInfo.get_pageListId();
        var list = web.get_lists().getById(pagesListId);
        var items = list.getItems(SP.CamlQuery.createAllItemsQuery());
        context.load(items);

        context.executeQueryAsync(
           function(){
               items.get_data().forEach(function(item){
                   console.log(item.get_item('FileRef')); 
               });
           },
        function(sender,args){
          console.log(args.get_message()); 
        });
 });
Vadim Gremyachev
  • 57,952
  • 20
  • 129
  • 193
  • 1
    Thank you for the awesome reply! I updated the post to show the whole code. Now, the problem is with reqCtx - I'm running it through the console and it keeps saying it's undefined. I think it may have to do with adding in scripts/references? What do you think? – LaLaLottie Feb 25 '16 at 21:40
  • Just verified the provided item template and it works for me.. Anyway, the answer has been updated that demonstrates how to utilize `SP.ClientContext class` – Vadim Gremyachev Feb 26 '16 at 13:48
  • This is the exact error message I get about the context: `Uncaught TypeError: Cannot read property 'toString' of undefinedSP.ListCollection.getById @ sp.js?rev=hfV5Po3SUEMXr9lb64ZrsQ%3D%3D:2(anonymous function) @ spr_item.js?ctag=2279$$15.0.4641.1000:36NotifyOnLoad.b @ init.js?rev=rQHvYUfURJXLBpgKnm0dcA%3D%3D:1NotifyOnLoad @ init.js?rev=rQHvYUfURJXLBpgKnm0dcA%3D%3D:1(anonymous function) @ init.js?rev=rQHvYUfURJXLBpgKnm0dcA%3D%3D:1` I think it just has to do with my set up at this point. Again, thank you so much! – LaLaLottie Feb 26 '16 at 15:43
  • And this SharePoint error: `context is not defined (CoreRender: ~sitecollection/_catalogs/masterpage/Display Templates/Search/SPR_Item.js)` – LaLaLottie Feb 26 '16 at 15:45
  • It seems that when I directly use the console (tried both Chrome's and IE's), it prints out exactly as intended. But in my own program, using console.log for either the declared variables (ex. var context = etc.) or just putting it straight in (ex. SP.ClientContext...etc.) produces undefined errors. – LaLaLottie Feb 26 '16 at 17:31
  • Hm, not sure why it happens, maybe another error occurs once the page is loaded and breaks display template JavaScript – Vadim Gremyachev Feb 26 '16 at 17:40
  • 1
    There was an error. So it turns out the reason my context was always undefined was basically I was using the wrong reference. I stopped using `.get_current()` and used a full URL and it now works! So apparently there's a context for the display template itself? Is that correct? Because once I put in the URL, I was able to get the web, list collection, items, etc. Thank you! `var context = new SP.ClientContext('https://...etc.');` – LaLaLottie Feb 26 '16 at 21:23