Implementing multiple search states
You may want to change which sources you use depending on the query or the number of results. A typical pattern is to display a different source when the query is empty and switch once the user starts typing. Or display a no results message when the current query does not match any results.
This guide explains how to conditionally display specific sources when the query is empty or returns no results.
Prerequisites
This guide assumes that you have:
- existing markup containing an input element where you want to implement the autocomplete dropdown
- frontend development proficiency with HTML, CSS, and JavaScript
Getting started
First, begin with some boilerplate for the autocomplete implementation. Create a file called index.js
in your src
directory, and add the boilerplate below:
1
2
3
4
5
6
7
8
9
import { autocomplete } from '@algolia/autocomplete-js';
import '@algolia/autocomplete-theme-classic';
autocomplete({
container: '#autocomplete',
placeholder: 'Search for products',
openOnFocus: true,
});
This boilerplate assumes you want to insert the autocomplete into a DOM element with autocomplete
as an id
. You should change the container
to match your markup. Setting openOnFocus
to true
ensures that the dropdown appears as soon as a user focuses the input.
Implementing the empty query state
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import algoliasearch from 'algoliasearch/lite';
import { autocomplete, getAlgoliaResults } from '@algolia/autocomplete-js';
import '@algolia/autocomplete-theme-classic';
const searchClient = algoliasearch(
'latency',
'6be0576ff61c053d5f9a3225e2a90f76'
);
autocomplete({
container: '#autocomplete',
placeholder: 'Search for products',
openOnFocus: true,
getSources({ query }) {
if (!query) {
return [
{
sourceId: 'links',
getItems() {
return [
{ label: 'Shipping', url: '#shipping' },
{ label: 'Contact', url: '#contact' },
];
},
getItemUrl({ item }) {
return item.url;
},
templates: {
item({ item }) {
return item.label;
},
},
},
];
}
return [
{
sourceId: 'products',
getItems() {
return getAlgoliaResults({
searchClient,
queries: [
{
indexName: 'instant_search',
query,
},
],
});
},
getItemUrl({ item }) {
return item.url;
},
templates: {
item({ item }) {
return item.name;
},
},
},
];
},
});
The getSources
function provides access to the current query
, which you can use to return sources conditionally. You can use this pattern to display predefined items like these, recent searches, and suggested searches when the query is empty. When the user begins to type, you can show search results.
When there isn’t a query, this autocomplete instance returns useful links. When there is, it searches an Algolia index. For more information on using Algolia as a source, follow the Getting Started guide.
Implementing the no results search state
Now that you can display a custom source when the query is empty, you can display a message if the query returned no results.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ...
autocomplete({
container: '#autocomplete',
placeholder: 'Search for products',
openOnFocus: true,
getSources({ query }) {
// ...
},
renderNoResults({ render, html, state }, root) {
render(
html`
<div class="aa-PanelLayout aa-Panel--scrollable">
No results for "${state.query}".
</div>
`,
root
)
},
});
The renderNoResults
function provides a way to render a no results section when there are no hits.
Note that you have access to the full autocomplete state, not only the query. It lets you compute sources based on various parameters, such as the query, but also the autocomplete status, whether the autocomplete is open or not, the context, etc.
The following example uses the empty query and no results states: