Created
December 17, 2015 12:54
-
-
Save beckettkev/e808b5ff5e9f42600ddc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
( function ( workspace, $ ) { | |
var matches = []; | |
//this is where we keep track of our refinement items for the Workspace refiner | |
var workspaceItems; | |
workspace.Mapping = { | |
//straight site collection one to one mapping on SPSiteURL. This is detailed in the first part of the scenario. | |
Simple: { | |
'Mappings': [ | |
{ 'Label': 'News', 'Relative': '/sites/news' }, | |
{ 'Label': 'Help', 'Relative': '/sites/help' }, | |
{ 'Label': 'Search', 'Relative': '/sites/search' }, | |
{ 'Label': 'Location', 'Relative': '/sites/location' } | |
], | |
'RegExpValues' : [ | |
/^\/sites\/news/, | |
/^\/sites\/help/, | |
/^\/sites\/search/, | |
/^\/sites\/location/ | |
] | |
}, | |
//Used for sounds like matches (e.g. /sites/essentials, /sites/essentials-hr etc..) | |
Standard: { | |
'Mappings': [ | |
{ 'Label': 'Essentials', 'Relative': '/sites/essentials' }, | |
{ 'Label': 'Projects', 'Relative': '/sites/project' }, | |
{ 'Label': 'Bids', 'Relative': '/sites/bid' } | |
], | |
'RegExpValues': [ | |
/^\/sites\/essentials/, | |
/^\/sites\/project/, | |
/^\/sites\/bid/ | |
] | |
}, | |
//used for multiple differing URL mappings for the communities IA (e.g /sites/communities, /sites/community, /sites/water, /sites/rail-engineering etc..) | |
Community: { | |
'Mappings': [ | |
{ | |
'Label': 'Communities', 'Relative': '/sites/communities', | |
'Label': 'Communities', 'Relative': '/sites/communityengagement', | |
'Label': 'Communities', 'Relative': '/sites/engineeringpractice', | |
'Label': 'Communities', 'Relative': '/sites/itdecisions', | |
'Label': 'Communities', 'Relative': '/sites/communicatingsuccess' | |
} | |
], | |
'RegExpValues' : [ | |
/^\/sites\/communities/, | |
/^\/sites\/engineeringpractice/, | |
/^\/sites\/itdecisions/, | |
/^\/sites\/communicatingsuccess/ | |
] | |
}, | |
/* | |
Meanwhile - underneath the community mapping | |
The Helper Methods (FindCategoryMatch and Category) to check our refinement managed property value against our array mappings (SPSiteURL) | |
*/ | |
FindCategoryMatch: function (arr, key, url, remember) { | |
var e = 0; | |
var valid = arr.some(function (regexp, index, array) { | |
e = index; | |
return regexp.test(url); | |
}); | |
var label = key !== 'Community' ? workspace.Mapping[key].Mappings[e].Label : workspace.Mapping[key].Mappings[0].Label; | |
var match = { 'Valid': valid, 'Index': e, 'Url': url, 'Name': valid ? label : '' }; | |
//add the new match into the refinement match array if a match is found | |
if (valid && remember) { | |
matches.push(match); | |
} | |
return match; | |
}, | |
Category: function (arr, key, url, remember) { | |
var match, num; | |
//check to see if we have any matches, if not gather this one and store it in our matches object (in case we need to use the info again) | |
if (matches.length === 0) { | |
match = workspace.Mapping.FindCategoryMatch(arr, key, url, remember); | |
} else { | |
//check if we have this information already and serve it up if we do (otherwise gather it) | |
if (matches.some(function (e, index, array) { num = index; return e.Url === url })) { | |
match = matches[num]; | |
} else { | |
match = workspace.Mapping.FindCategoryMatch(arr, key, url, remember); | |
} | |
} | |
return match; | |
} | |
}; | |
/* | |
Now we need to include the private internal and public methods for our custom refiner | |
*/ | |
//This is a cleanup function that removes refinements from a refiner if they are not needed | |
workspace.RemoveDeadRefinerItems = function (listData) { | |
var j = workspaceItems.Deletions.length - 1; | |
//when deleting items from an array, we do it in reverse order to preserve the array indexes integrity. | |
while (j > -1) { | |
delete listData[parseInt(workspaceItems.Deletions[j])]; | |
j -= 1; | |
} | |
init( ); | |
return listData; | |
}; | |
//Used for house keeping to reset the internal matches array | |
workspace.ClearExistingMatches = function ( ) { | |
//at the start of setting up the refiner, clear down previous matches | |
matches = []; | |
}; | |
//internal method used for getting the refinement value for the refinement. | |
function setRefinementTokens(item, options, url, push) { | |
if (!push) { | |
item.RefinementName = options.Name; | |
} | |
item.RefinerName = options.Property; | |
item.Modifier = options.Property; | |
if (options.Type === 'contains') { | |
item = addOrPushRefinementToken(item, 'RefinementTokenWrappedValues', '"' + url + '*"', push); | |
item = addOrPushRefinementToken(item, 'RefinementTokens', '"' + url + '*"', push); | |
} else if (options.Type === 'equals') { | |
item = addOrPushRefinementToken(item, 'RefinementTokenWrappedValues', 'equals("' + url + '*")', push); | |
item = addOrPushRefinementToken(item, 'RefinementTokens', '"ǂǂ' + MyCompany.MyProject.Utilities.stringToHex(url) + '"', push); | |
} | |
return item; | |
} | |
//internal method for actually setting the refinement values | |
function addOrPushRefinementToken(item, key, value, push) { | |
if (push) { | |
item[key].push(value); | |
} else { | |
item[key][0] = value; | |
} | |
return item; | |
} | |
//house keeping internal method for clearing out unnecessary properties from the refinement JavaScript object if there are now multiple refinement values | |
function deleteSingleTokenProperties(item, options) { | |
if (typeof item.RefinementToken !== 'undefined') { | |
delete item.RefinementToken; | |
delete item.RefinementValue; | |
} | |
return item; | |
} | |
//internal method for aggregating the count of a soon to be removed refinement item into the kept refinement and then marking the refinement item for deletion | |
function removeRefinerItem(item, options) { | |
workspaceItems[options.Name].Count += item.RefinementCount; | |
workspaceItems[options.Name].Refinements.push(item.RefinementName); | |
workspaceItems.Deletions.push(options.Id); | |
return workspaceItems; | |
} | |
//The main method called from the display template to process the refinement item | |
workspace.SetWorkspaceRefinementItem = function (listData, options) { | |
var current = null; | |
//relative url of the refinement item for comparisons | |
var url = listData[options.Id].RefinementValue.toLowerCase().replace(window.location.protocol + '//' + window.location.host, ''); | |
var base = window.location.protocol + '//' + window.location.host; | |
//check to see if the refinement item maps to the simple mappings (scenario one) | |
if (workspace.Mapping.Category(workspace.Mapping.Simple.RegExpValues, 'Simple', url, false).Valid) { | |
current = workspace.Mapping.Category(workspace.Mapping.Simple.RegExpValues, 'Simple', url, true); | |
options.Name = typeof options.Name === 'undefined' ? current.Name : options.Name; | |
listData[options.Id] = setRefinementTokens(listData[options.Id], options, (base + url), false); | |
listData[options.Id] = deleteSingleTokenProperties(listData[options.Id], options); | |
//check to see if the refinement item maps to the second scenario | |
//there maybe more than one mapping to this refinement, but they all should be returned by the same contains statement | |
} else if (workspace.Mapping.Category(workspace.Mapping.Standard.RegExpValues, 'Standard', url, false).Valid) { | |
current = workspace.Mapping.Category(workspace.Mapping.Standard.RegExpValues, 'Standard', url, true); | |
options.Name = typeof options.Name === 'undefined' ? current.Name : options.Name; | |
//get the refinement item url from the mapping (in case the top result in this mapping differs) | |
url = workspace.Mapping.Standard.Mappings[current.Index].Relative.indexOf('https:') > -1 ? workspace.Mapping.Standard.Mappings[current.Index].Relative : base + workspace.Mapping.Standard.Mappings[current.Index].Relative; | |
if (typeof workspaceItems[options.Name] === 'undefined') { | |
listData[options.Id] = setRefinementTokens(listData[options.Id], options, url, false); | |
workspaceItems[options.Name] = { 'Id': options.Id, 'Count': listData[options.Id].RefinementCount, 'Refinements': [listData[options.Id].RefinementValue] }; | |
listData[options.Id] = deleteSingleTokenProperties(listData[options.Id], options); | |
} else { | |
//we don't want to output this refinement item | |
workspaceItems = removeRefinerItem(listData[options.Id], options); | |
//aggregate the refinement item count to include this one and clearup unused properties (if necessary) | |
listData[workspaceItems[options.Name].Id].RefinementCount = workspaceItems[options.Name].Count; | |
} | |
//finally check to see if the refinement item maps to the third and more complex refinement scenario | |
} else if (workspace.Mapping.Category(workspace.Mapping.Community.RegExpValues, 'Community', url, false).Valid) { | |
//work out if the community does not start with refiner item sounds like (/sites/communit*) pattern (e.g. /sites/water or /sites/construction-community | |
var alternate = !workspace.Mapping.Category([workspace.Mapping.Community.RegExpValues[0]], 'Community', url, false).Valid; | |
//Override the incomming ManagedProperty | |
options.Property = 'SPSiteURL'; | |
options.Type = 'equals'; | |
current = workspace.Mapping.Category(workspace.Mapping.Community.RegExpValues, 'Community', url, true); | |
options.Name = typeof options.Name === 'undefined' ? current.Name : options.Name; | |
//get the refinement item url from the mapping (in case the top result in this mapping differs). We only want to map to /sites/communit | |
var ending = workspace.Mapping.Community.Mappings[0].Relative; | |
/* | |
if it was possible to do two contains int he same query, we could amend the url of the refinement item does not meet the communities pattern, save it in the url variable | |
url = alternate ? listData[options.Id].RefinementValue : base + ending; | |
*/ | |
url = listData[options.Id].RefinementValue; | |
if (typeof workspaceItems[options.Name] === 'undefined') { | |
//we want our refinement item to point to a specific contains URL which we get from the mappings (ending) | |
listData[options.Id] = setRefinementTokens(listData[options.Id], options, url, false); | |
workspaceItems[options.Name] = { 'Id': options.Id, 'Count': listData[options.Id].RefinementCount, 'Refinements': [url] }; | |
listData[options.Id] = deleteSingleTokenProperties(listData[options.Id], options); | |
} else { | |
//if (alternate || workspaceItems[options.Name].Refinements.indexOf(url) === -1) { | |
//this is either a new site (alteranteUrl) or it is the catch all site which we haven't got in the refinement item yet. | |
//we need to push this url into the Community refinement item (listData[workspaceItems[options.Name].Id]) either way | |
listData[workspaceItems[options.Name].Id] = setRefinementTokens(listData[workspaceItems[options.Name].Id], options, url, true); | |
//} | |
//then update the visible refinment item count to reflect this new total | |
listData[workspaceItems[options.Name].Id].RefinementCount = workspaceItems[options.Name].Count; | |
//mark the actual refiner item for deletion | |
workspaceItems = removeRefinerItem(listData[options.Id], options); | |
} | |
//if the refinement item does not map to one of our maps, mark it for deletion. | |
} else { | |
//mark the actual refiner item for deletion, it doesn't match one of our products | |
workspaceItems.Deletions.push(options.Id); | |
} | |
//our work here is done. | |
return listData; | |
}; | |
//set things up for creating the refiner, this is initialised only when the script is loaded. | |
function init( ) { | |
workspaceItems = { 'Deletions': [] }; | |
} | |
init( ); | |
})( myCompany.myProject.Search.Workspace = myCompany.myProject.Search.Workspace || {}, jQuery ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment