/**
* Helper method to store facet values of a particular section (label) in session storage.
* This is necessary because even with disjunctive facets
* Elastic will filter out facets of other groups that have no items to filter on,
* leaving us with empty labels.
*
* So, we will save the values into a session storage and display them, greyed out,
* even when elastic would have filtered them out.
*
* @param {Array} facets an array of facets within this group (label) as provided by elastic
* @param {String} label the label for this facet section
* @returns the values (individual checkbox names) of this facet section
*/
export function handleStorage(facets, label) {
let values = [];
if (Array.isArray(facets)) { // getting the current values from the provided facets
facets.forEach((facet) => values.push(facet.value))
}
// window.sessionStorage.clear() // for debugging
let storedValues = window.sessionStorage.getItem(SESSION_KEY);
if (storedValues) {
storedValues = JSON.parse(storedValues);
}
if (storedValues && storedValues.hasOwnProperty(label)) {
// if we had values, and the values have this label, update just in
// case (found issue where it saved an empty array first)
values = [...new Set([...values, ...storedValues[label]])];
storedValues[label] = values;
} else {
if (storedValues) { // if we have stored values, just not this label, then add our current values
storedValues[`${label}`] = values;
} else {
storedValues = { // if we don't have stored values at all, create the object
[`${label}`]: values
}
}
}
window.sessionStorage.setItem(SESSION_KEY, JSON.stringify(storedValues))
return values;
}
SESSION_KEY
is just a string constant of your choice.
I have my own filter component that I created based on the original one from the react-search-ui-views, using the withSearch
HOC with
withSearch(({ filters, facets, addFilter, removeFilter })
Then in the actual component....
const facetsForField = facets[field];
const facetValues = getSelectedFacetValues(
facetsForField,
filters,
field,
FILTER_TYPE
);
const storedFacets = handleStorage(facetValues, label);
Where field
and label
are props passed in.
Finally...
storedFacets.forEach(( value ) => {
const available = facetValues.find((availableValue) => {
return availableValue.value === value;
});
const disabled = available === undefined;
const { count, selected } = available
? available
: { count: "0", selected: false };
rows.push(
<Row key={`r-${value}`}>
<Column lg={14} key={`c-${value}`}>
<Checkbox
onChange={() =>
selected
? removeFilter(field, value, FILTER_TYPE)
: addFilter(field, value, FILTER_TYPE)
}
key={value}
labelText={value}
checked={selected}
disabled={disabled}
title={
disabled
? "Filter not available with the already selected options"
: `Filter for ${value}`
}
id={`cb-${value.toLowerCase()}`}
/>
</Column>
<Column className={cx(counter)} lg={2} key={`cc-${value}`}>
{count}
</Column>
</Row>
);
});
We're using the carbon design framework.
Hope this helps