Working with Refiners in SPO

When you find yourself in a scenario where you need to load a search results page, pre-filtered to a subsection of results by a search term, you can do this by passing the query via the URL. However, things get a little bit more complicated when you need to show the pre-selected query in the refiner(s) UI.

This blog post will walk you through what the issue is and how to get around it, allowing you to highlight the relevant refiner(s) for the search term when the search results page loads.

First of all, using the search results page as an example, let’s take a look by using a typical example to see how our search query is structured:

https://awesome.sharepoint.com/sites/search/pages/Results.aspx?k=owsRegion%3D%22UK20Region%22

If you decode this URL and focus specifically on the query:

​owsRegion:”UK Region”

We are filtering the results set to just show items which have been tagged with the UKMEA Region. Now this works, it will pre-filter the result set and display items in the search results which have been tagged with the UKMEA Region, however the issue is that this is not shown in the actual refiners (take a look at the screenshot below, the refiner on the left should be bold to show that we are filtering on Region for the “UK Region”).

So, what we need to do now is take a look at the refiner API and see if we can achieve what we want programmatically. Here is a good blog post detailing our options:

http://www.eliostruyf.com/part-5-search-refiner-control-methods-explained/

We will focus on the ‘addRefinemanetFilter’ method and to achieve what we have done so far with the URL, you can run the following JavaScript code (bit nasty, demonstration code):

Remember to make sure your refiner term is encased with double quotes if it has a space. This filters the results but annoyingly, the refiner is still not preselected! So let’s take a look behind the scenes to see what’s going on.

If we compare our URL after we have run the example code shown above (I have decoded the URLs for readability):

So you can see that when you click on the link as opposed to actually querying the results programmatically, an extra section is added to the JSON parsed through to search known as the refinement token (highlighted above in bold). Without this, the refiner will not highlight so you need to make sure it is present.

How do we get the Refinement Token?

There are two ways to get the refinement token, the first and easiest is to convert the search term into a hex value (in our case UK Region is 55 4B 4D 45 41 20 52 65 67 69 6F 6E) and then remove the spaces and set it to lower case. I have pulled together a quick function to do this below:

Alternatively, using a little bit of jQuery we can get back the filtered term element from the DOM (annoyingly all of the refiner links have the same ID, but we won’t get into why this is all kinds of wrong in this blog post):

This gives us the href link tag with the onClick event (again urggh!!) containing the missing attribute:

<a title=”Refine by: UK Region” id=”FilterLink” onclick=”$getClientControl(this).addRefinementFiltersJSON(‘{\u0022owsRegion\u0022:[\u0022\\\u0022\u01C2\u01C2554b4d454120526567696f6e\\\u0022\u0022]}’);” href=”javascript:{}”>..

So now we have this information, we can either replicate the search URL after a refiner selection or we can use the ‘addRefinmentFiltersJSON‘ method, passing in the refinement token. Simples. Taking this one step further, we can easily build a function which redirects a user to the search page with the correct URL structure (given the search property and the term), here is one I made earlier:

One thing to note is that if you do provide the refinement token, you need to ensure that there is a refiner for the property. This may sound quite straight forward, but quite often you can be searching for results filtered by a property which is not included in the refiners and you will need to handle such a scenario in your logic.

To give an example of how you can selectively include the refinement JSON in your URL, take a look at the following amended ‘loadFilteredResults’ method, which has a conditional output for when the search term is in the refiners:

Summary​

You have to use ‘addRefinementFiltersJSON‘ in order to show the selected refiners in the UI. It is important to supply the refinement token within this method (which you can get by converting the refinement term into hex). This blog post goes through this in detail, using the search results page as an example.

Working with Refiners in SPO

Leave a Reply

%d bloggers like this: