locked
Add page numbers to Content Search - list with paging control template RRS feed

  • Question

  • Hello, i'm using a content search web part with a customized List With Paging control template, and i'm trying to figure out how to add page number links to go along with the prev/next buttons. I'm hoping to do it just with javascript/jquery in the template html/js file. I assume there are some methods that i can use in the JS to get the information i need, ie: the total number of results. Any ideas? I'm not sure how to figure out what methods are available to me...like ctx.ClientControl.get_showResultCount() (saw that one in a different template, but isn't retrieving any data here.)

    Thursday, June 27, 2013 4:19 PM

Answers

  • This is my control display template based on the standard Control List with Paging template. I added some code to add page numbers. I use var totalRows = ctx.DataProvider.get_totalRows(); to get the total number of items being returned, so that I can figure out how many per page/how many pages etc... It allows me to figure out which page we're currently on so i can remove the HREF from that page number.

    <body>

        <!--
                Warning: Do not try to add HTML to this section. Only the contents of the first <div>
                inside the <body> tag will be used while executing Display Template code. Any HTML that
                you add to this section will NOT become part of your Display Template.
        -->
        <script>
            $includeLanguageScript(this.url, "~sitecollection/_catalogs/masterpage/Display Templates/Language Files/{Locale}/CustomStrings.js");
        </script>

        <!--
            Use the div below to author your Display Template. Here are some things to keep in mind:
            * Surround any JavaScript logic as shown below using a "pound underscore" (#_ ... _#) token
            inside a comment.

            * Use the values assigned to your variables using an "underscore pound equals"
            (_#= ... =#_) token.
        -->

        <div id="Control_ListWithPaging">

    <!--#_ 
    if (!$isNull(ctx.ClientControl) &&
        !$isNull(ctx.ClientControl.shouldRenderControl) &&
        !ctx.ClientControl.shouldRenderControl())
    {
        return "";
    }
    ctx.ListDataJSONGroupsKey = "ResultTables";
    var $noResults = Srch.ContentBySearch.getControlTemplateEncodedNoResultsMessage(ctx.ClientControl);

    var isRollupPageInDisplayMode = Srch.ContentBySearch.isRollupPage(ctx.ClientControl) && !Srch.U.isPageInEditMode();
    var noResultsClassName = isRollupPageInDisplayMode ? "ms-attractMode ms-uppercase ms-alignCenter" : "ms-srch-result-noResults";

    var ListRenderRenderWrapper = function(itemRenderResult, inCtx, tpl)
    {
        var iStr = [];
        iStr.push('<li>');
        iStr.push(itemRenderResult);
        iStr.push('</li>');
        return iStr.join('');
    }
    ctx['ItemRenderWrapper'] = ListRenderRenderWrapper;
    _#-->
        <ul class="cbs-List Control_ListWithPaging">

    <!--#_
    var showPaging = ctx.ClientControl.get_showPaging();
    if(showPaging)
    {
        var pagingInfo = ctx.ClientControl.get_pagingInfo();
        showPaging = !$isEmptyArray(pagingInfo);
        if(showPaging)
        {
            var currentPage = null;
            var firstPage = pagingInfo[0];
            var lastPage = pagingInfo[pagingInfo.length - 1];

            for (var i = 0; i< pagingInfo.length; i++)
            {
                var pl = pagingInfo[i];
                if (!$isNull(pl))
                {
                    if (pl.startItem == -1)
                    {
                        currentPage = pl;
                    }
                }
            }

            var getPagingImageClassName = function(buttonClassNamePrefix, isNext, isEnabled)
            {
                var className = buttonClassNamePrefix;
                className += (isNext && !Srch.U.isRTL()) || (!isNext && Srch.U.isRTL()) ? "right" : "left";
                if(!$isNull(isEnabled) && isEnabled == false)
                {
                    className += "-disabled";
                }
                return className;
            }

            var getPagingContainerClassName = function(buttonClassNamePrefix, isEnabled)
            {
                var className = buttonClassNamePrefix;
                className += isEnabled ? "enabled" : "disabled";
                return className;
            }
    var rowsPerPage = ctx.ClientControl.get_numberOfItems();
    var totalRows = ctx.DataProvider.get_totalRows();
    var currentPageNumber = ctx.ClientControl.get_currentPageNumber();
    var totalPages = Math.ceil(totalRows / rowsPerPage);
    var testLink = '';
    for (var i = 0; i < totalPages; i++)
    {
    if ((i+1) == currentPageNumber)
    testLink += '<a class="ms-commandLink ms-promlink-button ms-promlink-button-disabled">' + (i + 1) + '</a>';
    else
    testLink += '<a class="ms-commandLink ms-promlink-button ms-promlink-button-enabled" href="#" onclick="$getClientControl(this).page(' + ((i+1)*rowsPerPage -(rowsPerPage -1)) + ');return Srch.U.cancelEvent(event);">' + (i + 1) + '</a>';

    }

            var hasNextPage = lastPage.pageNumber == -2;
            var hasPreviousPage = firstPage.pageNumber == -1;
            var buttonClassNamePrefix = "ms-promlink-button-";
            var nextPageContainerClassName = getPagingContainerClassName(buttonClassNamePrefix, hasNextPage);
            var previousPageContainerClassName = getPagingContainerClassName(buttonClassNamePrefix, hasPreviousPage);
            var nextPageImageClassName = getPagingImageClassName(buttonClassNamePrefix, true, hasNextPage);
            var previousPageImageClassName = getPagingImageClassName(buttonClassNamePrefix, false, hasPreviousPage);
    _#-->

                _#= ctx.RenderGroups(ctx) =#_
                <li class="ms-promlink-header">
    <div class="pageNumbers" style="float:left;">_#= testLink =#_</div>
                    <span class="ms-promlink-headerNav">
                        <a class="ms-commandLink ms-promlink-button _#= $htmlEncode(previousPageContainerClassName) =#_" title="_#= $htmlEncode(firstPage.title) =#_" href="#" onclick='$getClientControl(this).page(_#= $htmlEncode(firstPage.startItem) =#_);return Srch.U.cancelEvent(event);'>
                            <!--<span class="ms-promlink-button-image">
                                <img class="_#= $htmlEncode(previousPageImageClassName) =#_" alt="_#= $htmlEncode(firstPage.title) =#_" src="_#= $urlHtmlEncode(GetThemedImageUrl('spcommon.png')) =#_">
                            </span>-->
                        &lt; prev
                        </a>
                        <a class="ms-commandLink ms-promlink-button _#= $htmlEncode(nextPageContainerClassName) =#_" title="_#= $htmlEncode(lastPage.title) =#_" href="#" onclick='$getClientControl(this).page(_#= $htmlEncode(lastPage.startItem) =#_);return Srch.U.cancelEvent(event);'>
                            <!--<span class="ms-promlink-button-image">
                                <img class="_#= $htmlEncode(nextPageImageClassName) =#_" alt="_#= $htmlEncode(lastPage.title) =#_" src="_#= $urlHtmlEncode(GetThemedImageUrl('spcommon.png')) =#_">
                            </span>-->
                        next &gt;
                        </a>
                    </span>
                </li>


    <!--#_
        }
    }
    _#-->
    <!--#_
    if(!showPaging)
    {
    _#--> 
    _#= ctx.RenderGroups(ctx) =#_
    <!--#_
    }
    _#-->

           </ul>
    <!--#_

    if (ctx.ClientControl.get_shouldShowNoResultMessage())
    {
    _#-->
            <div class="_#= noResultsClassName =#_">_#= $noResults =#_</div>
    <!--#_
    }
    _#-->

        </div>
    </body>
    </html>

                                                    
    • Proposed as answer by SuPar Friday, November 15, 2013 1:01 PM
    • Marked as answer by Scott3501 Friday, November 15, 2013 3:58 PM
    Wednesday, August 28, 2013 9:16 PM

All replies

  • Hi,

    I am have the same problem as I want to add the number of results also at the top of the result page. I am experimenting with ctx.DataProvider.get_totalRows() in another display template as Control_SearchResults where it is used. But I am getting "Object doesn't support property or mathod" as error. I'll keep you informed if I making progress.

    Wednesday, August 28, 2013 8:41 AM
  • This is my control display template based on the standard Control List with Paging template. I added some code to add page numbers. I use var totalRows = ctx.DataProvider.get_totalRows(); to get the total number of items being returned, so that I can figure out how many per page/how many pages etc... It allows me to figure out which page we're currently on so i can remove the HREF from that page number.

    <body>

        <!--
                Warning: Do not try to add HTML to this section. Only the contents of the first <div>
                inside the <body> tag will be used while executing Display Template code. Any HTML that
                you add to this section will NOT become part of your Display Template.
        -->
        <script>
            $includeLanguageScript(this.url, "~sitecollection/_catalogs/masterpage/Display Templates/Language Files/{Locale}/CustomStrings.js");
        </script>

        <!--
            Use the div below to author your Display Template. Here are some things to keep in mind:
            * Surround any JavaScript logic as shown below using a "pound underscore" (#_ ... _#) token
            inside a comment.

            * Use the values assigned to your variables using an "underscore pound equals"
            (_#= ... =#_) token.
        -->

        <div id="Control_ListWithPaging">

    <!--#_ 
    if (!$isNull(ctx.ClientControl) &&
        !$isNull(ctx.ClientControl.shouldRenderControl) &&
        !ctx.ClientControl.shouldRenderControl())
    {
        return "";
    }
    ctx.ListDataJSONGroupsKey = "ResultTables";
    var $noResults = Srch.ContentBySearch.getControlTemplateEncodedNoResultsMessage(ctx.ClientControl);

    var isRollupPageInDisplayMode = Srch.ContentBySearch.isRollupPage(ctx.ClientControl) && !Srch.U.isPageInEditMode();
    var noResultsClassName = isRollupPageInDisplayMode ? "ms-attractMode ms-uppercase ms-alignCenter" : "ms-srch-result-noResults";

    var ListRenderRenderWrapper = function(itemRenderResult, inCtx, tpl)
    {
        var iStr = [];
        iStr.push('<li>');
        iStr.push(itemRenderResult);
        iStr.push('</li>');
        return iStr.join('');
    }
    ctx['ItemRenderWrapper'] = ListRenderRenderWrapper;
    _#-->
        <ul class="cbs-List Control_ListWithPaging">

    <!--#_
    var showPaging = ctx.ClientControl.get_showPaging();
    if(showPaging)
    {
        var pagingInfo = ctx.ClientControl.get_pagingInfo();
        showPaging = !$isEmptyArray(pagingInfo);
        if(showPaging)
        {
            var currentPage = null;
            var firstPage = pagingInfo[0];
            var lastPage = pagingInfo[pagingInfo.length - 1];

            for (var i = 0; i< pagingInfo.length; i++)
            {
                var pl = pagingInfo[i];
                if (!$isNull(pl))
                {
                    if (pl.startItem == -1)
                    {
                        currentPage = pl;
                    }
                }
            }

            var getPagingImageClassName = function(buttonClassNamePrefix, isNext, isEnabled)
            {
                var className = buttonClassNamePrefix;
                className += (isNext && !Srch.U.isRTL()) || (!isNext && Srch.U.isRTL()) ? "right" : "left";
                if(!$isNull(isEnabled) && isEnabled == false)
                {
                    className += "-disabled";
                }
                return className;
            }

            var getPagingContainerClassName = function(buttonClassNamePrefix, isEnabled)
            {
                var className = buttonClassNamePrefix;
                className += isEnabled ? "enabled" : "disabled";
                return className;
            }
    var rowsPerPage = ctx.ClientControl.get_numberOfItems();
    var totalRows = ctx.DataProvider.get_totalRows();
    var currentPageNumber = ctx.ClientControl.get_currentPageNumber();
    var totalPages = Math.ceil(totalRows / rowsPerPage);
    var testLink = '';
    for (var i = 0; i < totalPages; i++)
    {
    if ((i+1) == currentPageNumber)
    testLink += '<a class="ms-commandLink ms-promlink-button ms-promlink-button-disabled">' + (i + 1) + '</a>';
    else
    testLink += '<a class="ms-commandLink ms-promlink-button ms-promlink-button-enabled" href="#" onclick="$getClientControl(this).page(' + ((i+1)*rowsPerPage -(rowsPerPage -1)) + ');return Srch.U.cancelEvent(event);">' + (i + 1) + '</a>';

    }

            var hasNextPage = lastPage.pageNumber == -2;
            var hasPreviousPage = firstPage.pageNumber == -1;
            var buttonClassNamePrefix = "ms-promlink-button-";
            var nextPageContainerClassName = getPagingContainerClassName(buttonClassNamePrefix, hasNextPage);
            var previousPageContainerClassName = getPagingContainerClassName(buttonClassNamePrefix, hasPreviousPage);
            var nextPageImageClassName = getPagingImageClassName(buttonClassNamePrefix, true, hasNextPage);
            var previousPageImageClassName = getPagingImageClassName(buttonClassNamePrefix, false, hasPreviousPage);
    _#-->

                _#= ctx.RenderGroups(ctx) =#_
                <li class="ms-promlink-header">
    <div class="pageNumbers" style="float:left;">_#= testLink =#_</div>
                    <span class="ms-promlink-headerNav">
                        <a class="ms-commandLink ms-promlink-button _#= $htmlEncode(previousPageContainerClassName) =#_" title="_#= $htmlEncode(firstPage.title) =#_" href="#" onclick='$getClientControl(this).page(_#= $htmlEncode(firstPage.startItem) =#_);return Srch.U.cancelEvent(event);'>
                            <!--<span class="ms-promlink-button-image">
                                <img class="_#= $htmlEncode(previousPageImageClassName) =#_" alt="_#= $htmlEncode(firstPage.title) =#_" src="_#= $urlHtmlEncode(GetThemedImageUrl('spcommon.png')) =#_">
                            </span>-->
                        &lt; prev
                        </a>
                        <a class="ms-commandLink ms-promlink-button _#= $htmlEncode(nextPageContainerClassName) =#_" title="_#= $htmlEncode(lastPage.title) =#_" href="#" onclick='$getClientControl(this).page(_#= $htmlEncode(lastPage.startItem) =#_);return Srch.U.cancelEvent(event);'>
                            <!--<span class="ms-promlink-button-image">
                                <img class="_#= $htmlEncode(nextPageImageClassName) =#_" alt="_#= $htmlEncode(lastPage.title) =#_" src="_#= $urlHtmlEncode(GetThemedImageUrl('spcommon.png')) =#_">
                            </span>-->
                        next &gt;
                        </a>
                    </span>
                </li>


    <!--#_
        }
    }
    _#-->
    <!--#_
    if(!showPaging)
    {
    _#--> 
    _#= ctx.RenderGroups(ctx) =#_
    <!--#_
    }
    _#-->

           </ul>
    <!--#_

    if (ctx.ClientControl.get_shouldShowNoResultMessage())
    {
    _#-->
            <div class="_#= noResultsClassName =#_">_#= $noResults =#_</div>
    <!--#_
    }
    _#-->

        </div>
    </body>
    </html>

                                                    
    • Proposed as answer by SuPar Friday, November 15, 2013 1:01 PM
    • Marked as answer by Scott3501 Friday, November 15, 2013 3:58 PM
    Wednesday, August 28, 2013 9:16 PM
  • Instead on CSWP if you try adding search results web part with the same query as that of CSWP. Results are returned with paging. Either you can check jquery templates for search results web part and find out the script to enable paging or you can create a copy of search template . Make changes as per your requirement to the template, add search results web part with the newly created search template.
    Wednesday, August 28, 2013 9:41 PM
  • Although this is an old question -> I thought I would offer another solution in case someone else comes across this post.  Instead of using your own custom code to add page numbers, you can copy/paste some built-in functionality from another Display Template that SharePoint uses for Search Results.  

    Download the "Control_SearchResults.html" Display Template from here: 
    Site Settings -> Master pages and page layouts -> Display Templates -> Search -> Control_SearchResults.html

    Open the file in your text editor and look for the line: 
    "if(ctx.ClientControl.get_showPaging()){"

    Copy that section (the starting javscript, the <ul> and <li> tags, and the multiple closing javscript "}") and replace the current paging area of your Display Template with it.

    Open searchv15.css in a text editor and look for the line:
    ".ms-srch-result #Paging"

    Copy the whole section (up to "ms-srch-error-header") and add it to your CSS "overrides" file.
    Replace references to the style ".ms-srch-result #Paging" with "#Paging.ms-srch-Paging"

    Deploy the updated Display Template and your CSS file.  (I'm using WSP's to deploy my SharePoint assets)

    Jason

    Tuesday, January 20, 2015 5:26 PM