Events
Events
This is for:
DeveloperYou can take advantage of the Coveo JavaScript Search Framework event system to interact with the framework using external, event-driven code. There are two broad categories of events you can attach handlers to: global events and component events.
Base assumptions
<link rel="stylesheet" href="./css/CoveoFullSearchNewDesign.css"/>
<script src="js/CoveoJsSearch.js"></script>
<script src="js/templates/templatesNew.js"></script>
The examples also assume that the id
attribute of the root element of your search interface is search
.
Attaching event handlers
The JavaScript Search Framework triggers regular DOM events. You can attach handlers to these events just as you would with “standard” events (for example, DOMContentLoaded
, click
, etc.).
Register your Framework event handlers on the root HTML element of your search interface. Some components trigger events on their own HTML element, but since these events bubble up, handlers registered on the root element can catch them as well.
Always register the Framework event handlers before the init
call of your search interface.
The following code excerpt registers a buildingQuery
event handler on the root HTML element of your search interface.
document.addEventListener("DOMContentLoaded", function() {
Coveo.SearchEndpoint.configureSampleEndpointV2();
root = document.querySelector("#search");
Coveo.$$(root).on("buildingQuery", function(e, args) {
// Some code to execute when the queryBuilder has just been instantiated...
});
Coveo.init(root);
});
Different ways to attach event handlers
There are three different ways to register Framework event handlers:
-
Using “pure” JavaScript (
document.addEventListener("[eventName]", function(e) { [ ... Code ... ] })
); -
Using the
Dom
helper class (Coveo.$$(root).on("[eventName]", function(e, args) { [ ... Code ... ] })
); -
Using the Coveo jQuery extension (
$(root).on("[eventName]", function(e, args) { [ ... Code ... ] })
).
Examples in this article use the on
method of the Dom
helper class to attach event handlers.
Embedding event handlers
When the JavaScript Search Framework triggers an event, listeners are notified in the order in which they were registered. Any Coveo component that needs to register its own event handlers does so when its constructor function is executed during the init
call of the search interface. Therefore, the event handlers that you register before the init
call will normally be registered before any Coveo component has a chance to register its own event handlers.
In some specific cases, you may need to ensure that an event handler is registered at a later moment. For example, you might want certain Coveo event handlers to be notified (and executed) before your own. You might also want to ensure that an event handler is only registered when the end user performs a given action (which triggers a specific event) in the search interface. In these situations, you should embed event handlers.
Attaching an embedded event handler:
The following code excerpt registers an embedded buildingQuery
event handler on the root HTML element of your search interface.
The buildingQuery
handler is embedded within an afterComponentsInitialization
handler. This implies that the buildingQuery
handler will only be registered when all Coveo components have registered their own event handlers.
document.addEventListener("DOMContentLoaded", function() {
Coveo.SearchEndpoint.configureSampleEndpointV2();
root = document.querySelector("#search");
// This handler will be registered after all components have registered their own handlers.
Coveo.$$(root).on("afterComponentsInitialization", function() {
Coveo.$$(root).on("buildingQuery", function(e, args) {
// Some code to execute when the `queryBuilder` has just been instantiated...
});
});
Coveo.init(root);
});
Global events
Global events have no direct association with any particular component. There are two types of global events in the JavaScript Search Framework: initialization events and query events.
Initialization events
Initialization events are triggered during the execution of the init
call of your search interface. Typically, you will attach handlers to these events to alter Coveo components before they’re rendered, or to interact with the state
object and the URL before the first query is launched. The initialization events are:
-
beforeInitialization
-
afterComponentsInitialization
-
restoreHistoryState
-
afterInitialization
Event flow
The following diagram displays the sequential flow of initialization events.
Handling initialization events
You must register all initialization event handlers before the init
call of your search interface, otherwise they will have no effect.
Handling events in lazy component loading mode
In lazy component loading mode, the init
function starts by asynchronously downloading the code of each required component. Downloading a component code chunks is a non-blocking process during which the execution stack processing can resume. Once the code chunk of a certain component has finished downloading, the init
function resumes and sequentially calls the constructor function of each future instance of this component. Then, the execution stack processing can resume, and so on until all components have been instantiated.
Therefore, in lazy component loading mode, it’s possible to successfully register initialization event handlers (except for beforeInitialization
handlers) after the init
call. Such handlers will be registered at some point after the beforeInitialization
event, and before the afterComponentsInitialization
event. There’s no easy way to tell precisely when the event handler will be registered, though. Because of this, you should avoid registering initialization event handlers after the init
call.
In conclusion, you should always handle events in lazy component loading mode precisely as you would in eager component loading mode.
Adding a filter to the query:
The following code excerpt shows how you could attach a handler to the afterInitialization
event to specify a hidden query (hq
) in the state
object.
In this example, an advanced expression is added to the query. It requires results to be English PDF files that contain the keyword Coveo
(see Query syntax).
document.addEventListener("DOMContentLoaded", function () {
Coveo.SearchEndpoint.configureSampleEndpointV2();
var root = document.querySelector("#search");
Coveo.$$(root).on("afterInitialization", function() {
Coveo.state(root, "hq", "(@filetype==pdf) (@language==English) (Coveo)");
});
Coveo.init(root);
});
Code samples
Modifying search interface options
The following code excerpt shows how you could use a beforeInitialization
event handler to modify a set of SearchInterface
options when a specific condition is met.
In this example, when the end user accesses the search page from a mobile device, the query result excerpt length is shortened and a special query pipeline is applied.
The userIsOnMobileDevice
function isn’t implemented in this code sample. To try it, you must provide your own implementation or ensure that the function returns an arbitrary Boolean value.
document.addEventListener("DOMContentLoaded", function() {
Coveo.SearchEndpoint.configureSampleEndpointV2();
/**
* Indicates whether the end user is on a mobile device.
*
* @returns {boolean} `true` if the end user is on a mobile device; `false` otherwise.
*/
var userIsOnMobileDevice = function() {
// ... Implementation ...
};
/**
* Sets the `excerptLength` and `pipeline` options of the `SearchInterface` to some arbitrary "mobile" values.
*
* @param rootElement The root element of the search interface.
*/
var setMobileOptionValues = function(rootElement) {
rootElement.setAttribute("data-excerpt-length", "100");
rootElement.setAttribute("pipeline", "mobileQueryPipeline");
};
root = document.querySelector("#search");
Coveo.$$(root).on("beforeInitialization", function() {
if (userIsOnMobileDevice()) {
setMobileOptionValues(root);
}
});
Coveo.init(root);
});
Selecting a tab and facet values
This example assumes that you include the following markup in your search page:
[ ... ]
<body id="search" data-design="new">
<div class="coveo-tab-section">
<a class="CoveoTab" data-id="All" data-caption="All Content"></a>
<a class="CoveoTab" data-id="Messages" data-caption="Messages Only" data-constant="true" data-expression="@objecttype==Message"></a>
</div>
[ ... ]
<div class="coveo-main-section">
<div class="coveo-facet-column">
<div class="CoveoFacet" data-title="Year" data-field="@year" data-tab="All,Messages"></div>
<div class="CoveoFacet" data-title="Month" data-field="@month" data-tab="All,Messages"></div>
</div>
[ ... ]
</body>
The following code excerpt shows how you could dynamically interact with the state
object and with component instances using an afterInitialization
event handler.
In this example, when the search page loads, the Messages tab is automatically selected. Then, in the Year facet, the current year is selected. Finally, in the Months facet, the current month and two preceding months are selected. These selections are made before the initial query (assuming the autoTriggerQuery
option of the SearchInterface
is set to true
), and don’t themselves trigger new queries; they simply serve as additional “filters” for the initial query.
document.addEventListener("DOMContentLoaded", function() {
Coveo.SearchEndpoint.configureSampleEndpointV2();
/**
* Selects the **Messages** tab by modifying the `state` object.
*
* @param rootElement The root element of the search interface.
*/
var selectMessagesTab = function(rootElement) {
if (Coveo.$$(document).find(".CoveoTab[data-id='Messages']") !== null) {
Coveo.state(rootElement, "t", "Messages");
}
};
/**
* Selects the current year value in the **Year** facet instance.
*/
var selectCurrentYearFacetValue = function() {
var yearFacetInstance = Coveo.get(Coveo.$$(document).find(".CoveoFacet[data-title='Year']"));
if (yearFacetInstance !== null) {
var thisYear = new Date().getFullYear().toString();
yearFacetInstance.selectValue(thisYear);
}
};
/**
* Selects values corresponding to this month and the two previous months in the **Months** facet instance.
*/
var selectRecentMonths = function() {
var monthFacetInstance = Coveo.get(Coveo.$$(document).find(".CoveoFacet[data-title='Month']"));
if (monthFacetInstance !== null) {
var thisMonth = new Date().getMonth();
for (var i=thisMonth-2; i <= thisMonth; i++) {
monthFacetInstance.selectValue("0" + i.toString());
}
}
};
var root = document.querySelector("#search");
Coveo.$$(root).on("afterInitialization", function() {
selectMessagesTab(root);
selectCurrentYearFacetValue();
selectRecentMonths();
});
Coveo.init(root);
});
Query events
Query events are triggered during the execution of a search request to the Coveo Search API. Typically, you will attach handlers to those events to:
-
Cancel the query;
-
Alter the appearance or behavior of a component before, during, or after the query;
-
Modify the outgoing query and the incoming result set;
-
Handle query errors and result sets that contain no results;
-
Alter the way the query results are rendered.
The query events are:
-
newQuery
-
buildingQuery
-
doneBuildingQuery
-
duringQuery
/duringFetchMoreQuery
-
queryError
-
preprocessResults
/preprocessMoreResults
-
noResults
-
querySuccess
/fetchMoreSuccess
-
deferredQuerySuccess
Query event arguments
All query event handlers receive a certain object as an argument. For example, all doneBuildingQuery
event handlers receive an IDoneBuildingQueryEventArgs
object as an argument. You can get or set the attributes of this object to interact with the query or with the results.
See the reference documentation of each individual query event for information about the object its handlers receive as an argument.
Event flow
The following diagram displays the sequential flow of query events.
Additional query events
This diagram doesn’t include the duringFetchMoreQuery
, preprocessMoreResults
, and fetchMoreSuccess
events.
These events are equivalent to the duringQuery
, preprocessResults
, and querySuccess
events respectively, except they’re triggered when certain components need to perform their own queries to fetch additional results (for example, for infinite scroll, folding, etc.).
Handling query events
In theory, you can register query event handlers either before or after the init
call of your search interface.
Registering a query event handler before the init
call implies that the handler will be registered before any component constructor functions are called. Registering the same handler after the init
call means that it will be registered after all of the component constructors have been executed. This is equivalent to embedding the handler inside an afterInitialization
handler.
You should always register query event handlers before the init
call. You can embed event handlers to enforce a sequential registration flow, when necessary.
Code samples
Modifying the appearance of an element
This example assumes that you include the following markup in your search page:
[ ... ]
<style>
.currently-hidden {
display : none;
}
</style>
<body id="search" class="CoveoSearchInterface" data-design="new">
<div id="loading-status">
<div id="query-done">Done!</div>
<div id="query-error" class="currently-hidden">Error.</div>
<div id="query-loading" class="currently-hidden">Loading...</div>
</div>
[ ... ]
</body>
Depending on the current state of the query, the following code excerpts show how you could use newQuery
, queryError
, and querySuccess
event handlers to modify the appearance of an HTML element.
In this example, when a new query is triggered, the element displays the Loading. text. When the query successfully returns (whether it actually contains results), it displays the Done! text. If the query fails (because of a search endpoint configuration error, for example), it displays the Error. text.
document.addEventListener("DOMContentLoaded", function() {
Coveo.SearchEndpoint.configureSampleEndpointV2();
var hiddenClass = "currently-hidden";
/**
* Indicates whether the target HTML element is currently hidden by verifying whether it has the corresponding
* CSS class.
*
* @param element The target HTML element.
*
* @returns {boolean} `true` if the HTML element is currently hidden; `false` otherwise.
*/
var isCurrentlyHidden = function(element) {
return element.classList.contains(hiddenClass);
};
/**
* Toggles the visibility of the target HTML element by adding or removing the corresponding CSS class.
*
* @param element The target HTML element.
*/
var toggleElementVisibility = function(element) {
if (isCurrentlyHidden(element)) {
element.classList.remove(hiddenClass);
}
else {
element.classList.add(hiddenClass);
}
};
root = document.querySelector("#search");
Coveo.$$(root).on("newQuery", function(e, args) {
// If the previous query returned an error, hide the `query-error` element when launching the new query.
var error = document.querySelector("#query-error");
if (!isCurrentlyHidden(error)) {
toggleElementVisibility(error);
}
toggleElementVisibility(document.querySelector("#query-done"));
toggleElementVisibility(document.querySelector("#query-loading"));
});
Coveo.$$(root).on("queryError", function(e, args) {
toggleElementVisibility(document.querySelector("#query-error"));
toggleElementVisibility(document.querySelector("#query-loading"));
});
Coveo.$$(root).on("querySuccess", function(e, args) {
toggleElementVisibility(document.querySelector("#query-loading"));
toggleElementVisibility(document.querySelector("#query-done"));
});
Coveo.init(root);
});
If you run this code sample, you should see something like this at the top of your search page:
Toggling the query cache
This example assumes that you include the following markup in your search page:
[ ... ]
<body id="search" class="CoveoSearchInterface" data-design="new">
[ ... ]
<div class="coveo-search-section">
[ ... ]
<div class="CoveoSearchbox"></div>
<input id="disable-query-cache-checkbox" type="checkbox"/>
<label for="disable-query-cache-checkbox">Disable Query Cache</label>
<div>
</body>
By default, the Search API tries to return cached query results when a search request is triggered. This means that sending the same search request again and again over a brief period of time doesn’t necessarily trigger many complete queries to the Coveo index, since the results are already available (and likely still up-to-date) in the cache.
The following code excerpt shows how you could use a buildingQuery
event handler to allow the end user to activate or deactivate query cache in your search page by interacting with a checkbox input.
In this example, the checkbox state is saved in local storage so that when the end user reloads the search page, the previously selected state is automatically reapplied.
Since it’s embedded within an afterInitialization
handler, this buildingQuery
handler will only be registered after each Coveo component has registered its own event handlers, and the hash part of the URL has been applied to the state
object. Consequently, this handler will be notified last when the buildingQuery
event is triggered. This ensures that no internal Coveo event handler can “override” this handler.
document.addEventListener("DOMContentLoaded", function () {
Coveo.SearchEndpoint.configureSampleEndpointV2();
/**
* Gets the `enableQueryCache.isEnabled` value if it exists in local storage.
*
* @returns {boolean|*} The `isEnabled` value if available; `null` otherwise.
*/
var getEnableQueryCacheValue = function() {
return JSON.parse(localStorage.getItem("enableQueryCache")).isEnabled;
};
/**
* Attaches a handler to the **Disable Query Cache** checkbox so that changing its state also changes the
* `enableQueryCache.isEnabled` value in local storage. Automatically selects the checkbox if the
* `enableQueryCache.isEnabled` value is currently set to `false`.
*/
var configureQueryCacheCheckbox = function() {
var disableCacheCheckbox = document.querySelector("#disable-query-cache-checkbox");
disableCacheCheckbox.addEventListener("change", function () {
localStorage.setItem("enableQueryCache", JSON.stringify({"isEnabled": !this.checked}));
});
disableCacheCheckbox.checked = getEnableQueryCacheValue() === false;
};
var root = document.querySelector("#search");
Coveo.$$(root).on("afterInitialization", function() {
configureQueryCacheCheckbox();
// When instantiating the `queryBuilder`, set the maximum age of cached results according to the
// `enableQueryCache.isEnabled` value in local storage. Use the default `maximumAge` parameter value (which is
// equivalent to 30 minutes) if `enableQueryCache.isEnabled` is either `true` or undefined.
Coveo.$$(root).on("buildingQuery", function(e, args) {
args.queryBuilder.maximumAge = getEnableQueryCacheValue() === false ? 0 : null;
});
});
Coveo.init(root);
});
If you run this code sample, you should see a Disable Query Cache checkbox input in your search page:
If you leave the box unchecked and launch a query whose results are already available in cache (the initial query, for example), you should see something like this when you inspect the query response:
If you check the box and try sending the same query again, the response should now contain something similar to this:
Replacing special characters in the query
The query syntax allows the end user to enter complex query expressions in the query box. The enableQuerySyntax
option of your Searchbox
component lets you enable or disable the use of query syntax in your search page.
In certain cases, you might need to disable some of the query syntax features (for example, setting the enableQuerySyntax
option to true
, but ignoring certain special characters which could otherwise be interpreted as Coveo query syntax, such as $
). While the Coveo Search API offers no “clean” way to do this in the query pipeline, it’s possible (although not ideal) to modify the queryBuilder
to artificially achieve this kind of query syntax granularity.
Query syntax and the JavaScript Search Framework v2.x
In v2.x of the Framework, enableQuerySyntax
defaults to false
, but it can be overridden by end-user preferences.
The following code excerpt shows how you could use a doneBuildingQuery
event handler to remove certain special characters from the basic query expression (q) before sending it to the Coveo Search API.
In this example, the $
character is replaced with the empty string.
document.addEventListener("DOMContentLoaded", function() {
Coveo.SearchEndpoint.configureSampleEndpointV2();
root = document.querySelector("#search");
Coveo.$$(root).on("doneBuildingQuery", function(e, args) {
args.queryBuilder.expression.parts[0] = args.queryBuilder.expression.parts[0].replace(/\$/g, "");
});
Coveo.init(root);
});
Querying commerce catalog content
The following code excerpt shows you how to query your commerce catalog content.
document.addEventListener("DOMContentLoaded", () => {
// ...
const root = document.getElementById("search");
Coveo.$$(root).on("buildingQuery", (e, args) => {
args.queryBuilder.commerce = { catalogId: "<MY_CATALOG_NAME>" };
});
// ...
Coveo.init(root);
});
Where you would replace <MY_CATALOG_NAME>
with the name of your catalog.
Modifying the query results
The following code excerpt shows how you could use a preprocessResults
event handler to modify the results before the ResultList
component renders them.
In this example, the handler converts the title of all results whose objecttype
field value is User
to uppercase.
document.addEventListener("DOMContentLoaded", function() {
Coveo.SearchEndpoint.configureSampleEndpointV2();
root = document.querySelector("#search");
Coveo.$$(root).on("preprocessResults", function(e, args) {
args.results.results.forEach(function(result) {
if (result.raw && result.raw.objecttype === "User") {
result.title = result.title.toUpperCase();
}
});
});
Coveo.init(root);
});
Client-side manipulations of query results such as this one are “quick and dirty” ways to fix problems and inconsistencies which actually reside within the index itself. If you frequently find yourself resorting to this kind of result manipulation in your search page, you should probably consider making adjustments in the index (for example, adding or modifying pre- and post-indexing pipeline extensions, field mapping rules, etc.).
Displaying query result information
The following code excerpt shows how you could use a querySuccess
event handler to interact with the current page of query results.
In this example, when the query successfully returns, the handler renders a list containing the number of occurrences of each source type present on the current page of results.
document.addEventListener("DOMContentLoaded", function() {
Coveo.SearchEndpoint.configureSampleEndpointV2();
root = document.querySelector("#search");
Coveo.$$(root).on("querySuccess", function(e, args) {
/**
* Removes the `source-type-summary` structure from the search page.
*/
var cleanUp = function() {
var sourceTypeSummary = document.querySelector("#source-type-summary");
if (sourceTypeSummary !== null) {
sourceTypeSummary.parentNode.removeChild(sourceTypeSummary);
}
};
/**
* Counts the number of occurrences of each source type on the current page of results.
*
* @returns {{}} A key-value set where each key is the name of a source type and each value is its
* corresponding number of occurrences on the current page of results.
*/
var getSourceOccurrences = function() {
var sources = {};
for (var i = 0; i < args.results.results.length; i++) {
var currentResult = args.results.results[i];
var currentSource = currentResult.raw.source;
if (sources[currentSource]) {
sources[currentSource] += 1;
}
else {
sources[currentSource] = 1;
}
}
return sources;
};
/**
* Creates the `source-type-summary` HTML structure, which contains an unordered list of each source type
* present on the current page of results and its corresponding number of occurrences. Prepends this node to
* the `coveo-results-column` element if it exists, or to the root element of the search interface otherwise.
*/
var createSourceTypeSummary = function() {
var sources = getSourceOccurrences();
if (sources instanceof Object) {
var sourceTypeSummary = document.createElement("div");
sourceTypeSummary.setAttribute("id", "source-type-summary");
var sourceTypeSummaryContent = document.createTextNode("Source type summary for this page: ");
sourceTypeSummary.appendChild(sourceTypeSummaryContent);
var sourceTypeList = document.createElement("ul");
for (var key in sources) {
var sourceTypeListItem = document.createElement("li");
var sourceTypeListItemContent = document.createTextNode(" " + key + ": " + sources[key]);
sourceTypeListItem.appendChild(sourceTypeListItemContent);
sourceTypeList.appendChild(sourceTypeListItem);
}
sourceTypeSummary.appendChild(sourceTypeList);
var resultsColumn = document.querySelector(".coveo-results-column");
if (resultsColumn) {
resultsColumn.insertBefore(sourceTypeSummary, resultsColumn.firstChild);
}
else {
root.insertBefore(sourceTypeSummary, root.firstChild);
}
}
};
// Remove the `source-type-summary` element if it already exists in the page to avoid carrying the existing
// structure over when displaying another page of results.
cleanUp();
createSourceTypeSummary();
});
Coveo.init(root);
});
If you run this code sample, you should see the following at the top of your result list:
Component events
Component events are usually triggered by specific components. The following JavaScript Search Framework components have their own sets of events:
-
AdvancedSearch
(seeAdvancedSearchEvents
) -
Analytics
(seeAnalyticsEvents
) -
Breadcrumb
(seeBreadcrumbEvents
) -
CardOverlay
(seeCardOverlayEvents
) -
FacetSlider
-
Omnibox
-
PreferencesPanel
-
QuerySummary
(seeQuerySummaryEvents
) -
Quickview
-
ResultLayout
-
ResultList
-
SearchAlerts
-
Settings
This article only discusses the most commonly used ResultList
events, and the changeAnalyticsCustomData
Analytics
event.
See the reference documentation of the aforementioned components for more information on their respective events.
Analytics events
changeAnalyticsCustomData
The changeAnalyticsCustomData
event is triggered right before sending the custom data and metadata of an analytics event to the Coveo Analytics REST service. All changeAnalyticsCustomData
event handlers receive ChangeAnalyticsCustomDataEventArgs
as an argument, which extends the IChangeableAnalyticsDataObject
interface. You can attach handlers to this event to read and modify the information that’s about to be sent to the Analytics REST service.
Argument object
Name
|
Description
|
---|---|
type |
The type of event that's being logged. Can be SearchEvent , ClickEvent , or CustomEvent . |
metaObject
|
The custom event metadata. All key-value pairs included in this object will be sent as custom metadata to the Coveo Analytics service, and can then be used to create custom dimensions in analytics reports. |
language |
The language of the search interface. By default, this value is populated by the localization file used by the search interface. |
originLevel1 |
The high-level origin of the analytics event. Typically, this is the name of the current search hub, or a name which can uniquely identify the search page. Default value is |
originLevel2 |
The mid-level origin of the analytics event. By default, this value is populated by the currently selected tab. |
originLevel3
|
The low level origin of the analytics event. Typically, this is the HTTP identifier of the page from which the event originates. By default, this property is left empty. |
( |
When the analytics event category is ClickEvents, the event object contains an additional attribute. You can take advantage of the resultData object to push more analytics data from the results that have been clicked. You want to include the value of the
|
ResultList
events
The ResultList
component can trigger several events. Two of these events are especially useful: newResultDisplayed
(singular: “result”) and newResultsDisplayed
(plural: “results”). You can attach handlers to these events to alter the appearance of rendered query results.
ResultList events versus result templates
Usually, you can rely on the result template evaluation mechanism rather than attaching your own handlers to the newResultDisplayed
or newResultsDisplayed
events.
Event flow
The following diagram displays the part of the sequential query event flow where the ResultList
component triggers the newResultDisplayed
and newResultsDisplayed
events.
In summary, the ResultList
component triggers the newResultDisplayed
event each time it renders a result. However, it triggers the newResultsDisplayed
event only once, when all results have been rendered.
A word of caution about this diagram
Other querySuccess event handlers may have been registered before (and after) the ResultList querySuccess event handler.
This means that in the previous diagram, the querySuccess
event could trigger other processes, which would either be executed before or after the ResultList
rendering process, depending on when their corresponding event listeners were registered.
Handling the newResultDisplayed
event
All newResultDisplayed
event handlers receive an IDisplayedNewResultEventArgs
as an argument. This object includes the current IQueryResult
(the result
object) as well as the current HTMLElement
(the item
object). Typically, you will want to get values from the result
object and set values in the item
object to alter the rendering of the results.
As usual, you should always register your newResultDisplayed
event handlers before the init
call of your search interface.
newResultDisplayed versus newResultsDisplayed
You can accomplish the exact same thing using either a newResultDisplayed
or a newResultsDisplayed
event handler. However the newResultDisplayed
event is often slightly easier and cleaner, since it doesn’t require you to write a loop when you need to iterate through each element in the result list.
Code sample
Modifying the rendering of each result:
The following code excerpt shows how you could use a newResultDisplayed
event handler to modify the appearance of each result in the result list.
In this example, the handler modifies the HTML of each rendered ResultLink
component so that it displays the name of the source before the result title.
document.addEventListener("DOMContentLoaded", function() {
Coveo.SearchEndpoint.configureSampleEndpointV2();
root = document.querySelector("#search");
Coveo.$$(root).on("newResultDisplayed", function(e, args) {
// Add the source type at the beginning of the result link text.
var formattedTitle = args.result.Title = args.result.raw.source + " - " + args.result.Title;
args.item.querySelectorAll("div.coveo-result-cell > a.CoveoResultLink").forEach(function(element) {
element.innerHTML = formattedTitle
});
});
Coveo.init(root);
});
Handling the newResultsDisplayed
event
All newResultsDisplayed
event handlers receive a recursive representation (tree) of the source (the srcElement
object) and target (the target
object) HTML elements of the ResultList
. Typically, you will want to get values from the srcElement
object and set values in the target
object to alter the rendering of the results.
As usual, you should always register your newResultsDisplayed
event handlers before the init
call of your search interface.
Code sample
Modifying the rendering of each result:
The following code excerpt shows how you could use a newResultsDisplayed
event handler to modify the appearance of each result in the result list.
In this example, the handler modifies the HTML of each rendered ResultLink
component so that it displays the name of the source before the result title.
document.addEventListener("DOMContentLoaded", function() {
Coveo.SearchEndpoint.configureSampleEndpointV2();
root = document.querySelector("#search");
Coveo.$$(root).on("newResultsDisplayed", function(e, args) {
// Add the source type at the beginning of the result link text.
for (var i = 0; i < e.target.lastChild.children.length; i++) {
var currentResult = e.target.lastChild.children[i];
var formattedTitle = currentResult.CoveoResult.raw.source + " - " + currentResult.CoveoResult.Title;
currentResult.children[0].querySelectorAll("div.coveo-result-cell > a.CoveoResultLink").forEach(function(element) {
element.innerHTML = formattedTitle;
});
}
});
Coveo.init(root);
});