Use Dependent Facets

Being able to control the visibility of elements in a page depending on some arbitrary condition is a task that application developers often need to tackle.

In the context of a search application, a frequent use case is to define relationships between facets (or filters), so that a dependent facet will only appear when the end user interacts with its specified parent facet.

Let’s assume that you have a @moviegenre facet field in your Coveo index, as well as a @moviesubgenre facet field.

@moviegenre may contain values such as Action, Comedy, and Drama.

@moviesubgenre may contain values such as War and Military Action, Martial Arts Action, Parody Comedy, and Historical Drama.

In your search interface, you may want the end user to only see the Movie genre facet initially, and to make the Movie subgenre facet appear only when a selection is made in the Movie genre facet.

Defining the Relationship

Every Headless controller exposes its state, and can subscribe to any state changes. Defining a relationship between facets involves retrieving the relevant data from the state and using this data to control the visual appearance of the application.

import {Facet, loadFacetSetActions, SearchEngine} from '@coveo/headless';
 
function makeDependent(
 parentFacet: Facet,
 dependentFacets: Facet[],
 engine: SearchEngine
) {
 parentFacet.subscribe(() => {
   const isParentActive = parentFacet.state.values.some(
     (v) => v.state !== 'idle'
   );
   if (!isParentActive) {
     dependentFacets.forEach((childFacet) =>
       clearChildFacet(childFacet, engine)
     );
   }
 
   controlAppearanceOfThePageWithParentState(isParentActive);
 });
}
 
function clearChildFacet(childFacet: Facet, engine: SearchEngine) {
 loadFacetSetActions(engine).deselectAllFacetValues(childFacet.state.facetId);
}
 
function controlAppearanceOfThePageWithParentState(isParentActive: boolean) {
 // your code
}

In the example above, the makeDependent function can be called to define a relationship between parent facet, and one or many dependent facets.

You could modify the isParentActive condition to fit your particular use case. For example, instead of verifying whether any value is selected (i.e., isn’t idle) in the parent facet, you could verify the state of a specific value.

We provide no sample implementation for the controlAppearanceOfThePageWithParentState function, as this would greatly vary based on what Web framework you’re using (e.g., Angular, React, Vue).

React Example

To better understand these explanations, you can refer to this example made with React: Dependent Facet React Example.

What's Next for Me?