rangeSlider
About this widget
The rangeSlider
widget provides a user-friendly way to filter the results, based on a single numeric range.
Requirements
The attribute provided to the widget must be added in attributes for faceting, either on the dashboard or using attributesForFaceting with the API. The values inside attribute
must be numbers, not strings.
Examples
1
2
3
4
instantsearch.widgets.rangeSlider({
container: '#range-slider',
attribute: 'price',
});
Options
container
|
type: string|HTMLElement
Required
The CSS Selector or |
||
Copy
|
|||
attribute
|
type: string
Required
The name of the attribute in the record. |
||
Copy
|
|||
min
|
type: number
Optional
The minimum value for the input. When not provided, the minimum value is automatically computed by Algolia from the data in the index. |
||
Copy
|
|||
max
|
type: number
Optional
The maximum value for the input. When not provided, the maximum value is automatically computed by Algolia from the data in the index. |
||
Copy
|
|||
precision
|
type: number
default: 0
Optional
The number of digits after the decimal point to use. |
||
Copy
|
|||
step
|
type: number
Optional
The number of steps between each handle move. |
||
Copy
|
|||
pips
|
type: boolean
Optional
Whether to show slider pips. |
||
Copy
|
|||
tooltips
|
type: boolean|object
Optional
Whether to show tooltips. The default tooltips show the raw value. You can also provide an object with a format function. |
||
Copy
|
|||
cssClasses
|
type: object
default: {}
Optional
The CSS classes to override.
|
||
Copy
|
Customize the UI - connectRange
If you want to create your own UI of the rangeSlider
widget, you can use connectors.
This connector is also used to build other widgets: RangeInput
It’s a 3-step process:
// 1. Create a render function
const renderRangeSlider = (renderOptions, isFirstRender) => {
// Rendering logic
};
// 2. Create the custom widget
const customRangeSlider = instantsearch.connectors.connectRange(
renderRangeSlider
);
// 3. Instantiate
search.addWidget(
customRangeSlider({
// 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 renderRangeSlider = (renderOptions, isFirstRender) => {
const {
number[] start,
object range,
function refine,
object widgetParams,
} = renderOptions;
if (isFirstRender) {
// Do some initial rendering and bind events
}
// Render the widget
}
Rendering options
start
|
type: number[]
The current value for the refinement, with |
||
Copy
|
|||
range
|
type: object
The current available value for the range. |
||
Copy
|
|||
refine
|
type: function
Sets a range to filter the results on. Both values are optional, and default to the higher and lower bounds. You can use |
||
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 customRangeSlider = instantsearch.connectors.connectRange(
renderRangeSlider
);
search.addWidget(
customRangeSlider({
attribute: string,
// Optional parameters
min: number,
max: number,
precision: number,
})
);
Instance options
attribute
|
type: string
Required
The name of the attribute in the record. |
||
Copy
|
|||
min
|
type: number
Optional
The minimum value for the input. When not provided, the minimum value is automatically computed by Algolia from the data in the index. |
||
Copy
|
|||
max
|
type: number
Optional
The maximum value for the input. When not provided, the maximum value is automatically computed by Algolia from the data in the index. |
||
Copy
|
|||
precision
|
type: number
default: 0
Optional
The number of digits after the decimal point to use. |
||
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
// Create the render function
const renderRangeSlider = (renderOptions, isFirstRender) => {
const { start, range, refine, widgetParams } = renderOptions;
if (isFirstRender) {
const input = document.createElement('input');
input.type = 'range';
input.addEventListener('change', event => {
refine([parseFloat(event.currentTarget.value)]);
});
widgetParams.container.appendChild(input);
return;
}
const input = widgetParams.container.querySelector('input');
input.min = range.min;
input.max = range.max;
input.value = Number.isFinite(start[0]) ? start[0] : '0';
};
// Create the custom widget
const customRangeSider = instantsearch.connectors.connectRange(
renderRangeSlider
);
// Instantiate the custom widget
search.addWidget(
customRangeSider({
container: document.querySelector('#range-slider'),
attribute: 'price',
})
);
HTML output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<div class="ais-RangeSlider">
<div class="rheostat rheostat-horizontal" style="position: relative;">
<div class="rheostat-background"></div>
<div class="rheostat-handle rehostat-handle--lower" aria-valuemax="5000" aria-valuemin="1" aria-valuenow="750" aria-disabled="false" data-handle-key="0" role="slider" tabindex="0" style="left: 15%; position: absolute;">
<div class="rheostat-tooltip">$750</div>
</div>
<div class="rheostat-handle rheostat-handle--upper" aria-valuemax="5000" aria-valuemin="750" aria-valuenow="5000" aria-disabled="false" data-handle-key="1" role="slider" tabindex="0" style="left: 100%; position: absolute;">
<div class="rheostat-tooltip">$5,000</div>
</div>
<div class="rheostat-progress" style="left: 15%; width: 85%;"></div>
<div class="rheostat-marker rheostat-marker--large" style="left: 0%; position: absolute; margin-left: 0px;">
<div class="rheostat-value">1</div>
</div>
<div class="rheostat-marker" style="left: 2.94118%; position: absolute; margin-left: 0px;"></div>
<!-- ... -->
<div class="rheostat-marker" style="left: 97.0588%; position: absolute; margin-left: 0px;"></div>
<div class="rheostat-marker rheostat-marker--large" style="left: 100%; position: absolute; margin-left: -1px;">
<div class="rheostat-value">5,000</div>
</div>
</div>
</div>