How to Display Results from Multiple Indices with Autocomplete.js
On this page
Introduction
Autocomplete menus offer many possibilities for engaging users. You can find an example of a complex multi-category dropdown menu live on birchbox.fr.
Dataset
We are going to display the results from 2 datasets: player but also team information.
Different types of data should be created as different indices. This allows you to create separate ranking strategies more tailored to each type of data.
Players
1
2
3
4
5
6
7
8
9
10
11
12
13
[
{
"name": "Sam Young",
"team": "Grizzlies",
"points": 595
},
{
"name": "Thaddeus Young",
"team": "76ers",
"points": 926
}
[...]
]
You can download the dataset here. Have look at how to import it with Algolia here
Teams
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
{
"name": "Hawks",
"location": "Atlanta",
"logoUrl": "Hawks_Atlanta.gif",
"score": 595.5714285714286
},
{
"name": "Celtics",
"location": "Boston",
"logoUrl": "Celtics_Boston.gif",
"score": 428.2105263157895
}
]
You can download the dataset here. Have look at how to import it with Algolia here
Configuring the indices
For both indices we specify both searchable attributes and custom ranking criterion.
Players
1
2
3
4
5
6
7
8
9
$client->initIndex("players")->setSettings(array(
"searchableAttributes" => array(
"name",
"team"
),
"customRanking" => array(
"desc(points)"
)
));
For players, it makes sense to allow users to search by player name or team name, as both of these attributes will be displayed. To rank the players, we have added a “points” attribute that reflects the amount of points each player has scored (the higher the scores, the better).
Teams
1
2
3
4
5
6
7
8
9
$client->initIndex("teams")->setSettings(array(
"searchableAttributes" => array(
"name",
"location"
),
"customRanking" => array(
"asc(score)"
)
));
For teams, it makes sense to allow users to search by team name or location, as both of these attributes will be displayed. To rank the teams, we have added a “score” attribute that reflects the average of the points of a team’s respective players.
HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- Include stylesheet -->
<link href="app.css" rel=stylesheet />
<!-- HTML Markup -->
<div class="aa-input-container" id="aa-input-container">
<input type="search" id="aa-search-input" class="aa-input-search" placeholder="Search for players or teams..." name="search" autocomplete="off" />
<svg class="aa-input-icon" viewBox="654 -372 1664 1664">
<path d="M1806,332c0-123.3-43.8-228.8-131.5-316.5C1586.8-72.2,1481.3-116,1358-116s-228.8,43.8-316.5,131.5 C953.8,103.2,910,208.7,910,332s43.8,228.8,131.5,316.5C1129.2,736.2,1234.7,780,1358,780s228.8-43.8,316.5-131.5 C1762.2,560.8,1806,455.3,1806,332z M2318,1164c0,34.7-12.7,64.7-38,90s-55.3,38-90,38c-36,0-66-12.7-90-38l-343-342 c-119.3,82.7-252.3,124-399,124c-95.3,0-186.5-18.5-273.5-55.5s-162-87-225-150s-113-138-150-225S654,427.3,654,332 s18.5-186.5,55.5-273.5s87-162,150-225s138-113,225-150S1262.7-372,1358-372s186.5,18.5,273.5,55.5s162,87,225,150s113,138,150,225 S2062,236.7,2062,332c0,146.7-41.3,279.7-124,399l343,343C2305.7,1098.7,2318,1128.7,2318,1164z" />
</svg>
</div>
<!-- Include AlgoliaSearch JS Client and autocomplete.js library -->
<script src="https://cdn.jsdelivr.net/algoliasearch/3/algoliasearch.min.js"></script>
<script src="https://cdn.jsdelivr.net/autocomplete.js/0/autocomplete.min.js"></script>
<script src="app.js"></script>
jsDelivr is a third-party CDN. We are not able to provide support regarding third party services.
JS (app.js)
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
const client = algoliasearch("4J2JTO3FLK", "2f4cff0198aca3ee49fffa6df138e260");
const players = client.initIndex('players');
const teams = client.initIndex('teams');
autocomplete('#aa-search-input', {}, [
{
source: autocomplete.sources.hits(players, { hitsPerPage: 3 }),
displayKey: 'name',
templates: {
header: '<div class="aa-suggestions-category">Players</div>',
suggestion({_highlightResult}) {
return `<span>${_highlightResult.name.value}</span><span>${_highlightResult.team.value}</span>`;
}
}
},
{
source: autocomplete.sources.hits(teams, { hitsPerPage: 3 }),
displayKey: 'name',
templates: {
header: '<div class="aa-suggestions-category">Teams</div>',
suggestion({_highlightResult}) {
return `<span>${_highlightResult.name.value}</span><span>${_highlightResult.location.value}</span>`;
}
}
}
]);
CSS Styles (app.css)
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
.aa-input-container {
display: inline-block;
position: relative;
}
.aa-input-search {
width: 300px;
padding: 12px 28px 12px 12px;
border: 1px solid #e4e4e4;
box-sizing: border-box;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.aa-input-search::-webkit-search-decoration, .aa-input-search::-webkit-search-cancel-button,
.aa-input-search::-webkit-search-results-button, .aa-input-search::-webkit-search-results-decoration {
display: none;
}
.aa-input-icon {
height: 16px;
width: 16px;
position: absolute;
top: 50%;
right: 16px;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
fill: #e4e4e4;
pointer-events: none;
}
.aa-dropdown-menu {
background-color: #fff;
border: 1px solid rgba(228, 228, 228, 0.6);
width: 300px;
margin-top: 10px;
box-sizing: border-box;
}
.aa-suggestion {
padding: 6px 12px;
cursor: pointer;
}
.aa-suggestions-category {
border-bottom: 1px solid rgba(228, 228, 228, 0.6);
border-top: 1px solid rgba(228, 228, 228, 0.6);
padding: 6px 12px;
}
.aa-dropdown-menu > div {
display: inline-block;
width: 100%;
vertical-align: top;
}
.aa-empty {
padding: 6px 12px;
}
The “CSS - Basic” tab contains out-of-the-box structural styles. For the fully-themed version (as shown in the live demo), copy the “CSS - Themed” tab.