Showing posts with label Display Templates. Show all posts
Showing posts with label Display Templates. Show all posts

Friday, January 2, 2015

How to Add Totals to Search Refiners in SharePoint 2013

So for every Search project I work on this requirement always surfaces, which is why I am confused to why Microsoft did not default the refiners to include the totals.  Including totals in your refiners is actually very easy and only requires a small modification to your Search Filter refiner.  Depending on whether you are utilizing a single option refiner or the multi value refiner will determine which filter refiner you will need to update.


Single Selection
              Filter_Default
Multiple Selections
             
Filter_MultiValue
The first step to modifying the refiner(s) is to locate them

How to Locate Your Filter Files:
(Note: We do not want to modify the JS Files, any updates we make to the HTML files will propagate to the linked JS files.)

  1.   Site Settings
  2.  Master pages and page layouts
  3.  Display Templates
  4.   Filters
  5. Save a copy of either the Filter_Default.html and/or Filter_MultiValue.html files to your desktop
How to Modify Your Filter Display Templates
Now that we have saved copies of the filter display templates, it is time to edit them in order to display totals.

  1. Open the files in a text editor i.e. Notepad++, Notepad, SharePoint Designer, Visual Studio, etc 
  2. Modify ShowCounts: to equal true
Original

<!--#_
 
    this.Options = {
        ShowClientPeoplePicker: false,
        ShowCounts: false
    };
Updated
<!--#_
 
    this.Options = {
        ShowClientPeoplePicker: false,
        ShowCounts: true
    };

After making the update from false to true you will need to upload the new file and publish the changes.  By using the exact same file name your changes should be saved as a new version to the file, if you were not modifying it directly.

Best Of Luck!
Dan

Wednesday, December 31, 2014

Log Managed Property Values Retrieved From a Display Template

Hello Interwebs!
I have been doing a ton of search work lately and just wanted to share a useful script for tracking down those pesky Managed Property Values.  I have been wanting to write a search series, but just can’t seem to find the time to put pen to paper (or fingers to keyboard in my case) to get them written up!

When I first started working with search I think my biggest headache was to tell which managed properties were being retrieved and what the values were for each managed property.  The below script can be added to your display template to log the managed property name & value to your console window for each search result returned.

for (var p in ctx.CurrentItem)
                             {
 console.log(p + ":" + $getItemValue(ctx, p));
                             }

This code can be implemented within any display template, but for this example I will be using the Item_CommonItem_Body display template
(NOTE after your test you should remove the code snippet due to compatibility issues for some browser versions & that there really isn’t a reason to log these values to console outside of testing) I am using this particular template as an example, but any display template which is called from search could be used.
Below is the default code from Body tag of our Item_Common_Body display template where I have added the script to iterate through the managed properties.

<body>
    <div id="Item_CommonItem_Body">
<!--#_


        var id = ctx.CurrentItem.csr_id;
        var title = Srch.U.getHighlightedProperty(id, ctx.CurrentItem, "Title");
        if ($isEmptyString(title)) {title = $htmlEncode(ctx.CurrentItem.Title)}

        var useWACUrl = !$isEmptyString(ctx.CurrentItem.ServerRedirectedURL);
        if(ctx.ScriptApplicationManager && ctx.ScriptApplicationManager.states){
            useWACUrl = (useWACUrl && !ctx.ScriptApplicationManager.states.openDocumentsInClient);
        }

        var appAttribs = "";
        if(!useWACUrl)
        {
            if (!$isEmptyString(ctx.CurrentItem.csr_OpenApp)) { appAttribs += "openApp=\"" + $htmlEncode(ctx.CurrentItem.csr_OpenApp) + "\"" }; 
            if (!$isEmptyString(ctx.CurrentItem.csr_OpenControl)) { appAttribs += " openControl=\"" + $htmlEncode(ctx.CurrentItem.csr_OpenControl) + "\"" };
        }

        var showHoverPanelCallback = ctx.currentItem_ShowHoverPanelCallback;
        if (Srch.U.n(showHoverPanelCallback)) {
            var itemId = id + Srch.U.Ids.item;
            var hoverId = id + Srch.U.Ids.hover;
            var hoverUrl = "~sitecollection/_catalogs/masterpage/Display Templates/Search/Item_Default_HoverPanel.js";
            showHoverPanelCallback = Srch.U.getShowHoverPanelCallback(itemId, hoverId, hoverUrl);
        }
        var displayPath = Srch.U.getHighlightedProperty(id, ctx.CurrentItem, "Path");
        if ($isEmptyString(displayPath)) {displayPath = $htmlEncode(ctx.CurrentItem.Path)} 
        var url = ctx.CurrentItem.csr_Path;
        if($isEmptyString(url)){
            if(useWACUrl)
            {
                url = ctx.CurrentItem.ServerRedirectedURL;
            } else {
                url = ctx.CurrentItem.Path;
            }        
        }
        ctx.CurrentItem.csr_Path = url;
        var pathLength = ctx.CurrentItem.csr_PathLength;
        if(!pathLength) {pathLength = Srch.U.pathTruncationLength}

        var maxTitleLengthInChars = Srch.U.titleTruncationLength;
        var termsToUse = 2;
        if(ctx.CurrentItem.csr_PreviewImage != null)
        {
            maxTitleLengthInChars = Srch.U.titleTruncationLengthWithPreview;
            termsToUse = 1;
        }

        var clickType = ctx.CurrentItem.csr_ClickType;
        if(!clickType) {clickType = "Result"}        
_#-->    
        <div id="_#= $htmlEncode(id + Srch.U.Ids.body) =#_" class="ms-srch-item-body" onclick="_#= showHoverPanelCallback =#_">
<!--#_
            if (!$isEmptyString(ctx.CurrentItem.csr_Icon)) {
_#-->
                <div class="ms-srch-item-icon"> 
                    <img id="_#= $htmlEncode(id + Srch.U.Ids.icon) =#_" onload="this.style.display='inline'" src="_#= $urlHtmlEncode(ctx.CurrentItem.csr_Icon) =#_" />
                </div>
<!--#_
            }

                                          var titleHtml = String.format('<a clicktype="{0}" id="{1}" href="{2}" class="ms-srch-item-link" title="{3}" onfocus="{4}" {5}>{6}</a>',
                                          $htmlEncode(clickType), $htmlEncode(id + Srch.U.Ids.titleLink), $urlHtmlEncode(url), $htmlEncode(ctx.CurrentItem.Title), 
                                          showHoverPanelCallback, appAttribs, Srch.U.trimTitle(title, maxTitleLengthInChars, termsToUse));
                                          
                                          }
_#-->       
            <div id="_#= $htmlEncode(id + Srch.U.Ids.title) =#_" class="ms-srch-item-title"> 
                <h3 class="ms-srch-ellipsis">
                    _#= titleHtml =#_
                </h3>
            </div>
<!--#_ 
            if (!$isEmptyString(ctx.CurrentItem.HitHighlightedSummary)) { 
_#-->
                <div id="_#= $htmlEncode(id + Srch.U.Ids.summary) =#_" class="ms-srch-item-summary">_#= Srch.U.processHHXML(ctx.CurrentItem.HitHighlightedSummary) =#_</div>
                
       


<!--#_ 
            }
            var truncatedUrl = Srch.U.truncateHighlightedUrl(displayPath, pathLength);
_#-->
            <div id="_#= $htmlEncode(id + Srch.U.Ids.path) =#_" tabindex="0" class="ms-srch-item-path" title="_#= $htmlEncode(ctx.CurrentItem.Path) =#_" onblur="Srch.U.restorePath(this, '_#= $scriptEncode(truncatedUrl) =#_', '_#= $scriptEncode(ctx.CurrentItem.Path) =#_')" onclick="Srch.U.selectPath('_#= $scriptEncode(ctx.CurrentItem.Path) =#_', this)" onkeydown="Srch.U.setPath(event, this, '_#= $scriptEncode(ctx.CurrentItem.Path) =#_', '_#= $scriptEncode(truncatedUrl) =#_')" >
                _#= truncatedUrl =#_
            </div>
        </div>
      


<!--#_
        if (!$isEmptyString(ctx.CurrentItem.csr_PreviewImage)) 
        {
            var altText = Srch.Res.item_Alt_Preview;
            if(!$isEmptyString(ctx.CurrentItem.csr_PreviewImageAltText)){
                altText = ctx.CurrentItem.csr_PreviewImageAltText;
            }

            var onloadJS = "var container = $get('" + $scriptEncode(id + Srch.U.Ids.preview) + "'); if(container){container.style.display = 'inline-block';}" +
                           "var path = $get('" + $scriptEncode(id + Srch.U.Ids.path) + "'); if (path) { Srch.U.ensureCSSClassNameExist(path, 'ms-srch-item-preview-path');}" +
                           "var body = $get('" + $scriptEncode(id + Srch.U.Ids.body) + "'); if (body) { Srch.U.ensureCSSClassNameExist(body, 'ms-srch-item-summaryPreview');}";

            var previewHtml = String.format('<a clicktype="{0}" href="{1}" class="ms-srch-item-previewLink" {2}><img class="ms-srch-item-preview" src="{3}" alt="{4}" onload="{5}" /></a>', 
                                            $htmlEncode(clickType), $urlHtmlEncode(url), appAttribs, $urlHtmlEncode(ctx.CurrentItem.csr_PreviewImage), $htmlEncode(altText), onloadJS);
_#-->       
            <div id="_#= $htmlEncode(id + Srch.U.Ids.preview) =#_"  class="ms-srch-item-previewContainer"> 
                _#= previewHtml =#_
            </div>
<!--#_
        }
         for (var p in ctx.CurrentItem)
  {
       console.log(p + ":" + $getItemValue(ctx, p));
  }
  
         _#-->
    </div>
</body>
Now that we have added the script, saved and published the display template we are ready to see what is brought back from our search results!

  1.  Open your browser’s developer tools
  2.  i.e. FireBug, Chrome Tools, F12, etc.
  3.  Enter a search query into the search box which will return results
  4. You can use * to grab everything
  5. Select the console tab in your developer tools
  6. Bask in the awesome... There are actually more properties for this particular item than the screenshot shows, but I can only grab so many with a screen capture :) 

In a future post I will be walking through how to add new Managed Properties to your display templates and how to surface them via the item results and hover panels.

Hope This Helps!
Dan