3min
Add Filters To URL
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 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
See : Custom Overrides for details on preparing for Klevu JS overriding
See : An in-action example and the source code on the Klevu CodeSandbox
Template JS Override
Add the supporting modules addFiltersToURL and apply its use(s) to the landing page override.
Note : the same addFiltersToURL module can be used on Category pages by applying the override to the catnav scope as well.
Full Example
JavaScript
|
<script type="text/javascript"> // Defer initialization (powerUp) of the Klevu components klevu({ powerUp: { landing: false } }); // OVERRIDE : LANDING PAGE klevu.coreEvent.build({ name: "myLandingPageOverride", fire: function () { if (klevu.getGlobalSetting("flags.setRemoteConfigLanding.build", false)) { return true; } return false; }, maxCount: 150, delay: 100 }); klevu.coreEvent.attach("myLandingPageOverride", { name: "attachToMyLandingPageOverride", fire: function () { // Apply the facets supplied in the current URL string klevu.search.landing.getScope().chains.request.control.addAfter("initRequest", { name: "selectFiltersFromURL", fire: function (data, scope) { klevu.search.modules.addFiltersToURL.base.getAndUpdateFilters(data, scope); } }); // Add selected facets to the URL string klevu.search.landing.getScope().chains.template.events.add({ name: "attachURLUpdateOnFilterSelect", fire: function (data, scope) { klevu.search.modules.addFiltersToURL.base.setFilters(data, scope); } }); // power up klevu({ powerUp: { landing: true } }); } }); // 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; } }); } filterValuesQueryParam = encodeURIComponent(filterValuesQueryParam); var searchPath = window.location.search; var updatedPath = klevu.dom.helpers.updateQueryStringParameter(searchPath, filterQueryParam, filterValuesQueryParam); if (!filterValuesQueryParam.length) { updatedPath = updatedPath.replace("&" + filterQueryParam + "=", ""); } 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>