menuSelect
menuSelect({ container: string|HTMLElement, attribute: string, // Optional parameters limit: number, sortBy: string[]|function, templates: object, cssClasses: object, transformItems: function, });
1
import { menuSelect } from 'instantsearch.js/es/widgets';
About this widget # A
The menuSelect
widget allows a user to select a single value to refine inside a select
element.
Requirements#
The attribute provided to the widget must be in attributes for faceting, either on the dashboard) or using attributesForFaceting
with the API.
Examples # A
1
2
3
4
menuSelect({
container: '#menu-select',
attribute: 'brand',
});
Options # A
Parameter | Description | ||
---|---|---|---|
container
# |
type: string|HTMLElement
Required
The CSS Selector or |
||
Copy
|
|||
attribute
# |
type: string
Required
The name of the attribute in the record. |
||
Copy
|
|||
limit
# |
type: number
default: 10
Optional
The maximum number of values to display. |
||
Copy
|
|||
sortBy
# |
type: string[]|function
default: Uses facetOrdering if set, ["name:asc"]
Optional
How to sort refinements. Must be one or more of the following strings:
It’s also possible to give a function, which receives items two by two, like JavaScript’s If |
||
Copy
|
|||
templates
# |
type: object
Optional
The templates to use for the widget. |
||
Copy
|
|||
cssClasses
# |
type: object
default: {}
Optional
TThe CSS classes you can override:
|
||
Copy
|
|||
transformItems
# |
type: function
default: items => items
Optional
Receives the items, and is called before displaying them. Should return a new array with the same shape as the original array. Useful for mapping over the items to transform, and remove or reorder them. |
||
Copy
|
Templates # A
You can customize parts of the widget’s UI using the Templates API.
Every template provides an html
function you can use as a tagged template. Using html
lets you safely provide templates as an HTML string. It works directly in the browser without a build step. See Templating your UI for more information.
The html
function is available starting from v4.46.0.
Parameter | Description | ||
---|---|---|---|
item
# |
type: string|function
Optional
The template to customize each
|
||
Copy
|
|||
defaultOption
# |
type: string|function
Optional
The template to customize the first option of the select. |
||
Copy
|
HTML output# A
1
2
3
4
5
6
7
8
<div class="ais-MenuSelect">
<select class="ais-MenuSelect-select">
<option class="ais-Menu-option">
Apple (50)
</option>
<!-- more items -->
</select>
</div>
Customize the UI with connectMenu# A
If you want to create your own UI of the menuSelect
widget, you can use connectors.
This connector is also used to build other widgets: Menu
To use connectMenu
, you can import it with the declaration relevant to how you installed InstantSearch.js.
1
import { connectMenu } from 'instantsearch.js/es/connectors';
Then it’s a 3-step process:
// 1. Create a render function
const renderMenuSelect = (renderOptions, isFirstRender) => {
// Rendering logic
};
// 2. Create the custom widget
const customMenuSelect = connectMenu(
renderMenuSelect
);
// 3. Instantiate
search.addWidgets([
customMenuSelect({
// instance params
})
]);
Create a render function#
This rendering function is called before the first search (init
lifecycle step)
and each time results come back from Algolia (render
lifecycle step).
const renderMenuSelect = (renderOptions, isFirstRender) => {
const {
object[] items,
boolean canRefine,
function refine,
function sendEvent,
object widgetParams,
} = renderOptions;
if (isFirstRender) {
// Do some initial rendering and bind events
}
// Render the widget
}
If SEO is critical to your search page, your custom HTML markup needs to be parsable:
- use plain
<a>
tags withhref
attributes for search engines bots to follow them, - use semantic markup with structured data when relevant, and test it.
Refer to our SEO checklist for building SEO-ready search experiences.
Rendering options #
Parameter | Description | ||
---|---|---|---|
items
# |
type: object[]
The elements that can be refined for the current search results. With each item:
|
||
Copy
|
|||
canRefine
# |
type: boolean
Returns |
||
Copy
|
|||
refine
# |
type: function
Sets the refinement and triggers a search. |
||
Copy
|
|||
sendEvent
# |
type: (eventType, facetValue) => void
The function to send
|
||
Copy
|
|||
widgetParams
# |
type: object
All original widget options forwarded to the render function. |
||
Copy
|
Create and instantiate the custom widget#
We first create custom widgets from our rendering function, then we instantiate them. When doing that, there are two types of parameters you can give:
- Instance parameters: they are predefined parameters that you can use to configure the behavior of Algolia.
- Your own parameters: to make the custom widget generic.
Both instance and custom parameters are available in connector.widgetParams
, inside the renderFunction
.
const customMenuSelect = connectMenu(
renderMenuSelect
);
search.addWidgets([
customMenuSelect({
attribute: string,
// Optional parameters
limit: number,
sortBy: string[]|function,
transformItems: function,
})
]);
Instance options #
Parameter | Description | ||
---|---|---|---|
attribute
# |
type: string
Required
The name of the attribute in the record. |
||
Copy
|
|||
limit
# |
type: number
default: 10
Optional
The maximum number of values to display. |
||
Copy
|
|||
sortBy
# |
type: string[]|function
default: ["isRefined", "name:asc"]
Optional
How to sort refinements. Must be one or more of the following strings:
It’s also possible to give a function, which receives items two by two, like JavaScript’s |
||
Copy
|
|||
transformItems
# |
type: function
default: items => items
Optional
Receives the items, and is called before displaying them. Should return a new array with the same shape as the original array. Useful for mapping over the items to transform, and remove or reorder them. |
||
Copy
|
Full example#
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
// Create the render function
const renderMenuSelect = (renderOptions, isFirstRender) => {
const { items, canRefine, refine, widgetParams } = renderOptions;
if (isFirstRender) {
const select = document.createElement('select');
select.addEventListener('change', event => {
refine(event.target.value);
});
widgetParams.container.appendChild(select);
}
const select = widgetParams.container.querySelector('select');
select.disabled = !canRefine;
select.innerHTML = `
<option value="">See all</option>
${items
.map(
item =>
`<option
value="${item.value}"
${item.isRefined ? 'selected' : ''}
>
${item.label}
</option>`
)
.join('')}
`;
};
// Create the custom widget
const customMenuSelect = connectMenu(renderMenuSelect);
// Instantiate the custom widget
search.addWidgets([
customMenuSelect({
container: document.querySelector('#menu-select'),
attribute: 'brand',
})
]);