ais-refinement-list
<ais-refinement-list attribute="string" // Optional parameters operator="or|and" [limit]="number" [showMoreLimit]="number" showMoreLabel="string" showLessLabel="string" [searchable]="boolean" searchPlaceholder="string" [sortBy]="string[]|function" [autoHideContainer]="boolean" [transformItems]="function" ></ais-refinement-list>
About this widget # A
The ais-refinement-list
component displays a list that let the end user choose multiple values for a specific facet.
Requirements#
The attribute passed to the attribute
prop must be present in “attributes for faceting” on the Algolia dashboard or configured as attributesForFaceting
via a set settings call to the Algolia API.
If you are using the searchable
prop, you’ll also need to make the attribute searchable using the dashboard or using the API.
Examples # A
1
<ais-refinement-list attribute="categories"></ais-refinement-list>
Props # A
attribute
# |
type: string
Required
The name of the attribute in the record. |
||
Copy
|
|||
operator
# |
type: string
default: or|and
Optional
How to apply refinements. |
||
Copy
|
|||
limit
# |
type: number
default: 10
Optional
How many facet values to retrieve. |
||
Copy
|
|||
showMoreLimit
# |
type: number
Optional
The maximum number of items to displayed when the list is showing more items. |
||
Copy
|
|||
showMoreLabel
# |
type: string
default: Show more
Optional
Label of the “Show more” button. |
||
Copy
|
|||
showLessLabel
# |
type: string
default: Show less
Optional
Label of the show less button. |
||
Copy
|
|||
searchable
# |
type: boolean
default: false
Optional
You should set it to |
||
Copy
|
|||
searchPlaceholder
# |
type: string
default: Search here...
Optional
Label for the placeholder of the search box. |
||
Copy
|
|||
sortBy
# |
type: string[]|function
default: ["isRefined", "count:desc", "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 must have the same signature than the JavaScript |
||
Copy
|
|||
autoHideContainer
# |
type: boolean
Optional
Hides the refinement list if there’s no item to display. |
||
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 transforming, removing, or reordering items. In addition, the full |
||
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
<div class="ais-RefinementList">
<div class="ais-RefinementList-searchBox">
<!-- SearchBox widget here -->
</div>
<ul class="ais-RefinementList-list">
<li class="ais-RefinementList-item ais-RefinementList-item--selected">
<label class="ais-RefinementList-label">
<input class="ais-RefinementList-checkbox" type="checkbox" value="Insignia™" checked />
<span class="ais-RefinementList-labelText">Insignia™</span>
<span class="ais-RefinementList-count">746</span>
</label>
</li>
<li class="ais-RefinementList-item">
<label class="ais-RefinementList-label">
<input class="ais-RefinementList-checkbox" type="checkbox" value="Samsung">
<span class="ais-RefinementList-labelText">Samsung</span>
<span class="ais-RefinementList-count">633</span>
</label>
</li>
</ul>
<button class="ais-RefinementList-showMore">Show more</button>
</div>
Customize the UI with connectRefinementList# A
If you want to create your own UI of the ais-refinement-list
widget, you can combine the connectRefinementList
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-refinement-list',
template: '<p>It works!</p>'
})
export class RefinementList extends TypedBaseWidget {
constructor(
@Inject(forwardRef(() => NgAisIndex))
@Optional()
public parentIndex: NgAisIndex,
@Inject(forwardRef(() => NgAisInstantSearch))
public instantSearchInstance: NgAisInstantSearch
) {
super('RefinementList');
}
}
There are a couple of things happening in this boilerplate:
- create a
RefinementList
class extendingTypedBaseWidget
- reference the
<ais-instantsearch>
parent component instance on theRefinementList
widget class - set
app-refinement-list
as a selector, so we can use our component as<app-refinement-list></app-refinement-list>
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
import { Component, Inject, forwardRef, Optional } from '@angular/core';
import { TypedBaseWidget, NgAisInstantSearch, NgAisIndex } from 'angular-instantsearch';
import connectRefinementList, {
RefinementListWidgetDescription,
RefinementListConnectorParams
} from 'instantsearch.js/es/connectors/refinement-list/connectRefinementList';
@Component({
selector: 'app-refinement-list',
template: '<p>It works!</p>'
})
export class RefinementList extends TypedBaseWidget<RefinementListWidgetDescription, RefinementListConnectorParams> {
public state: RefinementListWidgetDescription['renderState']; // Rendering options
constructor(
@Inject(forwardRef(() => NgAisIndex))
@Optional()
public parentIndex: NgAisIndex,
@Inject(forwardRef(() => NgAisInstantSearch))
public instantSearchInstance: NgAisInstantSearch
) {
super('RefinementList');
}
ngOnInit() {
this.createWidget(connectRefinementList, {
// instance options
attribute: 'brands',
});
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: RefinementListWidgetDescription['renderState'];
// {
// items: object[];
// refine: Function;
// createURL: Function;
// isFromSearch: boolean;
// searchForItems: Function;
// isShowingMore: boolean;
// canToggleShowMore: boolean;
// toggleShowMore: Function;
// widgetParams: object;
// }
1
2
3
4
5
<label *ngFor="let item of state.items">
<input type="checkbox"
(click)="state.refine(item.value)"
[checked]="item.isRefined" > {{ item.label }} ({{ item.count }})
</label>
Rendering options #
items
# |
type: object[]
The list of refinement values returned from the Algolia API. Each object has the following properties:
|
refine
# |
type: function
Toggles a refinement. |
createURL
# |
type: function
Generates a URL for the corresponding search state. |
isFromSearch
# |
type: boolean
Whether the |
searchForItems
# |
type: function
Triggers a search inside items values. To make this feature work, you need to make the attribute searchable using the dashboard or using the |
isShowingMore
# |
type: boolean
Whether the menu is displaying all the menu items. |
canToggleShowMore
# |
type: boolean
Whether the “Show more” button can be activated (if there are enough items to display and not already displaying more than the |
toggleShowMore
# |
type: function
Toggles the number of displayed values between |
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 records. |
operator
# |
type: string ("or"|"and")
default: "or"
Optional
How to apply refinements.
|
limit
# |
type: number
default: 10
Optional
How many facet values to retrieve. When isShowingMore is |
showMoreLimit
# |
type: number
Optional
The maximum number of items to display if the widget is showing more items. Needs to be bigger than the |
escapeFacetValues
# |
type: boolean
default: true
Optional
When |
sortBy
# |
type: string[]|function
default: ["isRefined","count:desc","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 |
transformItems
# |
type: function
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 transforming, removing, or reordering items. In addition, the full |
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
import { Component, Inject, forwardRef, Optional } from '@angular/core';
import { TypedBaseWidget, NgAisInstantSearch, NgAisIndex } from 'angular-instantsearch';
import connectRefinementList, {
RefinementListWidgetDescription,
RefinementListConnectorParams
} from 'instantsearch.js/es/connectors/refinement-list/connectRefinementList';
@Component({
selector: 'app-refinement-list',
template: `
<label *ngFor="let item of state.items">
<input type="checkbox"
(click)="state.refine(item.value)"
[checked]="item.isRefined" > {{ item.label }} ({{ item.count }})
</label>
`
})
export class RefinementList extends TypedBaseWidget<RefinementListWidgetDescription, RefinementListConnectorParams> {
public state: RefinementListWidgetDescription['renderState']; // Rendering options
constructor(
@Inject(forwardRef(() => NgAisIndex))
@Optional()
public parentIndex: NgAisIndex,
@Inject(forwardRef(() => NgAisInstantSearch))
public instantSearchInstance: NgAisInstantSearch
) {
super('RefinementList');
}
ngOnInit() {
this.createWidget(connectRefinementList, {
// instance options
attribute: 'brands',
});
super.ngOnInit();
}
}