ais-numeric-menu
<ais-numeric-menu attribute="string" [items]="object[]" // Optional parameters [autoHideContainer]="boolean" ></ais-numeric-menu>
About this widget # A
The ais-numeric-menu
component displays a menu that lets the user choose a single range for a specific numeric attribute.
Requirements#
-
The attributes passed to the
attributes
prop must be declared as Attributes for faceting on the Algolia dashboard or configured asattributesForFaceting
with the Algolia API. -
The attribute passed to the
attribute
prop must be represented as a number in the index, not a string.
Examples # A
1
2
3
4
5
6
7
8
9
10
<ais-numeric-menu
attribute="price"
[items]="[
{ label: 'All' },
{ end: 4, label: 'less than 4' },
{ start: 4, end: 4, label: '4' },
{ start: 5, end: 10, label: 'between 5 and 10' },
{ start: 10, label: 'more than 10' }
]"
></ais-numeric-menu>
Properties # A
attribute
# |
type: string
Required
The name of the attribute in the record. |
||
Copy
|
|||
items
# |
type: object[]
Required
The list of ranges availables. Both |
||
Copy
|
|||
autoHideContainer
# |
type: boolean
default: true
Optional
Whether to hide the menu if there’s no item to display |
||
Copy
|
HTML output# A
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
<div class="ais-NumericMenu">
<ul class="ais-NumericMenu-list">
<li class="ais-NumericMenu-item ais-NumericMenu-item--selected">
<label class="ais-NumericMenu-label">
<input
class="ais-NumericMenu-radio"
type="radio"
name="NumericMenu"
checked
/>
<span class="ais-NumericMenu-labelText">All</span>
</label>
</li>
<li class="ais-NumericMenu-item">
<label class="ais-NumericMenu-label">
<input
class="ais-NumericMenu-radio"
type="radio"
name="NumericMenu"
/>
<span class="ais-NumericMenu-labelText">Less than 500</span>
</label>
</li>
</ul>
</div>
Customize the UI with connectNumericMenu# A
If you want to create your own UI of the ais-numeric-menu
widget, you can combine the connectNumericMenu
connector with the TypedBaseWidget
class.
1. Extend the TypedBaseWidget
class#
First of all, you will need to write some boilerplate code to initialize correctly the TypedBaseWidget
class. This happens in the constructor()
of your class extending the TypedBaseWidget
class.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { Component, Inject, forwardRef, Optional } from '@angular/core';
import { TypedBaseWidget, NgAisInstantSearch, NgAisIndex } from 'angular-instantsearch';
@Component({
selector: 'app-numeric-menu',
template: '<p>It works!</p>'
})
export class NumericMenu extends TypedBaseWidget {
constructor(
@Inject(forwardRef(() => NgAisIndex))
@Optional()
public parentIndex: NgAisIndex,
@Inject(forwardRef(() => NgAisInstantSearch))
public instantSearchInstance: NgAisInstantSearch
) {
super('NumericMenu');
}
}
There are a couple of things happening in this boilerplate:
- create a
NumericMenu
class extendingTypedBaseWidget
- reference the
<ais-instantsearch>
parent component instance on theNumericMenu
widget class - set
app-numeric-menu
as a selector, so we can use our component as<app-numeric-menu></app-numeric-menu>
2. Connect your custom widget#
The TypedBaseWidget
class has a method called createWidget()
which takes two arguments: the connector to use and an object of options
(instance options)
for this connector. We call this method at ngOnInit
. This component now implements OnInit
.
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
import { Component, Inject, forwardRef, Optional } from '@angular/core';
import { TypedBaseWidget, NgAisInstantSearch, NgAisIndex } from 'angular-instantsearch';
import connectNumericMenu, {
NumericMenuWidgetDescription,
NumericMenuConnectorParams
} from 'instantsearch.js/es/connectors/numeric-menu/connectNumericMenu';
@Component({
selector: 'app-numeric-menu',
template: '<p>It works!</p>'
})
export class NumericMenu extends TypedBaseWidget<NumericMenuWidgetDescription, NumericMenuConnectorParams> {
public state: NumericMenuWidgetDescription['renderState']; // Rendering options
constructor(
@Inject(forwardRef(() => NgAisIndex))
@Optional()
public parentIndex: NgAisIndex,
@Inject(forwardRef(() => NgAisInstantSearch))
public instantSearchInstance: NgAisInstantSearch
) {
super('NumericMenu');
}
ngOnInit() {
this.createWidget(connectNumericMenu, {
// instance options
attribute: 'free_shipping',
items: [
{ label: "All" },
{ end: 4, label: "less than 4" },
{ start: 4, end: 4, label: "4" },
{ start: 5, end: 10, label: "between 5 and 10" },
{ start: 10, label: "more than 10" }
],
});
super.ngOnInit();
}
}
3. Render from the state#
Your component instance has access to a this.state
property which holds the rendering options of the widget.
public state: NumericMenuWidgetDescription['renderState'];
// {
// items: object[];
// hasNoResults: boolean;
// refine: Function;
// createURL: Function;
// widgetParams: object;
// }
1
2
3
4
5
<select (change)="state.refine(select.selectedOptions[0].value)" #select>
<option *ngFor="let item of state.items; index as i" [value]="item.value">
{{ state.widgetParams.items[i].label }}
</option>
</select>
Rendering options #
items
# |
type: object[]
The list of available options, with each option:
|
hasNoResults
# |
type: boolean
Whether the search has results. |
refine
# |
type: function
Sets the selected value and triggers a new search. |
createURL
# |
type: function
Generates a URL for the next state. |
widgetParams
# |
type: object
All original widget options forwarded to the render function. |
Instance options #
attribute
# |
type: string
Required
The name of the attribute in the record. |
items
# |
type: object[]
Required
A list of all the options to display, with:
|
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. |
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
import { Component, Inject, forwardRef, Optional } from '@angular/core';
import { TypedBaseWidget, NgAisInstantSearch, NgAisIndex } from 'angular-instantsearch';
import connectNumericMenu, {
NumericMenuWidgetDescription,
NumericMenuConnectorParams
} from 'instantsearch.js/es/connectors/numeric-menu/connectNumericMenu';
@Component({
selector: 'app-numeric-menu',
template: `
<select (change)="state.refine(select.selectedOptions[0].value)" #select>
<option *ngFor="let item of state.items; index as i" [value]="item.value">
{{ state.widgetParams.items[i].label }}
</option>
</select>
`
})
export class NumericMenu extends TypedBaseWidget<NumericMenuWidgetDescription, NumericMenuConnectorParams> {
public state: NumericMenuWidgetDescription['renderState']; // Rendering options
constructor(
@Inject(forwardRef(() => NgAisIndex))
@Optional()
public parentIndex: NgAisIndex,
@Inject(forwardRef(() => NgAisInstantSearch))
public instantSearchInstance: NgAisInstantSearch
) {
super('NumericMenu');
}
ngOnInit() {
this.createWidget(connectNumericMenu, {
// instance options
attribute: 'free_shipping',
items: [
{ label: "All" },
{ end: 4, label: "less than 4" },
{ start: 4, end: 4, label: "4" },
{ start: 5, end: 10, label: "between 5 and 10" },
{ start: 10, label: "more than 10" }
],
});
super.ngOnInit();
}
}