You've by now seen the out-of-the-box Search UI. You've got a search bar on top, search results on the right below that, and then facets on the left. It works, nothing wrong with it.
In many cases, it's all that's needed. Add a splash of CSS here and there and that's what most search pages look like. Does it have to? No.
In fact, the interaction with the entire Search UI is flexible enough that you can make the entire page look and feel like a completely new experience if so desired.
Today, we're going to focus on facets. Specifically, how you can easily alter and interact with them to meet your needs.
Before We Begin
What will we cover here today? Glad you asked.
- Altering facet values
- Triggering the selection or deselection of facet values by interacting with other HTML elements
- Resetting facets using JavaScript
It seems like a lot, but it isn't. Each section of what we're going to cover leads us to be able to use other HTML elements in ways that alter a search experience.
Facets
There are several facets that you can use in a Coveo Search UI. Some are new, some have been deprecated. There are two groupings of facets. You have your Dynamic facets which include:
- DynamicFacet
- DynamicFacetRange
- DynamicHierarchialFacet
It's recommended that going forward you use these over the other type, the Regular facets. The reason being is they're much more flexible in the handling of the data provided to them. It depends on what you're trying to do. Regular facets include:
- Facet
- FacetRange
- FacetSlider
- TimespanRange
- CategoryFacet
- SimpleFilter
For a breakdown in greater detail, you can check out the Coveo Facet Types page.
Altering Facet Values
Pretty much any facet value can be displayed differently upon render. You don't need to do very much to make it happen.
Ideally, a facet's values would be updated to the desired values during the indexing process via a computed field calculation or through an Extension.
What if you have multiple search pages using the same source and each one needs to represent that data differently, then you likely will want to change that value in the UI.
Changing Values During Initialization
Let's say, your facets consisted of a list of country codes. i.e. US, JP, CA, etc. For the end-user, not very handy, so let's rename them to United States, Australia, Canada.
You'd want this to happen as part of the initialization process of the search page.
<div class="CoveoDynamicFacet" id="countryFacet" data-title="Country" data-field="@countrycode"></div>
With the facet in place, we can interact with change the facet values in two ways.
Using The data-value-caption
Attribute
By adding the relationship directly to the facet itself, shown below we can update the values. This is often handy when implementing using Hive.
<div class="CoveoDynamicFacet" id="countryFacet" data-title="Country" data-field="@countrycode" data-value-caption='{ "US": "United States", "JP": "Japan", "CA": "Canada" }' ></div>
Using Init / Option Actions
Coveo.init(document.getElementById("search"),{
countryFacet {
valueCaption: {
"US": "United States",
"JP": "Japan",
"CA": "Canada"
}
}
});
This short bit of code links the new facet values based upon the id
attribute of the facet. Super simple. Now we know we can interact with facets to alter the values, what about interacting with them to trigger the selection or deselection of said values.
Triggering Facet Selection Or Deselection
What if we have a client that wants to be able to use facets but doesn't want to see facets in their native look & feel. Maybe they want to use a couple of buttons.
It's important to note that even after changing the values for the captions above, we're still going to be interacting with them using their original value.
The original value is actually maintained in the HTML, within the hierarchy as shown below:
<span class="coveo-facet-value-caption" title="United States" data-original-value="US">United States</span>
Setting Up A Button
This should be fairly obvious but I'm setting up a simple button that, upon clicking, will trigger the associated facet value to be selected or deselected.
<button class="facet-selection" data-facet-id="countryFacet" data-facet-value="US">United States</button>
Setting Up The Event
When it comes to setting up the event it's important to know when to initialize the click event. You can't just enable it at any time.
When is the right time, you ask? You want to be sure to set up your click events when the afterInitialization
Coveo pipeline event has triggered. The facet needs to have been initialized before otherwise clicking a button can result in nothing happening.
More importantly though, right before the afterInitialization
event is triggered, the state from the hash portion of the URL is applied (i.e. facet values that should be selected are updated to show are selected).
As such this is also a good trigger point to apply button state, if you want certain buttons to show they've been selected to match the state of the facet.
Important Methods Of NoteThere are three facet methods one should know when it comes to changing a facet value.
toggleSelectValue
- Toggles the value on or off depending on stateselectValue
- Toggles facet value ondeselectValue
- Toggles facet value off
None of the methods above will cause a search query to be executed. You have to perform that action separately.
Let's take a look at an example.
Coveo.$$(document.getElementById("search")).on('afterInitialization', function() {
$(".facet-selection").click(function(el) {
// Get the facet for the button and then the DOM element
var facetId = $(el.target).data('facet-id');
var facetElement = document.getElementById(facetId);
// Get the facet value to look for
var toggleFacetValue = $(el.target).data('facet-value');
// Get the facet instance and toggle the value
var facetInstance = Coveo.get(facetElement);
facetInstance.toggleSelectValue(toggleFacetValue);
// After the value has been selected or deselected it's important to execute the
// query, otherwise it won't impact the search results.
Coveo.executeQuery(document.getElementById("search"));
});
});
I want to call out a couple things about the above code.
- The state of the button. If you want to change the state of the button depending on the state of the facet (e.g. added a class or removing a class depending on if the facet has been selected or deselected) then you need to do additional work.
- When to display the button. If the search page isn't yet visible, you won't want to display the button. If the facet isn't ready to be clicked, the button should not be ready either. Forgetting to do so may result in your button being selected and the facet not being selected.
One way to get around that is by not using toggleSelectValue
but rather a combination of selectValue
and deselectValue
as shown below in this modified version.
If toggleSelectValue
returned the state rather than just returning void
we could avoid this, but that's the way it is today.
I've expanded the stages so it's clearer as to what's happening where, as such you can likely do the same in far fewer steps.
Coveo.$$(document.getElementById("search")).on('afterInitialization', function() {
$(".facet-selection").click(function(e) {
// Determine button state
var isSelected = false;
if ($(e.target).hasClass('selected')) {
isSelected = true;
}
// Get the facet for the button and then the DOM element
var facetId = $(el.target).data('facet-id');
var facetElement = document.getElementById(facetId);
// Get the facet value to look for
var toggleFacetValue = $(el.target).data('facet-value');
// Get the facet instance and then depending on button state select or deselect
var facetInstance = Coveo.get(facetElement);
if (isSelected) {
facetInstance.deselectValue(toggleValue);
$(e.target).removeClass('selected');
} else {
facetInstance.selectValue(toggleValue);
$(e.target).addClass('selected');
}
// After the value has been selected or deselected it's important to execute the
// query, otherwise it won't impact the search results.
Coveo.executeQuery(document.getElementById("search"));
});
});
Resetting Facets Values
Just as important as knowing how to toggle whether a facet value is selected or not is the ability to reset a single facet or all facets.
If you have a lot of values, perhaps you want to create a simple yet obvious button for resetting everything back to the original state.
Reset All Facets On Button Click
Much the same way as toggling facet value selection, we can reset them all back to the default state. Let's say we have a button, shown below, that we want to reset all facets.
<button class="facet-reset" >Reset Everything</button>
How do we make it actually reset everything? Well, if we're using the Dynamic Facet for all facets, we could do something as simple as the following.
If we have other facet types, we can simply add other selections and 'reset' them as well.
Coveo.$$(document.getElementById("search")).on('afterInitialization', function() {
$(".facet-reset").click(function(e) {
// Set the facets back to default state
$('.CoveoDynamicFacet').coveo('reset');
// Execute the query to get the appropriate search results.
Coveo.executeQuery(document.getElementById("search"));
});
});
What Else Can You Do?
Honestly, you're only limited by your imagination. I just wanted to present a few simple ways of interacting with facets that will, at the very least, lay a groundwork for you to build upon.