Building a Multi-Category Autocomplete Menu
On this page
This guide uses an outdated version of Autocomplete. Algolia recommends using Autocomplete v1 instead.
Introduction
For multi-category autocomplete menus, a horizontal display often provides a better user experience than a vertical display. The increased size allows for more results to be displayed without the need for scrolling, which helps users more easily find information. We can also take advantage of the additional space to display images of the team logos.
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. Learn how to import the dataset into 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. Learn how to import the dataset into Algolia here
Configuring the indices
For both indices we specify 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 team name or location, 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
15
16
17
<!-- 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 v3 and autocomplete.js library -->
<script src="https://cdn.jsdelivr.net/npm/algoliasearch@3/dist/algoliasearchLite.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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
const client = algoliasearch('YourApplicationID', 'YourSearchOnlyAPIKey');
const players = client.initIndex('players');
const teams = client.initIndex('teams');
autocomplete(
'#aa-search-input',
{
debug: true,
templates: {
dropdownMenu:
'<div class="aa-dataset-player"></div>' +
'<div class="aa-dataset-team"></div>',
},
},
[
{
source: autocomplete.sources.hits(players, {hitsPerPage: 7}),
displayKey: 'name',
name: 'player',
templates: {
header: '<div class="aa-suggestions-category">Players</div>',
suggestion({_highlightResult}) {
return `<span>${_highlightResult.name.value}</span><span>${_highlightResult.team.value}</span>`;
},
empty: '<div class="aa-empty">No matching players</div>',
},
},
{
source: autocomplete.sources.hits(teams, {hitsPerPage: 5}),
displayKey: 'name',
name: 'team',
templates: {
header: '<div class="aa-suggestions-category">Teams</div>',
suggestion({logoUrl, _highlightResult}) {
return `
<img src="${logoUrl}">
<div>
<span>${_highlightResult.name.value}</span>
<span>${_highlightResult.location.value}</span>
</div>`;
},
empty: '<div class="aa-empty">No matching teams</div>',
},
},
]
);
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
.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);
min-width: 300px;
margin-top: 10px;
box-sizing: border-box;
}
.aa-suggestion {
padding: 6px 12px;
cursor: pointer;
}
.aa-suggestion + .aa-suggestion {
border-top: 1px solid rgba(228, 228, 228, 0.6);
}
.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;
}