JavaScript Search Framework Components

Components are the building blocks of a JavaScript Search Framework interface. They render widgets such as a Searchbox (in which the end user enters queries), a Facet on a particular field (allowing users to easily filter results), etc. Some components are containers such as the ResultList (where returned search results are displayed) or appear only when triggered, such as FieldSuggestions (appearing below the Searchbox as the user types a query). You can build a search interface by arranging the components you want as you see fit.

Components are automatically attached to HTML elements that have a specific CSS class. This is automatically performed during the initialization of the search interface.

Most components can be configured through options to adjust their behavior, and many also expose methods and events that can be used by external code to further customize their behavior.

  • The SearchButton component can be used with any clickable element (such as an <a> tag or an <input type="button">), and causes a new query to be executed every time the user clicks the element.

  • The Querybox component is used with a textbox element (such as a <div type="text"/>). When a query is executed, it automatically adds the search keywords entered in the textbox to the query, which is then sent to the Search API.

Available Components

The Coveo JavaScript Search Framework became an open source package in July 2016 (see July 2016 Release (v1.667.24)) and the reference documentation site is now generated from documentation embedded in the source code.

You can find the list of all available components and their associated documentation on GitHub (see Coveo JavaScript Search Framework - Reference Documentation).

The component documentation is also searchable through connect.coveo.com.

Creating Component Instances

Automatic Initialization

Most of the time, components are automatically created during the initialization of the search interface, that is when the init function is invoked. When this happens, all the HTML elements under the specified root element are scanned, and the proper components are initialized for all elements having a CSS class that is associated with a component.

If your JavaScript Search Framework version was released after July 2016, refer to the documentation of the Initialization class.

The CSS class name is the component name prefixed with Coveo.

If an <a> element has the class="CoveoSearchButton" attribute when the init function is executed, a SearchButton component is automatically created and attached to that element.

Manual Initialization

Although it is rarely necessary to do so, you can manually create components and bind them to HTML elements.

To do this, you can call the constructor of the component you want to instantiate, passing the HTML element(s) on which you want to bind this component as an argument. You can also pass configuration options as an argument when calling a component constructor.

Alternatively, you can use the jQuery Extension, calling the coveo extension on a selector matching the element(s) for which to create components, and passing the name of the desired component as an argument. You can also pass options as a second argument to this call.

Consider the following markup:

<div id="search" class="CoveoSearchInterface">
  <div class="coveo-tab-section">
    <a id="myElement"></a>
  </div>
</div>

Executing the following script instantiates a Tab component with Don't Panic as a caption, 42 as an id and @author=="Douglas Adams" as an expression on the element that matches to the #myElement CSS selector:

const myElement = document.getElementById("myElement");
 
const options = {
  caption: "Don't Panic",
  id: "42",
  expression: "@author==\"Douglas Adams\""
};
 
new Coveo.Tab(myElement, options);

You can achieve the same result using the jQuery coveo extension:

$("#myElement").coveo("Tab", options);
  • All component constructors allow you to specify configuration options (assuming, of course, that some configuration options are available for that component). You can also specify component bindings. This is optional, however, as the Coveo JavaScript Search Framework can automatically resolve the bindings on its own. Some component constructors also allow you to specify values for additional parameters. You can find detailed information about each component constructor in the reference documentation (see Coveo JavaScript Search Framework - Reference Documentation).

  • When initializing a component manually in lazy mode, you must use the load top-level function to ensure that the component code is available (see Interacting with Lazy Components):

    // ...
    Coveo.load("Tab").then((Tab) => {
      new Coveo.Tab(myElement, options);
    });
    

Configuring Components

Most components support being passed a number of options when they are initialized. For convenience, those options can be specified in different ways. Refer to the documentation for each component to get the list of options supported by each one.

Using Attributes

The simplest way to specify options for a component is to use custom attributes directly on the HTML element bound to the component.

The attribute name is built by splitting words of the camel case option name with dashes and adding the data- prefix.

On the HTML element of a Searchbox component, you can set the enableSearchAsYouType option to true using the data-enable-search-as-you-type attribute:

<input type="text" class="CoveoSearchbox" data-enable-search-as-you-type="true"/>

Passing Component Options in the init Call

Another way to configure components is to pass options to the init top-level function call.

Consider the following markup:

<body id="search" class="CoveoSearchInterface">
  <div class="coveo-search-section">
    <div class="CoveoSearchbox"></div>
  </div>
  <div class="coveo-main-section">
    <div class="coveo-result-column">
      <div class="coveo-result-layout-section">
        <span class="CoveoResultLayoutSelector"></span>
      </div>
      <div class="CoveoResultList" data-layout="list" data-enable-infinite-scroll="false"></div>
      <div id="myCardResultList" class="CoveoResultList" data-layout="card"></div>
    </div>
  </div>
</body>

With the following script, the init function sets the enableSearchAsYouType option to true on the Searchbox it finds under the root element, and sets the enableInfiniteScroll and autoSelectFieldsToInclude options to true on both ResultList components it finds.

If you specify certain component configuration options both in the markup and in the init call, the markup options override the corresponding options in the init call.

Therefore, in the following example, the resulting enableInfiniteScroll option is false for the ResultList whose layout is list, whereas it is true for the ResultList whose layout is card.

document.addEventListener("DOMContentLoaded", () => {
  Coveo.SearchEndpoint.configureSampleEndpointV2();
 
  const mainSearchInterface = document.getElementById("search");
 
  Coveo.init(mainSearchInterface, {
    Searchbox: {
      enableSearchAsYouType: true
    },
    ResultList: {
      enableInfiniteScroll: true,
      autoSelectFieldsToInclude: true
    }
  });
});

You can also specify options for a specific component in the init call by referring to its HTML id attribute.

If you specify options for both a component type and a specific id that refers to a component of that type, the Coveo JavaScript Search Framework merges these options, prioritizing the options you specify by id.

Once again, remember that configuration options you specify in the markup will override corresponding options set in the init call.

Thus, in the following code sample, the resulting waitAnimation of the ResultList whose id is myCardResultList is spinner, its enableInfiniteScroll and autoSelectFieldsToInclude are both true, and its infiniteScrollPageSize is 15.

document.addEventListener("DOMContentLoaded", function() {
  Coveo.SearchEndpoint.configureSampleEndpointV2();
  const root = document.getElementById("search");
  Coveo.init(root, {
    ResultList: {
      enableInfiniteScroll: true,
      waitAnimation: "fade",
      autoSelectFieldsToInclude: true
    },
    myCardResultList: {
      waitAnimation: "spinner",
      infiniteScrollPageSize: 15
    }
  });
});

Passing Component Options Before the init Call

When you are working on a hosted search page, or on a Coveo for Salesforce search page, you cannot directly access the init call of your search interface. You can, however, pass component configuration options before the init call by using the options top-level function.

Consider the following markup:

<div id="search" class="CoveoSearchInterface">
  <div id="fileTypeFilter" class="CoveoFacet" data-field="@filetype" data-title="File Type"></div>
</div>

The following script would make the fileTypeFilter Facet display normalized facet value captions:

const root = document.getElementById("search");
const fileTypeFilterValueCaptions = {
  // ...
  "html": "Web pages",
  "txt": "Text files",
  "zip": "ZIP files"
};
Coveo.options(root, {
  fileTypeFilter: {
    valueCaption: fileTypeFilterValueCaptions
  }
});

Initializing Components External to your CoveoSearchInterface

Sometimes, it can be useful to have a component that is outside your main Search Interface. A common case is when you want to have a search box in your page header and bind it to a Search Interface that is in another section of your page.

Suppose you have the following two components:

<div class="CoveoSearchbox" id="myStandaloneSearchbox"></div>
<div class="CoveoSearchInterface" id="myMainSearchInterface"></div>

You could initialize your external search box as follows:

document.addEventListener("DOMContentLoaded", () => {
  Coveo.SearchEndpoint.configureSampleEndpointV2();
 
  const standaloneSearchbox = document.getElementById("myStandaloneSearchbox");
  const mainSearchInterface = document.getElementById("myMainSearchInterface");
 
  Coveo.init(mainSearchInterface, {
    externalComponents: [
      standaloneSearchbox
    ]
  });
});

Your search box would then be linked to your search interface. Note that the externalComponents option accepts an array of jQuery objects. And each component in this array will be initialized after components that are direct children of the search interface.

Using Child Elements

Sometimes, a child HTML element with a special CSS class can be used to configure an option. This is typically used for result templates.

The ResultList Component supports using a template annotated with the result-template class.

<div class="CoveoResultList">
  <script id="myTemplate" type="text/html" class="result-template">
    <!-- ... -->
  </script>
</div>

Changing Options After Initialization

The Coveo JavaScript Search Framework currently does not support changing options after component initialization.

Calling Methods on Components

Some components expose methods that you can use to perform certain actions. You can use the get top-level function to retrieve the component instance whose method you want to execute.

The ResultList component has a displayMoreResults method that causes it to fetch and display additional results after the ones that are already displayed.

You can call this method as such:

const resultListElement = document.getElementById('#myResultList');
let resultListInstance = Coveo.get(resultListElement);
resultListInstance.displayMoreResults(10);

You can also achieve similar results using the jQuery extension:

$('#myResultList').coveo('displayMoreResults', 10);

The jQuery selector in the expression must match an element bound to a component exposing the requested method. The first argument to the coveo jQuery extension is the name of the method to invoke, followed by its arguments. The call to the jQuery extension returns the method return value if there is one, and the selector itself otherwise (this is to allow method chaining as is usual with jQuery).

If several elements are matching the selector, the method will be invoked on all of those, and the return value will be that of the first invocation.

What’s Next?

Articles in this section:

Recommended Articles