PortiBlog

Get SharePoint Search Parameters from URL Hash

26 augustus 2019

This is part of a solution in which we allowed the end user to save search queries after using the refinement panel, paging or making query changes in the search results page.

For this I needed to be able to access the search parameters from behind the ‘#’, the ‘hash’, in the url querystring.

When using the SharePoint search box, your url will usually look somewhat like this after you have performed a search:

http://server/pages/search.aspx?k=myquery

When you are in your search results page and you decide to change your query, your url will get a ‘hash’ add-on, resulting in something like this:

http://server/pages/search.aspx?k=myquery#k=mynewquery.

When you apply any filtering / refiners, or simply start paging your results, more encoded gibberish will be added:

In this case we filter on FileType: pdf, searchword ‘mynewquery’:

http://server/pages/search.aspx?k=myquery#Default=%7B%22k%22%3A%22mynewquery%22%2C%22r%22%3A%5B%7B%22n%22%3A%22FileType%22%2C%22t%22%3A%5B%22equals(%5C%22pdf%5C%22)%22%5D%2C%22o%22%3A%22or%22%2C%22k%22%3Afalse%2C%22m%22%3Anull%7D%5D%7D

There is no way to extract these new search parameters from behind the ‘hash’, or ‘#’, from serverside code, since anything behind a ‘#’ is clientside and will not be sent to the server.

You can however use javascript. But, the markup behind the # can differ quite a lot depending on the field type being filtered. So, some transformation is necessary.

To start off, we extract the querystring and parse the value to JSON, values are placed in an Array.

    var hash = "";
var fullUrl = window.location.href;
var i = fullUrl.indexOf("#");
if (i > -1)
hash = fullUrl.substring(i);

var hashQuery = [];

var queryGroups = hash.split("#");
for (var i = 1; i < queryGroups.length; i++) { if (queryGroups[i].length > 0) {
var keyValue = queryGroups[i].split("=", 2);
var key = keyValue[0];
var encodedValue = keyValue[1];

if (key === "Default") { // json string format
var jsonStringValue = decodeURIComponent(encodedValue);
var safejsonStringValue = jsonStringValue.replace("’", "\’").replace("'", "\'");
var queryObject = JSON.parse(safejsonStringValue);
hashQuery[key] = queryObject;
}
else if (key === "k") { // simple format
hashQuery[key] = encodedValue;
}
}
}

After we collect the values, we need to make some sense of them so we can use them later on.

I have encountered an array (multi select filters), hex values (DocumentType), date ranges and simple key / values. Please see comments in code.

   if (hashQuery["Default"] != undefined) { // json string format
for (var i = 0; i < hashQuery["Default"].r.length; i++) {
if (hashQuery["Default"].r[i].m != null) { // check if 'm' contains data
for (var n = 0; n < hashQuery["Default"].r[i].t.length; n++) {
var keywordkey = hashQuery["Default"].r[i].n;
var keywordvalue = hashQuery["Default"].r[i].m[hashQuery["Default"].r[i].t[n]];
}
}
else {
for (var n = 0; n < hashQuery["Default"].r[i].t.length; n++) {
var tvalue = hashQuery["Default"].r[i].t[n];
if (tvalue.indexOf('ǂ') !== -1) {
// value is HEX type
var keywordkey = hashQuery["Default"].r[i].n;
var keywordvalue = hex2a(tvalue);
// your code here
}
else if (tvalue.indexOf('range(') !== -1) {
// value is a range (i.e. dates)
var rangestring = tvalue.match(/\((.+)\)/)[1];
var dates = rangestring.split(', ');
var minvalue = dates[0].split('T')[0]; // start of range
var maxvalue = dates[1].split('T')[0]; // end of range
if (minvalue !== "min") { // check for actual date or minvalue
var mindate = new Date(dates[0]);
var day = mindate.getDate();
if (day < 10)
day = "0" + day;
var month = mindate.getMonth() + 1;
if (month < 10)
month = "0" + month;
var keywordkey = hashQuery["Default"].r[i].n;
var keywordmindate = day + "-" + month + "-" + mindate.getFullYear();
// your code here
}
if (maxvalue !== "max") { // check for actual date or maxvalue
var maxdate = new Date(dates[1]);
var day = maxdate.getDate();
if (day < 10)
day = "0" + day;
var month = maxdate.getMonth() + 1;
if (month < 10)
month = "0" + month;
var keywordkey = hashQuery["Default"].r[i].n;
var keywordmaxdate = day + "-" + month + "-" + maxdate.getFullYear();
// your code here
}
}
else { // simple format
var keywordkey = hashQuery["Default"].r[i].n
var keywordvalue = tvalue;
// your code here
}
}
}
}
}
else if (hashQuery["k"] != undefined) { // simple value (no json)
var keywordkey = "k";
var keywordvalue = hashQuery["k"];
// your code here
}

For extracting the hex values add this function:

function hex2a(hexx) {
var hex = hexx.toString();
hex = hex.replace('"', '').replace('"', '').replace('ǂ', '').replace('ǂ', '');
var str = '';
for (var i = 0; i <= (hex.length - 2) ; i += 2) {
str += String.fromCharCode(parseInt(hex.substring(i, i + 2), 16));
}
return str;
}

Download the full .js file here.

Submit a comment