Add Filters To URL
1 min
There are scenarios when it is useful for the user selected filters and/or merchant preset filters to be captured as part of the SRLP or Category URL.
For Example:
- Allow for consistent tracking of selected facets.
- Reusable 'landing page' links
To accomplish this we will add in a custom override module named addFiltersToURL that will:
- Intercept the outgoing query
- Analyze the existing URL string
- Update the localstorage of selected facets
- Apply the necessary filters to the outgoing query
- Update the existing URL string
Template JS Override
Add the supporting module, addFiltersToURL and apply its use to the page overrides.
Note : The example is set for both Search (landing) and Category (catnav) scopes.
Full Example
<script type="text/javascript">
klevu.modifyRequest("landing,catnav", function(data, scope){
// Apply the selected facets from the current URL string
klevu.search.modules.addFiltersToURL.base.getAndUpdateFilters(data, scope);
});
klevu.afterTemplateRender("landing,catnav", function(data, scope){
// Add selected facets to the URL string
klevu.search.modules.addFiltersToURL.base.setFilters(data, scope);
});
</script>
<script type="text/javascript">
/* Klevu addFiltersToURL Module */
(function(klevu) {
klevu.extend(true, klevu.search.modules, {
addFiltersToURL: {
base: {
setFilters: function(data, scope, queryId) {
var activeQueryId = klevu.getObjectPath(data, "context.activeQueryId");
if (queryId && queryId.length) {
activeQueryId = queryId;
}
var filterQueryParam = activeQueryId + "Filters";
var activeQueryFilters = klevu.getObjectPath(data, "template.query." + activeQueryId + ".filters");
var filterValuesQueryParam = "";
if (activeQueryFilters) {
klevu.each(activeQueryFilters, function(key, filter) {
var selectedFilterKeyString = "";
var filterOptions = filter.options;
var selectedValues = "";
if (filterOptions && filterOptions.length) {
klevu.each(filterOptions, function(key, option) {
if (option.selected === true) {
if (selectedValues.length) {
selectedValues += ",";
}
selectedValues += option.value;
}
});
} else if (filter.type === "SLIDER") {
var startValue = filter.start;
var endValue = filter.end;
var minValue = filter.min;
var maxValue = filter.max;
if (typeof startValue !== "undefined" && startValue !== null && typeof endValue !== "undefined" && endValue !== null) {
if (Number(startValue) === Number(minValue) && Number(endValue) === Number(maxValue)) {} else {
selectedValues = startValue + "-" + endValue;
}
}
}
if (selectedValues.length) {
selectedFilterKeyString += filter.key + ":" + selectedValues;
}
if (selectedFilterKeyString.length) {
if (filterValuesQueryParam.length) {
filterValuesQueryParam += ";";
}
filterValuesQueryParam += selectedFilterKeyString;
}
});
}
var searchPath = window.location.search;
var updatedPath;
if (filterValuesQueryParam.length) {
// Add or update the filter parameter when there are values
filterValuesQueryParam = encodeURIComponent(filterValuesQueryParam);
updatedPath = klevu.dom.helpers.updateQueryStringParameter(searchPath, filterQueryParam, filterValuesQueryParam);
} else {
// Remove the filter parameter when empty
updatedPath = klevu.dom.helpers.updateQueryStringParameter(searchPath, filterQueryParam, "");
updatedPath = updatedPath.replace("?" + filterQueryParam + "=&", "?");
updatedPath = updatedPath.replace("&" + filterQueryParam + "=", "");
updatedPath = updatedPath.replace("?" + filterQueryParam + "=", "");
}
// Handle when no URL parameters are present
if (!updatedPath || updatedPath === "" || updatedPath === "?") {
updatedPath = window.location.pathname;
}
if ('undefined' !== typeof window.history && 'undefined' !== typeof window.history.replaceState) {
window.history.replaceState({}, "", updatedPath);
} else {
console.log("This browser does not have the support of window.history or window.history.replaceState");
}
},
getAndUpdateFilters: function(data, scope, queryId) {
var hasAlreadyTriggered = klevu.getObjectPath(scope.kScope, "element.kScope.getAndUpdateFiltersTriggered");
if (hasAlreadyTriggered === true) {
return;
}
var matchedQueryParamId = ""
, matchedQueryParamValue = "";
var recordQueries = klevu.getObjectPath(data, "request.current.recordQueries");
if (recordQueries && recordQueries.length) {
klevu.each(recordQueries, function(key, query) {
if (query.id) {
var filtersFromURL = klevu.dom.helpers.getQueryStringValue(query.id + "Filters");
if (filtersFromURL && filtersFromURL.length) {
matchedQueryParamId = query.id;
matchedQueryParamValue = filtersFromURL;
}
}
})
}
klevu.setObjectPath(scope.kScope, "element.kScope.getAndUpdateFiltersTriggered", true);
var activeQueryId = klevu.getObjectPath(data, "context.activeQueryId");
if (queryId && queryId.length) {
activeQueryId = queryId;
} else if (matchedQueryParamId.length && matchedQueryParamValue.length) {
activeQueryId = matchedQueryParamId;
var storage = klevu.getSetting(scope.kScope.settings, "settings.storage");
if (storage.tabs) {
storage.tabs.setStorage("local");
storage.tabs.mergeFromGlobal();
storage.tabs.addElement("active", activeQueryId);
storage.tabs.mergeToGlobal();
}
}
var filterQueryParam = activeQueryId + "Filters";
var filtersFromURL = klevu.dom.helpers.getQueryStringValue(filterQueryParam);
if (filtersFromURL && filtersFromURL.length) {
var facets = filtersFromURL.split(";");
if (facets) {
klevu.each(facets, function(key, facet) {
var splitFacet = facet.split(":");
if (splitFacet.length) {
var facetKey = splitFacet[0];
var facetValues = splitFacet[1].split(",");
var applyFilters = klevu.getObjectPath(data, "localOverrides.query." + activeQueryId + ".filters.applyFilters.filters");
if (applyFilters && applyFilters.length) {
var isExistingKey = false;
klevu.each(applyFilters, function(key, applyFilter) {
if (applyFilter.key === facetKey) {
isExistingKey = true;
klevu.each(facetValues, function(key, facetValue) {
var isFilterOptionMatched = false;
klevu.each(applyFilter.values, function(key, value) {
if (facetValue === value) {
isFilterOptionMatched = true;
}
});
if (!isFilterOptionMatched) {
applyFilter.values.push(facetValue);
}
});
}
});
if (!isExistingKey) {
applyFilters.push({
key: facetKey,
values: facetValues
});
}
} else {
klevu.setObjectPath(data, "localOverrides.query." + activeQueryId + ".filters.applyFilters.filters", [{
key: facetKey,
values: facetValues
}]);
}
}
});
}
}
}
},
build: true
}
});
}
)(klevu);
</script>