Building a SharePoint 2013 Search Refiner with Custom Intervals

Introduction

SharePoint 2013 Search has really improved over its SharePoint 2010 predecessor. These improvements are down to the integration of the FAST search feature set into SharePoint 2013.

One of the nice features is the slider graph refiner which gives a visual representation of the results that can be filtered. However, unfortunately it doesn’t work well for custom managed properties.

Here is the refiner using the out of the box Last Modified Managed Property

clip_image002

Here is the refiner using a custom Date Time Managed Property called Timeline (this is the date of the document).

clip_image004

As you can see the date range is only for the last year, the numbers have commas in them and as the following image shows the descriptions for refining the data between the different intervals does not really make sense.

clip_image006

In a recent project this led to the decision to use a normal text refiner over the slider bar graph. However, the user base asked for the refinement options to be changed to a custom set of values. The out of the box date time refinement has the following options:-

· Last Year

· Last Six Months

· Last Month

· Last Week

· Last day

However the requirement was to have a custom set of refinements as shown below:-

timeline_datetime_refiner

Investigation

So to achieve the requirement above we need be able to do two things:-

· Configure how the refiner web part calculates the additional refiners

· Configure the text being used to display the refinement options to the user

How to configure the refinement calculations

The first thing that I did was have a look and see if there was anyone else who had tackled this issue and unfortunately I didn’t come up with much on MSDN or out there on the web.

The next step was to start looking at the customisation options for the web part.

By editing the web part properties and clicking on the “Choose Refiners” button you can decide which managed properties are going to be refinement options. Microsoft have given quite a lot of flexibility to custom the refiners but these options are not available for date/time data types . There are more options for the other data types such as text or number.

For example a managed property which is based on a number gives you the opportunity to create manual intervals to refine by.

clip_image007

However, a refiner based on a date/time data type doesn’t have much flexibility. This is probably easier to see via a screenshot.

clip_image009

There is an option to define the dates in the search schema but when that option is select then you get the following error message.

clip_image011

So this leads to the question what do I do now?

Quite often with web parts I start looking at the actual web part xml definition to try and workout if there are any appropriately named properties or values. So I exported the web part and opened up the web part in notepad.

After a lot of looking about I found the following web part property, “SelectedRefinementControlsJson”:-

clip_image013

This property contains a JSON string which defines the refinement control configuration. For each refiner that is selected a set of properties are stored within this string, these include properties such as

· sortBy

· sortOrder

· maxNumberOfRefinementItems

· DisplayTemplate

· etc

However, there were two properties which has interesting names and they were:-

clip_image015

clip_image017

I presumed that I could change the useDefaultDateIntervals to false and then provide some sort of JSON object for the intervals property. However, the difficult was trying to work out what the intervals structure would look like!

I started to debug the refiners using the Internet Explorer Developer Toolbar but didn’t really find much to help reverse engineer the process.

The approach that I quite often take is to examine the .NET code using a tool like Reflector. So it was time to reflect the appropriate web part. The refinement web part is of type:-

· Microsoft.Office.Server.Search.WebControls.RefinementScriptWebPart

After some searching I found the appropriate code.

The ResultScriptWebPart has a private method called GetRefinementControls() this instatiates another class called RefinementControl. A RefinementControl object is created for each Refinement Control JSON object and part of that object looks at the useDefaultDateIntervals property and if this has been set then the GetDefaultDateIntervalSpecString() is loaded.

clip_image019

The function GetDefaultDateIntervalSpecString() gives the clue of how the intervals parameter should be formatted.

clip_image021

So the intervals are basically an array of integers so the representation of this in JSON is the following:-

clip_image023

And of course to ensure that the custom intervals are loaded we need to change the useDefaultDateIntervals property to false.

clip_image025

So just to go back the intervals that have been set for the refiners are the number of days that should be removed from todays date to create the interval. The intervals -1065,-730,-365,-183,-30,-7, 0 translates to the less than 3+ years, 2-3 years, 1-2 years, 6 months to 1 year, 1-6 months, 1 week – 1 month and today.

So now we are able to control the refinement calculations, the next step is how to configure the labels displayed to the user.

If we don’t configure the labels we get the following being displayed to the user, which is obviously not good enough.

How to configure the refinement labels

Now I haven’t found a simpler solution for this but if anyone finds an alternative solution which for example overrides a particular web part property then please let me know.

The approach that I took in the end was to create my own filter display template. I haven’t covered display templates in my blog as yet. I am planning a post to discuss my findings with SharePoint 2013 Search development soon. However, the following articles provide some good information.

Anyway, display templates are found in the master page catalog document library which can be found at http://sharepoint/_catalogs/masterpage/displaytemplates. An alternate method to browse to this list is by going to the SharePoint site collection, click Site settings cog icon -> Site Settings->Master Pages and Page Layouts (under the Web Designer Galleries section).

All the out of box refinement filters can be found under the DisplayTemplates/Filters folder. I downloaded the Filter_Default.html file which is used as the standard out of the box text refinement filter. The file was renamed the file to Filter_CustomDateTime.html and edited in Visual Studio.

Here is an example of the contents of the Display Template

clip_image027

The <head> tag was updated to give a new title and then the following script was added which will go and set the labels presented to the end user. The JavaScript was added after all the default label data has been loaded, this was to ensure the custom configuration was not overwritten.

clip_image029

The display template was loaded back into SharePoint, I suggest that you put it in a custom folder and use a Module to deploy the file. In my example I am putting the filter in the following directory, Display Templates/iThinkSharePoint/.

Now we have the custom display template and we have configured our web part to use custom intervals there is one last step.

Can you guess what it is?

So we need to tell the web part to use our custom filter display template, this is another modification of the web part property, SelectedRefinementControlsJson. With some care look through the JSON string and find the refinement configuration for our custom Managed Property.

clip_image031

Now the web part configuration can be saved and uploaded into SharePoint as a new web part in the web part gallery.

Solution

So to recap the final solution has the following components:-

· Custom Web Part Configuration which includes the custom intervals, references the custom display template

· Custom Display Template for the Refinement control

This creates the following refiner:-

timeline_datetime_refiner

You can download the example Display Template and Web Part Configuration XML file from here:-

ITSPSearchRefineCustomIntervals.zip

If you find this useful please let me know and please ask if you need some more clarification.

56 Comments

  1. For the date slider control, custom intervals apply as Simon’s post describes but the labels will take a little extra work:

    1. Create a new display template based off of the default date slider.
    2. Within the display template’s sliderInitCallback function, after the call to GetDefaultBuckets and before the call to GetDefaultFilterLabelMarkupAndOptions customize ctx.BucketedFilterData.BoundaryValues (Label and NextIntervalLable) and ctx.BucketedFilterData.Labels (max, min, range, value) as you need.
    3. Ensure your field’s refiner configuration uses the new display template and that it uses the appropriate setting (for this example, “Last day, week, month, six months and year setting”.)

    I found putting a ‘debugger;’ breakpoint in the sliderInitCallback very helpful. This is not a pretty solution and not very adaptable (you may need a single template for each date division you might want.) I look forward to seeing someone describe the right way to do this. For instance, where in the search schema are these labels defined?

    Example code to be inserted into sliderInitiCallback as described above:

    // Force the date slider labels
    if ( ctx.BucketedFilterData.BoundaryValues.length > 0 )
    {
    ctx.BucketedFilterData.BoundaryValues[0].Label = “Earlier than {0}”;
    ctx.BucketedFilterData.BoundaryValues[0].NextIntervalLabel = “Earlier than One Year Ago”;
    ctx.BucketedFilterData.BoundaryValues[1].Label = “One Year Ago”;
    ctx.BucketedFilterData.BoundaryValues[1].NextIntervalLabel = “One Year Ago – One Month Ago”;
    ctx.BucketedFilterData.BoundaryValues[2].Label = “One Month Ago”;
    ctx.BucketedFilterData.BoundaryValues[2].NextIntervalLabel = “One Month Ago – One Week Ago”;
    ctx.BucketedFilterData.BoundaryValues[3].Label = “One Week Ago”;
    ctx.BucketedFilterData.BoundaryValues[3].NextIntervalLabel = “One Week Ago – Today”;
    ctx.BucketedFilterData.BoundaryValues[4].Label = “Today”;
    ctx.BucketedFilterData.BoundaryValues[4].NextIntervalLabel = “Today”;
    ctx.BucketedFilterData.BoundaryValues[5].Label = “{0}”;
    ctx.BucketedFilterData.Labels.max = “{0}”;
    ctx.BucketedFilterData.Labels.min = “Earlier than {0}”;
    ctx.BucketedFilterData.Labels.range = “{0} – {1}”;
    ctx.BucketedFilterData.Labels.value = “{0}”;
    }

    Reply

    1. Hi Richard,
      Wow thanks for taking the time to reply and put that valuable information as a comment. I will have to try it out. If you have a blog post then let me know and I’ll link to it.

      Thanks for sharing.

      Cheers
      Simon

      Reply

  2. Hi Simon,

    I created a new display template and made the changes as you described to show the custom labels. I exported the web part and made the changes as described and uploaded the modified web part. But when I use this modified web part, it does not work because it never gets the new intervals defined in the modified web part. Your javascript code checks whether the length of the listdata is greater than or equal to 8 but for me that piece of code is never hit. I can make it work only when the length of the listdata to 5 or less, This makes me believe that the new intervals defined in the .webpart file are not loaded by the web part.

    Could you please help?

    Thanks.

    Reply

    1. Hi,
      Something to check is the path of the JavaScript. When the web part is first used it seems to take the ~site token for the site’s URL.

      Please post me the web part file and I’ll take a look.

      Cheers
      Simon

      Reply

      1. Hi Simon,

        Thanks for taking time to reply to my question. Below are the contents of my .weppart file. The Filter_CustomDefault.html file is exactly the same as you have posted with this article. As I stated earlier, the labels from the Filter_CustomDefault.html are not displayed because of the condition where we are checking the length of the listdata to be greater than or equal to 8. For me, the length of the listdata is always 5 (which I am assuming is the length of the default intervals and NOT the custom intervals defined in this new .wepart). Please let me know if there is anything else that you need from me. Your help is very much appreciated.

        Cannot import this Web Part.

        {}

        null

        {“refinerConfigurations”:[{“sortBy”:0,”sortOrder”:0,”maxNumberRefinementOptions”:15,”propertyName”:”PublicAffairsCategoryOWSCHCS”,”type”:”Text”,”displayTemplate”:”~sitecollection/_catalogs/masterpage/Display Templates/Filters/Filter_Default.js”,”displayName”:”Public Affairs Category”,”useDefaultDateIntervals”:false,”aliases”:null,”refinerSpecStringOverride”:””,”intervals”:null},{“sortBy”:0,”sortOrder”:0,”maxNumberRefinementOptions”:15,”propertyName”:”PaperCategoryOWSCHCS”,”type”:”Text”,”displayTemplate”:”~sitecollection/_catalogs/masterpage/Display Templates/Filters/Filter_Default.js”,”displayName”:”Paper Category”,”useDefaultDateIntervals”:false,”aliases”:null,”refinerSpecStringOverride”:””,”intervals”:null},{“sortBy”:0,”sortOrder”:0,”maxNumberRefinementOptions”:15,”propertyName”:”PertainsToOWSCHCS”,”type”:”Text”,”displayTemplate”:”~sitecollection/_catalogs/masterpage/Display Templates/Filters/Filter_Default.js”,”displayName”:”Advisory Bulletin Pertains To”,”useDefaultDateIntervals”:false,”aliases”:null,”refinerSpecStringOverride”:””,”intervals”:null},{“sortBy”:0,”sortOrder”:0,”maxNumberRefinementOptions”:15,”propertyName”:”ReportPlanCategoryOWSCHCS”,”type”:”Text”,”displayTemplate”:”~sitecollection/_catalogs/masterpage/Display Templates/Filters/Filter_Default.js”,”displayName”:”Report Plan Category”,”useDefaultDateIntervals”:false,”aliases”:null,”refinerSpecStringOverride”:””,”intervals”:null},{“sortBy”:0,”sortOrder”:0,”maxNumberRefinementOptions”:15,”propertyName”:”owstaxIdFHFAAudience”,”type”:”Text”,”displayTemplate”:”~sitecollection/_catalogs/masterpage/Display Templates/Filters/Filter_Default.js”,”displayName”:”Audience”,”useDefaultDateIntervals”:false,”aliases”:null,”refinerSpecStringOverride”:””,”intervals”:null},{“sortBy”:0,”sortOrder”:0,”maxNumberRefinementOptions”:15,”propertyName”:”FHFAPublishedDateOWSDATE”,”type”:”DateTime”,”displayTemplate”:”~sitecollection/_catalogs/masterpage/Display Templates/Filters/FHFA/Filter_CustomDate.js”,”displayName”:”Publishing Date”,”useDefaultDateIntervals”:false,”aliases”:null,”refinerSpecStringOverride”:””,”intervals”:[-1065,-730,-365,-183,-30,-7,0]},{“sortBy”:0,”sortOrder”:0,”maxNumberRefinementOptions”:15,”propertyName”:”Date-of-Paper-PublicationOWSDATE”,”type”:”DateTime”,”displayTemplate”:”~sitecollection/_catalogs/masterpage/Display Templates/Filters/Filter_Slider.js”,”displayName”:”Paper Publication Date”,”useDefaultDateIntervals”:true,”aliases”:null,”refinerSpecStringOverride”:””,”intervals”:null}]}
        True
        ~sitecollection/_catalogs/masterpage/Display Templates/Filters/Control_Refinement.js
        True

        All
        True
        True
        This webpart helps the users to refine search results
        True
        None
        Normal

        Modeless

        False
        Custom Date Interval Refiner
        True
        Cannot import this Web Part.
        False
        Default
        True
        NotSet

      2. Hi Ajay,
        I have to say I cant see much wrong with the web part’s JSON.
        Did you modify the JavaScript above where it is checking the listdata and modify it for the names of your respective managed properties.

        e.g.

        if((ctx.RefinementControl.propertyName == "FHFAPublishedDateOWSDATE")) {

        The only other thing and its probably just the process of copying over the JSON into the browser but the JSON at the end of the string seems to have different style double-quotes. Maybe just check those as well.

        Let me know how you get on.

        Cheers
        Simon

  3. Hi Simon,

    I used your webpart file as is by just changing the path to display template and also used the display template as is but it doesn’t show the custom intervals. It still shows OOB intevals. Any help would be appreicated.

    Thanks
    Nilay

    Reply

    1. Hi Nilay,
      Thanks for the comment, maybe take a look through the post again. Did you modify the display template with the name of the field that is used for your refiner with custom intervals?

      Regards
      Simon

      Reply

  4. Hi Simon,

    Excellent article & I’m sure I’ll use it at some point.

    I had the same problem as you, but I think I have found the solution…at least to use the OOTB refiners. Thought I would post it here so that others have the choice.

    To get your date to be recognised by the refiner you need to re-use one of the pre-defined Managed Properties. So I have re-defined RefinableDate00 to index my ows_ArticleStartDate and then used that in the refiner.

    This works as expected.

    –Vince

    Reply

  5. Hi Simon,

    Thanks for the post, it works great! I implemented a similar approach for a custom date property, but I used the following intervals in the web part: -1460,-1095,-730,-365,365,730,1095,1460 This works well, except 1460 does not include dates after 1460 in the search results. I would like it to be “3+ years from now”, not “up to 3 years from now”. Do you know how I could accomplish this? -1460 does seem to work for “3+ years ago” so I am not sure why this wouldn’t work for dates in the future.

    Kevin

    Reply

    1. Hi Kevin,
      How about adding an additional interval way into the future so -1460,-1095,-730,-365,365,730,1095,1460,32567

      Haven’t tested it but worth a go.

      Cheers
      Simon

      Reply

      1. Hi Simon,

        Thanks for answering my question! Adding an interval way into the future works.

        Kevin

  6. Hi Simon,

    Thanks for this article, it’s a great help in getting further understanding on how it all works. Do you know if there is a way to make the date intervals static rather than relative to the current date e.g. rather than 1yr ago, 2yrs ago etc… have 2011-2012, 2012-2013 etc?

    Thank you again for your research efforts.

    Regards
    Pete

    Reply

    1. Hmm I am sure its possible but probably with a different refiner type. I would have to do some investigation and at the moment I am a bit snowed under with a project about to go live. Will see if I can take a look towards the end of the week.

      Sorry cannot be more helpful.

      Cheers
      Simon

      Reply

    1. Export the webpart that is on the page by editing the page, selecting the webpart and using the drop down arrow on top right.
      This will download a .webpart file which is an XML file. Make your changes and upload the webpart using the import webpart option. This is available, when you edit a page and click insert webpart.
      HTH
      Cheers
      Simon

      Reply

  7. hi, nice post. I have a problems because the webpart always show me

    Timeline
    Earlier than One Year Ago
    One Year Ago – One Month Ago
    One Month Ago – One Week Ago

    I use the ITSPSearchRefineCustomIntervals.zip and add the intervals, change false the use of default intervals…but nothings.

    Reply

    1. Hi if you look at the JavaScript there is an if statement which is checking the name of the column before adding the refinement interval headings, make sure you change this line to use the column that you wish to display the refiners for.
      Cheers
      Simon

      Reply

  8. Hi, I had the same problem where I wanted to show a custom date managed property and it was showing numbers rather than text (not like the OOTB modified date), however changing the name of the managed property (custom) to end with OWSDATE solved the problem for me. So rather than naming my managed property MyDate, I renamed to MyDateOWSDATE. Hope it helps 🙂

    Reply

  9. Hi, I’ve this webpart (is your with only LastModifiedField

    Cannot import this Web Part.

    {}

    null

    {“refinerConfigurations”:[{“sortBy”:0,”sortOrder”:0,”maxNumberRefinementOptions”:0,”propertyName”:”LastModifiedTime”,”type”:”DateTime”,”displayTemplate”:”~sitecollection/_catalogs/masterpage/Display Templates/iThinkSharePoint/Filter_CustomDefault.js”,”displayName”:”LastModifiedTime”,”useDefaultDateIntervals”:false,”aliases”:null,”refinerSpecStringOverride”:””,”intervals”:[-730,-365,-183,-30,-7,0]}]}
    True
    ~sitecollection/_catalogs/masterpage/Display Templates/Filters/Control_Refinement.js
    True

    All
    True
    True
    This webpart helps the users to refine search results
    True
    None
    Normal

    Modeless

    False
    Search Refinement (Custom Intervals)
    True
    Cannot import this Web Part.
    False
    Default
    True
    NotSet

    I’ve also modified the relative Display Template with the customization of the labeling. The problem is that i’ve defined 6 intervals but i’m able to see only 5, the default.

    suggestions?

    Reply

    1. Hi Luca
      Apologies hadn’t seen your comment.
      I’ll need to take a look.
      I would guess the issue is down to the display template js which needs to iterate over 6 options.

      Simon

      Reply

  10. Simon
    Possibly outside scope of your article but related to search refiners and custom dates – Have date/time column BUT need refiners by Month and Year simply by Month names and year not relative to today or modified date.
    Unable to sort refiners by month (when I use text by name obviously April comes before Jan)

    Reply

    1. Hi there,
      So there is a comment by Vincent Rothwell further down which I think will help. Rather than use a custom managed property, map the crawled property to one of the Site collection Pre defined refinable managed properties such as RefinableDate00 / RefinableDate01 and then setup the Alias to the name that you used for your Custom Managed Property. Use the pre-defined managed property for your search refiner.

      Let me know how you get on.

      Cheers

      Reply

  11. In the Refinement panel web part, when selecting “Sort by” Name the refinement items are not sorted.
    If the refiners being used on your search page are a custom metadata term (They usually have a name like “owstaxId…”) you will need to add additional sort options to the “Display template” being used by the Refinement webpart. The Display Template is choosen within the Refinement configuration popup window when you edit the Refinement web part. The display template being used here need to be edited. This Display Template is a html file located on the SharePoint server in the _catalogs\masterpage\Display Template\Filters folder. Do NOT edit the .js file. It will update automatically when you save your html file. Edit the filter file that is being used by your search page in notepad or an editor of your choice. (notepad++ is ideal for this).

    The default code in the filter file only contains sort functions for “FileType.” You will have to add code for filtering on your custom “owstaxId…” properties in three sections as shown below.

    At about line 314, the filter html file contains the “ctx.RefinementControl.propertyName” code. After this section you need to add additional “if (ctx.RefinementControl.propertyName == “owstaxIdyourpropertyname”)” lines of code as shown below marked by –>. Be sure not to include the –> in the actual code.

    if (ctx.RefinementControl.propertyName == “FileType”)
    {
    if (unselectedFilters.length if (ctx.RefinementControl.propertyName == “owstaxIdyourpropertyname1”)
    –> {
    –> unselectedFilters = unselectedFilters.sort(SortAlphabetically);
    –> selectedFilters = selectedFilters.sort(SortAlphabetically);
    –> }

    –> if (ctx.RefinementControl.propertyName == “owstaxIdyourpropertyname2”)
    –> {
    –> unselectedFilters = unselectedFilters.sort(SortAlphabetically);
    –> selectedFilters = selectedFilters.sort(SortAlphabetically);
    –> }
    if (selectedFilters.length > 0 || hasAnyFiltertokens)
    {

    About 50 lines further down you need to add a second section of custom code as shown below for “owstaxIdyourpropertyname”.
    if (shortListSize if (ctx.RefinementControl.propertyName == “owstaxIdyourpropertyname1”) {
    –> shortList = unselectedFilters.slice(0, numShortList).sort(SortAlphabetically);
    –> }
    –> if (ctx.RefinementControl.propertyName == “owstaxIdyourpropertyname2”) {
    –> shortList = unselectedFilters.slice(0, numShortList).sort(SortAlphabetically);
    –> }
    }

    About 30 lines further down you need to add third section of custom code as shown below for “owstaxIdyourpropertyname”.
    if (ctx.RefinementControl.propertyName == “owstaxIdyourpropertyname1”) {
    –> unselectedFilters = unselectedFilters.sort(SortAlphabetically);
    –> }
    –> if (ctx.RefinementControl.propertyName == “owstaxIdyourpropertyname2”) {
    –> unselectedFilters = unselectedFilters.sort(SortAlphabetically);
    –> }
    for (var i = 0;

    Save the html file. Wait for the .js to update automatically.
    NOTE: If you also made any changes to your display templates, like other assets in the Master Page Gallery, they must be Published in order for all users to use them. Once you have completed your edits, return to the Mater Page Gallery and Publish a Major Version of the files so that your users will be able to see them.

    Reply

  12. Hi all,

    I am trying out this as something new, however I want to edit the intervals.

    Do I do so with VS or am I going crazy and cant find it in the HTML.

    Thanks
    All 🙂

    Reply

    1. Hi Darren,
      You can find the intervals string mentioned in the post by adding a search refiner web part to the page. Export the web part to your local file system and then open up the .webpart and look for the string SelectedRefinementControlsJson if you look through the value of this XML you will see the intervals JSON string object.

      HTH

      Reply

  13. Hey Simon,
    I am trying to find the location of the Web Part Configuration XML file and the file where the GetDefaultDateIntervalSpecString(). Can you tell me how to navigation to them and use a generic path. Also where would I go to edit the text “One Year Ago” about the bar? Would it be possible for you to do a youtube video?

    Reply

    1. Hi,
      Download the file zip file at the bottom of the page, unpack it and then the .webpart file is the Web Part Configuration XML.
      The GetDefaultDateIntervalSpecString() is a function which looks at the Web Part Configuration XML file if you search for intervals in the xml file you will find the intervals which you can change..

      Not sure how you can change the One Year Ago as that is part of a slider refiner, I haven’t looked into that.

      I could be persuaded to do a video though it wont be in the next couple of weeks, sorry.

      Hope that helps.

      Regards
      Simon

      Reply

  14. Hey Simon,
    I get the following error:
    Invalid array passed in, ‘,’ expected. (1414): {“refinerConfigurations”:[{“sortBy”:0,”sortOrder”:0,”maxNumberRefinementOptions”:21,”propertyName”:”FileType”,”type”:”Text”,”displayTemplate”:”~sitecollection/_catalogs/masterpage/Display Templates/Filters/Filter_Default.js”,”displayName”:””,”useDefaultDateIntervals”:false,”aliases”:[“format”],”refinerSpecStringOverride”:””,”intervals”:null},{“sortBy”:1,”sortOrder”:1,”maxNumberRefinementOptions”:50,”propertyName”:”DocumentType”,”type”:”Text”,”displayTemplate”:”~sitecollection/_catalogs/masterpage/Display Templates/Filters/Filter_Default.js”,”displayName”:”Document Type”,”useDefaultDateIntervals”:false,”aliases”:null,”refinerSpecStringOverride”:””,”intervals”:null},{“sortBy”:0,”sortOrder”:0,”maxNumberRefinementOptions”:0,”propertyName”:”DocumentTimeline”,”type”:”DateTime”,”displayTemplate”:”~sitecollection/_catalogs/masterpage/Display Templates/iThinkSharePoint/Filter_CustomDefault.js”,”displayName”:”Timeline”,”useDefaultDateIntervals”:false,”aliases”:null,”refinerSpecStringOverride”:””,”intervals”:[-1065,-730,-365,-183,-30,-7,0]},{“sortBy”:0,”sortOrder”:0,”maxNumberRefinementOptions”:0,”propertyName”:”LastModifiedTime”,”type”:”DateTime”,”displayTemplate”:”~sitecollection/_catalogs/masterpage/Display Templates/Filters/Filter_SliderBarGraph.js”,”displayName”:””,”useDefaultDateIntervals”:true,”aliases”:[“Write”,”FileWrite”,”DAV:getlastmodified”],”refinerSpecStringOverride”:””,”intervals”:null}}]}

    Reply

    1. Hi,
      I put the string into Notepad++ and went through to character 1414. It looks like there were too many curly braces }.
      Try this
      {“refinerConfigurations”:[{“sortBy”:0,”sortOrder”:0,”maxNumberRefinementOptions”:21,”propertyName”:”FileType”,”type”:”Text”,”displayTemplate”:”~sitecollection/_catalogs/masterpage/Display Templates/Filters/Filter_Default.js”,”displayName”:””,”useDefaultDateIntervals”:false,”aliases”:[“format”],”refinerSpecStringOverride”:””,”intervals”:null},{“sortBy”:1,”sortOrder”:1,”maxNumberRefinementOptions”:50,”propertyName”:”DocumentType”,”type”:”Text”,”displayTemplate”:”~sitecollection/_catalogs/masterpage/Display Templates/Filters/Filter_Default.js”,”displayName”:”Document Type”,”useDefaultDateIntervals”:false,”aliases”:null,”refinerSpecStringOverride”:””,”intervals”:null},{“sortBy”:0,”sortOrder”:0,”maxNumberRefinementOptions”:0,”propertyName”:”DocumentTimeline”,”type”:”DateTime”,”displayTemplate”:”~sitecollection/_catalogs/masterpage/Display Templates/iThinkSharePoint/Filter_CustomDefault.js”,”displayName”:”Timeline”,”useDefaultDateIntervals”:false,”aliases”:null,”refinerSpecStringOverride”:””,”intervals”:[-1065,-730,-365,-183,-30,-7,0]},{“sortBy”:0,”sortOrder”:0,”maxNumberRefinementOptions”:0,”propertyName”:”LastModifiedTime”,”type”:”DateTime”,”displayTemplate”:”~sitecollection/_catalogs/masterpage/Display Templates/Filters/Filter_SliderBarGraph.js”,”displayName”:””,”useDefaultDateIntervals”:true,”aliases”:[“Write”,”FileWrite”,”DAV:getlastmodified”],”refinerSpecStringOverride”:””,”intervals”:null}]}

      Cheers
      Simon

      Reply

  15. how can i achieve like this dynamically?
    –refiner
    <>
    –sub refiners
    q1(jan-apr)
    q2(may-aug)
    –refiner
    <>
    –sub refiners
    q1(jan-apr)
    q2(may-aug)

    Reply

  16. Hi Simon,

    Thanks for the great post. This was exactly what i was looking for buth the article got me thinking. If you can edit the filter_default display template, why not edit the filter_SliderBarGraph display template to get it working with a slider.

    I followed the same steps for the webpart (exported it and changed the json to include the custom intervals)

    Than I downloaded a copy of the filter_SliderBarGraph.html display template and changed the labels. This was not as straight forward as the default display template but I got it working.

    At the bottom of the display template the following function is called:

    AjaxControlToolkit.SliderRefinementControl.OnPostRenderInitSliderForElement(ctx);

    Right before this function is called I added the code below. I figured out that the values of the labels were located in ctx.FilterLabelOptions.BucketData.BoundaryValues object. Then I changed the Label and NextIntervalLabel property of each interval in the boundaryValues to fit my custom intervals.

    var filter = ctx.FilterLabelOptions;

    var bucket = filter.BucketData;

    var boundaryValues = bucket.BoundaryValues;

    boundaryValues[0].NextIntervalLabel = “Earlier than One Year Ago”;

    boundaryValues[1].NextIntervalLabel = “One Year Ago – Six Months Ago”;

    boundaryValues[2].NextIntervalLabel = “Six Months Ago – Three Months Ago”;
    boundaryValues[2].Label = “Six Months Ago”;

    boundaryValues[3].NextIntervalLabel = “Three Months Ago – One Month Ago”;
    boundaryValues[3].Label = “Three Months Ago”;

    boundaryValues[4].NextIntervalLabel = “One Month Ago – One Week Ago”;
    boundaryValues[4].Label = “One Month Ago”;

    boundaryValues[5].NextIntervalLabel = “One Week Ago – Today”;
    boundaryValues[5].Label = “One Week Ago”;

    boundaryValues[6].NextIntervalLabel = “Today”;
    boundaryValues[6].Label = “Today”;

    ctx.FilterLabelOptions.BucketData.BoundaryValues = boundaryValues;

    Anyway, thanks for this detailed article.

    KR, Robin

    Reply

  17. Hi Simon,

    Nice Post, however in my page I have search result web part and refiner webpart. I have placed some jquery to replace the physical file path to web url. In the initial page load it works fine but when I choose any refiner in the left,the default javacript {} executes and the jquery was not executing.

    Can you please tell me how can i force to exceute my jquery script if i choose refiner? Your help is much appreciated.

    Reply

    1. Hi Balaji,
      Thanks for the message.
      Not sure I entirely understand your situation with what jQuery is doing. But can you check whether you have MDS (Minimal Download Strategy) enabled on your site as it does sound like a symptom of that.

      Kind Regards
      Simon

      Reply

  18. I have requirement for custom refinement interval {today to < 1 month ago}, {1 month ago to 6 moths ago}, {6 months ago to 1 Year ago} can u help out in intervals array..so that I want only 3 refiners to be displayed….

    Reply

  19. This seems to be exactly what I need, which I am immensely thankful for, but one query. The webpart file refers to the file Filter_CustomDefault.js, but this seems not to be part of the zip file download. Can I create it using the existing Filter_Default.js?

    I am attempting to do this for SharePoint Online btw.

    Reply

    1. Hi David,
      Glad that it has helped.

      The solution was built on a publishing site and so the Filter_CustomDefault.html file gets compiled as the Filter_CustomDefault.js file automatically.
      I would suggest creating a publishing site and uploading the file into the Master Page Gallery’s Display Templates folder to get the js file created for you.

      I would say that I’d send you a copy but it will take me a while.

      Cheers
      Simon

      Reply

      1. Thanks Simon,

        I have it all working now. As you say I just needed to upload the new template to the Master Pages\Display Templates\Filters folder in the site collection that contains the search pages, and the javascript file is generated automatically. The

        The SelectedRefinementControlsJson property in the webpart xml needed to be altered slightly as the elements are a little different to those in your example webpart. Perhaps this is specific to SharePoint Online. For others with this issue, I downloaded a copy of the Filer_Default.html from the gallery and used this as a template for Filer_CustomDefault.html.

        Thanks for the original post. Glad I found your blog and will return again.

  20. I am having a bit of trouble after following the post.

    I exported the webpart and imported it back with the changes. I set my intervals to be: [-90, -60, -30]

    I also changed my display template to check for the RefinableDate00 (which is my mapped date property) and I have changed the label to be as follows:

    listData[0].RefinementName =”30 Days”;
    listData[0].RefinementName =”60 Days”;
    listData[0].RefinementName =”90 Days”;

    The problem I am seeing is that this is my output on the webpart once all these changes were made:

    60 Days
    90 Days
    One Week Ago to Today
    Today

    Where are the other two coming from? I only want to see and filter by 30 days past due, 60 days past due, and 90 days past due?

    Reply

  21. Hi Simon, just found this useful blogs. I hate myself find this too late. It seems that all the screenshot are not available. Can I check if you made the changes on top of the Single Selection Template. It seems that one. And is it possible to share sample code with me as reference. I’m currently facing the same problem to modify Date time refiner in SharePoint 2016 environment. Thanks.

    Reply

    1. Hi
      Hmm will have to look at the image links it has been a while since this post was done.

      Did the link at the bottom help you it should have all the JSON code?

      Cheers
      Simon

      Reply

Thoughts? Comments about this post? Please leave them here..

This site uses Akismet to reduce spam. Learn how your comment data is processed.