Multi List Filters
Multi List filters are comprised of one or more list filters, where the options in each list depends on the previous selection.
An example use case for this kind of filter is for filtering a list of cars. The Multi List Filter may have 3 lists in this case - make, model, and year. When the user selects a make, the models will become selectable, and will be based on the selected make. When a model is selected, the years become available.
Unlike List Filters, only one item in each list is selectable. So, in the above example, only one make, one model, and one year can be selected.
A query for multi list filters looks like this:
... on MultiListFilter {
id
name
isActive @client
lists {
id
hasActiveItems @client
name
items {
id
value
text
resultCount
isActive @client
}
}
}
Notice the @client
directives. When rendering the multi list filter these help you to indicate whether the multi list filter itself is active, which lists have active items, and which item in that list are selected.
useMultiFilter
The useMultiFilter hook can be used to update multi list filters. It will update the state of the 3 client fields in the query above, and will also update the URL params with the selected values.
const { apply, clearList, clearFilter } = useMultiFilter({ filter })
Arguments
Argument | Type | Required? | Description |
---|---|---|---|
options | Options | true | Required options object |
Options
Option | Type | Required? | Description |
---|---|---|---|
filter | MultiListFilter | true | The MultiListFilter you would like to act on |
Result
Property | Type | Description |
---|---|---|
apply | ({ value, listIndex }: { value: string, listIndex: number }) => Promise<ExecutionResult<MultiListFilter>> |
Applies the given value to the list specified by listIndex. Returns a promise that will resolve with the multi list filter. |
clearList | ({ listIndex }: { listIndex: number }) => Promise<ExecutionResult<MultiListFilter>> |
Clears the selected value for the list specified by listIndex. Any lists with higher indexes will also be cleared. |
clearFilter | () => void | Clears all selected values |
Example
function MultiListFilter({ multiListFilter }) {
const { apply, clearList } = useMultiFilter({
filter: multiListFilter
});
// A multiListFilter has one or more `lists`.
return multiListFilter.lists.map((list, index) => (
<FilterDropdownMenu>
<Button disabled={list.items.length === 0}>
<span>{list.name}</span>
{list.hasActiveItems ? <Check /> : <Carot className="carot" />}
</Button>
<Items as="ul">
{list.items.map(item => (
<DropdownMenuItem
key={item.id}
onSelect={({ setIsOpen }) => {
apply({
value: item.value,
listIndex: index
});
setIsOpen(false);
}}
>
<span>{item.text}</span>
{item.isActive ? <Check /> : <span>{item.resultCount}</span>}
</DropdownMenuItem>
))}
<>
{list.hasActiveItems && (
<DropdownMenuItem
onSelect={({ setIsOpen }) => {
setIsOpen(false);
clearList({ listIndex: index });
}}
>
{t('Clear filter')}
</DropdownMenuItem>
)}
</>
</Items>
</FilterDropdownMenu>
));
}