ais-refinement-list
Angular InstantSearch isn’t compatible with Angular’s Ivy view engine. We’re investigating how best to support this. For more information and to vote for Algolia’s support of Angular 16 and beyond, see the GitHub issue Algolia Support for Angular InstantSearch
<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>
1
2
3
4
5
6
7
8
import { NgAisRefinementListModule } from 'angular-instantsearch';
@NgModule({
imports: [
NgAisRefinementListModule,
],
})
export class AppModule {}
1. Follow additional steps in Optimize build size to ensure your code is correctly bundled.
2. This imports all the widgets, even the ones you don’t use. Read the Getting started guide for more information.
About this widget
The ais-refinement-list
component displays a list that lets users 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
through 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
1
<ais-refinement-list attribute="categories"></ais-refinement-list>
Props
Parameter | Description | ||
---|---|---|---|
attribute
|
type: string
Required
The name of the attribute in the record. To avoid unexpected behavior, you can’t use the same |
||
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 In some situations, refined facet values might not be present in the data returned by Algolia. Read the FAQ to get more information and adjust your configuration. |
||
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 In some situations, refined facet values might not be present in the data returned by Algolia. Read the FAQ to get more information and adjust your configuration. |
||
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
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
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
Parameter | Description |
---|---|
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
Parameter | Description |
---|---|
attribute
|
type: string
Required
The name of the attribute in the records. To avoid unexpected behavior, you can’t use the same |
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 In some situations, refined facet values might not be present in the data returned by Algolia. Read the FAQ to get more information and adjust your configuration. |
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();
}
}