ais-pagination
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-pagination // Optional parameters [padding]="number" [totalPages]="number" [showFirst]="boolean" [showLast]="boolean" [showPrevious]="boolean" [showNext]="boolean" ></ais-pagination>
1
2
3
4
5
6
7
8
import { NgAisPaginationModule } from 'angular-instantsearch';
@NgModule({
imports: [
NgAisPaginationModule,
],
})
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-pagination
widget displays a pagination system which lets users change the current page of search results.
The Algolia search engine limits paginating to 1,000 hits per page.
Examples
1
<ais-pagination></ais-pagination>
Props
Parameter | Description | ||
---|---|---|---|
padding
|
type: number
default: 3
Optional
How many page links to display around the current page. |
||
Copy
|
|||
totalPages
|
type: number
default: Infinity
Optional
The maximum number of pages to display (and to allow navigating to). |
||
Copy
|
|||
showFirst
|
type: boolean
default: true
Optional
Display the first page link. |
||
Copy
|
|||
showLast
|
type: boolean
default: true
Optional
Display the last page link. |
||
Copy
|
|||
showPrevious
|
type: boolean
default: true
Optional
Display the previous page link. |
||
Copy
|
|||
showNext
|
type: boolean
default: true
Optional
Display the next page link. |
||
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
23
24
25
26
27
28
<div class="ais-Pagination">
<ul class="ais-Pagination-list">
<li class="ais-Pagination-item ais-Pagination-item--firstPage ais-Pagination-item--disabled">
<span class="ais-Pagination-link" aria-label="First">‹‹</span>
</li>
<li class="ais-Pagination-item ais-Pagination-item--previousPage ais-Pagination-item--disabled">
<span class="ais-Pagination-link" aria-label="Previous">‹</span>
</li>
<li class="ais-Pagination-item ais-Pagination-item--selected">
<a class="ais-Pagination-link" href="#">1</a>
</li>
<li class="ais-Pagination-item ais-Pagination-item--page">
<a class="ais-Pagination-link" href="#">2</a>
</li>
<li class="ais-Pagination-item ais-Pagination-item--page">
<a class="ais-Pagination-link" href="#">3</a>
</li>
<li class="ais-Pagination-item">
<a class="ais-Pagination-link" href="#">4</a>
</li>
<li class="ais-Pagination-item ais-Pagination-item--nextPage">
<a class="ais-Pagination-link" aria-label="Next" href="#">›</a>
</li>
<li class="ais-Pagination-item ais-Pagination-item--lastPage">
<a class="ais-Pagination-link" aria-label="Last" href="#">››</a>
</li>
</ul>
</div>
Customize the UI with connectPagination
If you want to create your own UI of the ais-pagination
widget, you can combine the connectPagination
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-pagination',
template: '<p>It works!</p>'
})
export class Pagination extends TypedBaseWidget {
constructor(
@Inject(forwardRef(() => NgAisIndex))
@Optional()
public parentIndex: NgAisIndex,
@Inject(forwardRef(() => NgAisInstantSearch))
public instantSearchInstance: NgAisInstantSearch
) {
super('Pagination');
}
}
There are a couple of things happening in this boilerplate:
- create a
Pagination
class extendingTypedBaseWidget
- reference the
<ais-instantsearch>
parent component instance on thePagination
widget class - set
app-pagination
as a selector, so we can use our component as<app-pagination></app-pagination>
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
import { Component, Inject, forwardRef, Optional } from '@angular/core';
import { TypedBaseWidget, NgAisInstantSearch, NgAisIndex } from 'angular-instantsearch';
import connectPagination, {
PaginationWidgetDescription,
PaginationConnectorParams
} from 'instantsearch.js/es/connectors/pagination/connectPagination';
@Component({
selector: 'app-pagination',
template: '<p>It works!</p>'
})
export class Pagination extends TypedBaseWidget<PaginationWidgetDescription, PaginationConnectorParams> {
public state: PaginationWidgetDescription['renderState']; // Rendering options
constructor(
@Inject(forwardRef(() => NgAisIndex))
@Optional()
public parentIndex: NgAisIndex,
@Inject(forwardRef(() => NgAisInstantSearch))
public instantSearchInstance: NgAisInstantSearch
) {
super('Pagination');
}
ngOnInit() {
this.createWidget(connectPagination, {
// instance options
});
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: PaginationWidgetDescription['renderState'];
// {
// pages: number[];
// currentRefinement: number;
// nbHits: number;
// nbPages: number;
// isFirstPage: boolean;
// isLastPage: boolean;
// refine: Function;
// createURL: Function;
// widgetParams: Function;
// }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<button
(click)="state.refine(state.currentRefinement - 1)"
[disabled]="state.isFirstPage"
>
Prev
</button>
<button *ngFor="let page of state.pages" (click)="state.refine(page)">
<strong *ngIf="page === state.currentRefinement">{{ page + 1 }}</strong>
<span *ngIf="page !== state.currentRefinement">{{ page + 1 }}</span>
</button>
<button
(click)="state.refine(state.currentRefinement + 1)"
[disabled]="state.isLastPage"
>
Next
</button>
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 |
---|---|
pages
|
type: number[]
The pages relevant to the current state and padding. |
currentRefinement
|
type: number
The number of the currently displayed page. |
nbHits
|
type: number
The computed number of hits for the last query (can be approximate). |
nbPages
|
type: number
The number of pages for the result set. |
isFirstPage
|
type: boolean
Whether the current page is also the first one. |
isLastPage
|
type: boolean
Whether the current page is also the last one. |
refine
|
type: function
Sets the current page and triggers a search. |
createURL
|
type: function
Generates a URL for the next state. The number is the page to generate the URL for. |
widgetParams
|
type: function
All original widget options forwarded to the render function. |
Instance options
Parameter | Description |
---|---|
totalPages
|
type: number
Optional
The total number of pages to browse. |
padding
|
type: number
default: 3
Optional
The padding of pages to show around the current page. |
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
45
46
47
import { Component, Inject, forwardRef, Optional } from '@angular/core';
import { TypedBaseWidget, NgAisInstantSearch, NgAisIndex } from 'angular-instantsearch';
import connectPagination, {
PaginationWidgetDescription,
PaginationConnectorParams
} from 'instantsearch.js/es/connectors/pagination/connectPagination';
@Component({
selector: 'app-pagination',
template: `
<button
(click)="state.refine(state.currentRefinement - 1)"
[disabled]="state.isFirstPage"
>
Prev
</button>
<button *ngFor="let page of state.pages" (click)="state.refine(page)">
<strong *ngIf="page === state.currentRefinement">{{ page + 1 }}</strong>
<span *ngIf="page !== state.currentRefinement">{{ page + 1 }}</span>
</button>
<button
(click)="state.refine(state.currentRefinement + 1)"
[disabled]="state.isLastPage"
>
Next
</button>
`
})
export class Pagination extends TypedBaseWidget<PaginationWidgetDescription, PaginationConnectorParams> {
public state: PaginationWidgetDescription['renderState']; // Rendering options
constructor(
@Inject(forwardRef(() => NgAisIndex))
@Optional()
public parentIndex: NgAisIndex,
@Inject(forwardRef(() => NgAisInstantSearch))
public instantSearchInstance: NgAisInstantSearch
) {
super('Pagination');
}
ngOnInit() {
this.createWidget(connectPagination, {
// instance options
});
super.ngOnInit();
}
}