2016-10-23

The next blog post describes how you can create a Load More Results link as the name itself describes, loads more results. The solution is created to be used in a Content Search WebPart.

For this solution you will need to create a new Control Display Template (or you can append it to an existing one).

The first thing to do is to create a reference to jQuery in your Control Display Template (jQuery makes it easier to manipulate the HTML). If it is already loaded in your master page, you do not have to include it in the control template.

The jQuery reference can be referenced in the control like this:

$includeScript(“”, “http://code.jquery.com/jquery-1.10.1.min.js”);

When you want to retrieve more results, you can make use of a function called page. This function is available on the Client Control of the context (ctx.ClientContext.page()). When this function gets called, it’s going to load the next set of results.

The problem I had, was that my previously loaded results were always removed when I called the page function. When the function gets called, the web part retrieves the next set of results, and this causes the Display Templates to render the HTML of the new set of results. So the previous results that were rendered will be gone, and the new results are shown instead.

First time:

  1. Result A
  2. Result B

Second time:

  1. Result C
  2. Result D

What we need is the following:

  1. Result A
  2. Result B
  3. Result C
  4. Result D

Showing the Results

After some testing, I found that the best way is to place the set of results in an element outside the render area of the Control Display Template. To do this, you need to create a new element outside the WebPart body. The element that contains the original set of results will be hidden.

var hiddenElm = $(‘#’+controlId);
var visibleElm = hiddenElm.parents(‘.ms-WPBody:eq(0)’).parent().children(‘#Show-Items’);
// Hide the original set of results
hiddenElm.hide();

// Check if the Visible items element already exists
if (visibleElm.length <= 0) {
// Get the tag name of the element
var tagname = hiddenElm.prop(‘tagName’);
// Box needs to be created before or after the web part,
// otherwise the content will be cleared when new results are retrieved.
hiddenElm.parents(‘.ms-WPBody:eq(0)’).before(‘<‘+tagname+’ id=”Show-Items” class=”+hiddenElm.attr(‘class’)+”></’+tagname+’>’);
visibleElm = hiddenElm.parents(‘.ms-WPBody:eq(0)’).parent().children(‘#Show-Items’);
}

The next step is to append all the items from your result set to the new element. This can be done like this:

// Append all the hidden items to the visible items element
hiddenElm.children().each(function () {
  // Append the items to the visible div
  $(this).appendTo(visibleElm);
});

Adding the Show More Link

Most of the code comes from the Control_ListWithPaging.html Display Template. In that control you have two buttons, a previous and a next button. I only copied the code that was needed for the next button.

// Get the paging information
var pagingInfo = ctx.ClientControl.get_pagingInfo();
var lastPage = pagingInfo[pagingInfo.length -1];
// If the value of pageNumber is equal to -2, more results can be retrieved
var hasNextPage = lastPage.pageNumber == -2;

The last line in the code block is a special one. It checks if the value of lastPage.pageNumber is equal to minus two, and when this condition is met, it means that there are more results that can be loaded.

So by checking the hasNextPage, you can append a Show More Results link after the hidden element, when the value condition is true.

// Append the show more link if a next page is available
if(hasNextPage)
{
hiddenElm.after(‘<a href=”#” id=”‘+controlId+’showmore”>Show More Results</a>’);
}

The last thing is to create and event handler which listens to the click event of the Show More Results link.

// When clicked on the show more link, the new set of results needs to be retrieved
$(‘#’+controlId+’showmore’).click(function () {
// Load the next set of results
ctx.ClientControl.page(lastPage.startItem);
return false;
});

All of this code needs to be executed when the rendering of the results is completed. This can be done with the ctx.OnPostRender method.

ctx.OnPostRender = [];
ctx.OnPostRender.push(function () {
// Place the code here
});

Final Result

Here is the whole script:

var hiddenElmId = $htmlEncode(ctx.ClientControl.get_nextUniqueId() + “_Results_”);
ctx.OnPostRender = [];
ctx.OnPostRender.push(function () {
var hiddenElm = $(‘#’+hiddenElmId);
var visibleElm = hiddenElm.parents(‘.ms-WPBody:eq(0)’).parent().children(‘#Show-Items’);
// Hide the original set of results
hiddenElm.hide();

// Check if the Visible items element already exists
if (visibleElm.length <= 0) {
// Get the tag name of the element
var tagname = hiddenElm.prop(‘tagName’);
// Box needs to be created before or after the web part,
// otherwise the content will be cleared when new results are retrieved.
hiddenElm.parents(‘.ms-WPBody:eq(0)’).before(‘<‘+tagname+’ id=”Show-Items” class=”+hiddenElm.attr(‘class’)+”></’+tagname+’>’);
visibleElm = hiddenElm.parents(‘.ms-WPBody:eq(0)’).parent().children(‘#Show-Items’);
}

// Append all the hidden items to the visible items element
hiddenElm.children().each(function () {
//$(‘#Show-Items’).append($(this).clone(true));

// Append the items to the visible div
$(this).appendTo(visibleElm);
});

// Get the paging information
var pagingInfo = ctx.ClientControl.get_pagingInfo();
var lastPage = pagingInfo[pagingInfo.length -1];
// If the value of pageNumber is equal to -2, more results can be retrieved
var hasNextPage = lastPage.pageNumber == -2;
// Append the show more link if a next page is available
if(hasNextPage)
{
hiddenElm.after(‘<a href=”#” id=”‘+hiddenElmId+’showmore”>Show More Results</a>’);
}

// When clicked on the show more link, the new set of results needs to be retrieved
$(‘#’+hiddenElmId+’showmore’).click(function () {
// Load the next set of results
ctx.ClientControl.page(lastPage.startItem);
return false;
});
});

The list HTML looks like this:

<ul id=”_#=hiddenElmId=#_” class=”cbs-List”>
  _#= ctx.RenderGroups(ctx) =#_
</ul>

Note: you can also place the code from inside the ctx.OnPostRender method in a separate JavaScript file, and reference the file the same way as the jQuery file.

Note 2: I made the code as generic as possible so that this can be used by multiple CSWP on the same page.

About the author 

Elio Struyf

Elio Struyf is a SharePoint Consultant at Xylos, a leading ICT service company, specializing in Systems Integration, Systems Management, Information Worker Solutions (SharePoint Consulting) and Learning.

He has a passion for branding / graphical design, and this is his main focus the last five years in SharePoint. Knowledge sharing and gathering are two of his key triggers to start the day. If you want to know more, you can check out his blog at: http://www.eliostruyf.com