PortiBlog

Add a sorted ‘show more’ link to your searchwebpart

31 juli 2019

You probably have a page somewhere with a webpart that rolls up some search result content from the rest of your SharePoint environment. And if you want to offer your users a ‘show more’ link to easily redirect them to all the results on your search page, you can change your display template to add a 'show more' link.
This can be a static link, but it is much nicer if you do this dynamically by retrieving the search query from your context.

However, this will just let you query the results without any custom sort. To make sure the results are in the same order that the user sees on the homepage you will also need to retrieve the selected sorting from the context. And to make matters more challenging, what if the webpart is configured to show the sort-dropdown so the user can switch sorting? We will make sure to support both in our template, starting with the fallbacksort which can be configured in the webpart's query builder.

Because I am using the ResultScriptWebPart webpart in this example, I need to make a copy of the Control_SearchResults.html display template. This template is the wrapper for the search results and displays the sort-dropdown and the footer for the results. I renamed it Control_SearchResults_showmore.html.

Add the link and retrieve the query

You probably want to show the link at the bottom of your results. So go and find the ‘ms-srch-resultFooter’ div which contains the footer for the webpart.
We only want to display the link if there are more results than are shown in the webpart. So we will need to check the total returned rows (totalrows) are higher than the amount displayed (rowcount).

<!--#_
/*** Start Show More ***/
var totalrows = ctx.DataProvider.get_totalRows();
var rowcount = ctx.DataProvider.get_resultsPerPage();

Then we build up the url to the search results page and retrieve the query from the context. Some characters needs to be replaced to make sure any encoding will not mess up our querystring.

    var searchurl = "/search/Pages/Everything.aspx?k="
var searchquery = $htmlEncode(ctx.ListData.ResultTables[0].Properties.QueryModification);
searchquery = searchquery.replace("&","%26");
searchquery = searchquery.replace(new RegExp(""", 'g'), "%5C%22");
var searchlink = searchurl + searchquery;
if (!ctx.ClientControl.get_shouldShowNoResultMessage() && totalrows > rowcount)
{
_#-->
<a id="btnshowmore" style="float: right;" href="_#= searchlink =#_" target="_blank" rel="noopener noreferrer">show more</a>
<!--#_ } /*** End Show More ***/ _#-->

Get the configured sort and add this to the query

We are going to place the currently applied sort in a variable, ‘window.SelectedSort’.
Find the div ‘ResultHeader’. In here you will find the sort dropdown with id ‘SortBySel’. Around this div there is an ‘if’ statement (showSortOptions) to determine if the sort dropdown is shown.
We need to add an ‘else’ statement to this, so if the dropdown is not enabled, possibly the fallbacksort is enabled and needs to be used. So, below this existing 'if' statement:

    if(showSortOptions){
----snipped default code----
}

Add the following 'else' statement:

    else
{
window.selectedSort = ctx.DataProvider.get_fallbackSort()[0];
}

(Note:This example supports only one sort-level. Of course you can get more than one sort level by iterating through the sorts.)

Add support for the sort-dropdown

On the first load the current sortrankname (ctx.DataProfider.getSortRankName()) will be empty. So we need to check for this. If it is the first load, you can select the first available sort which is selected by default:

    if (ctx.DataProvider.getSortRankName() == null)
{
window.selectedSort = availableSorts[0].sorts[0];
}

After selecting a different sort order, the availablesort will be filled and you can save the current sort to your parameter:

    if(ctx.DataProvider.getSortRankName() == cplxsort.name)
{
window.selectedSort = cplxsort.sorts[0];
----snipped default code----
}

Pick up the selected sort and add this to the searchlink. Again some characters need to be replaced to ensure encoding will not mess up our querystring.

    if (window.selectedSort != null)
{
searchlink = searchlink.replace("?k=", "#Default={%22k%22:%22");
searchlink = searchlink + "%22,%22o%22:[{%22d%22:" + window.selectedSort.d + ",%22p%22:%22" + window.selectedSort.p + "%22}]}";
}

All together now!

Combined this will make your header look like this:

                    if(showSortOptions){
var resultHeaderClassNoEncode = "ms-metadata";
var availableSorts = ctx.DataProvider.get_availableSorts();
_#-->
<div id="ResultHeader" class="_#= resultHeaderClassNoEncode =#_">
<ul id="Actions">
<li id="Sortby">
<select title="_#= $htmlEncode(Srch.Res.rs_SortDescription) =#_" id="SortBySel" onchange="$getClientControl(this).sortOrRank(this.value);">
<!--#_
if (ctx.DataProvider.getSortRankName() == null)
{
window.selectedSort = availableSorts[0].sorts[0];
}
for (var i = 0; i < availableSorts.length; i++) {
var cplxsort = availableSorts[i];
if(!$isNull(cplxsort)){
if(ctx.DataProvider.getSortRankName() == cplxsort.name) {
window.selectedSort = cplxsort.sorts[0];
_#-->
<option selected="selected" value="_#= $htmlEncode(cplxsort.name) =#_">
_#= $htmlEncode(cplxsort.name) =#_
</option>
<!--#_
} else {
_#-->
<option value="_#= $htmlEncode(cplxsort.name) =#_">
_#= $htmlEncode(cplxsort.name) =#_
</option>
<!--#_
}
}
}
_#-->
</select>
</li>
</ul>
</div>
<!--#_
}
else
{
window.selectedSort = ctx.DataProvider.get_fallbackSort()[0];
}

And your footer:

<div class="ms-srch-resultFooter">
<!--#_
/*** Start Show More ***/
var totalrows = ctx.DataProvider.get_totalRows();
var rowcount = ctx.DataProvider.get_resultsPerPage();

var searchurl = "/search/Pages/Everything.aspx?k="
var searchquery = $htmlEncode(ctx.ListData.ResultTables[0].Properties.QueryModification);
searchquery = searchquery.replace("&","%26");
searchquery = searchquery.replace(new RegExp(""", 'g'), "%5C%22");
var searchlink = searchurl + searchquery;

if (window.selectedSort != null)
{
searchlink = searchlink.replace("?k=", "#Default={%22k%22:%22");
searchlink = searchlink + "%22,%22o%22:[{%22d%22:" + window.selectedSort.d + ",%22p%22:%22" + window.selectedSort.p + "%22}]}";
}
_#-->
<!--#_
if (!ctx.ClientControl.get_shouldShowNoResultMessage() && totalrows > rowcount)
{
_#-->
<a id="btnshowmore" style="float:right;" href="_#= searchlink =#_" target="_blank">show more</a>
<!--#_
}
/*** End Show More ***/
_#-->

You can download the full displaytemplate html file here..

Submit a comment