Reputation: 39
I have a figma design for angular mat paginator.how can i style mat paginator angular as it is shown in figma?
Upvotes: 1
Views: 3362
Reputation: 57909
To create a pagination button with ellipsis we can look for in internet the necessary algoritm. I did'nt want re-invent the wheel, but, sadly I can not find one "paginator" I like (the most of then add ellipsis and I can not get always the same number of elements (buttons and ellipsis). So, if we has "getNumberOfPages (the total pages)", "countPages" (the number of buttons), "pageIndex" (the actual page -0 is the first, 1 the second one...) we can return an array of strings using the function:
createButtonsPage() {
const last = this.getNumberOfPages() - 1;
const b = new Array(
last < this.countPages ? last + 1 : this.countPages
).fill('.');
if (last < this.countPages) return b.map((_x, i) => '' + i);
const links0_5 = (this.countPages - 1) / 2;
let start = this.pageIndex - links0_5 < 0 ? 0 :
this.pageIndex - links0_5;
let end =start == 0? this.countPages - 1:
this.pageIndex + links0_5 > last ? last:
this.pageIndex + links0_5;
if (end == last) start = end - this.countPages + 1;
return b.map((_x, i) => {
return i == 0 ? '0':
i == this.countPages - 1? '' + last:
(i == 1 && start) || (i == this.countPages - 2 && end != last)? '...':
'' + (i + start);
});
}
We can choose show buttons depending the size of the screen using fromEvent in the way
fromEvent(window, 'resize')
.pipe(
startWith({ target: { innerWidth: window.innerWidth } }),
debounceTime(200),
distinctUntilChanged(),
takeUntil(this.active),
map((e: any) => {
const countPage =
e.target.innerWidth > 620 ? (e.target.innerWidth > 750 ? 9 : 7) : 5;
return this.countPage
? countPage < this.countPage
? countPage
: this.countPage
: countPage;
})
)
.subscribe((x: number) => {
this.countPages = this.countPagesOld = x;
this._buttons = this.createButtonsPage();
});
And in our paginator, we can use a getter to the buttons. As we don't want "recalculate the buttons" we can store in variables the old values, some like
get buttons() {
if (
!this._buttons ||
this.pageIndexOld != this.pageIndex ||
this.countPagesOld != this.countPages ||
this.pageSizeOld != this.pageSize ||
this.lengthOld != this.length
) {
this._buttons = this.createButtonsPage();
this.pageIndexOld = this.pageIndex;
this.countPagesOld = this.countPages;
this.pageSizeOld = this.pageSize;
const last = this.getNumberOfPages();
if (last && +this.control.value > last)
this.control.setValue(last, { emitEvent: false });
}
return this._buttons;
}
Well, I made a new stackblitz. In the stackblitz you can also
Upvotes: 1
Reputation: 57909
You can create a custom-paginator component that extends from _MatPaginatorBase
export class CustomPaginatorComponent extends
_MatPaginatorBase<MatPaginatorDefaultOptions> {
constructor(
intl: MatPaginatorIntl,
changeDetectorRef: ChangeDetectorRef,
@Optional() @Inject(MAT_PAGINATOR_DEFAULT_OPTIONS) defaults?:
MatPaginatorDefaultOptions,
) {
super(intl, changeDetectorRef, defaults);
}
To next/prev page simply call to previousPage()
and nextPage()
<button (click)="previousPage()">prev</button>
custom-paginator works!
<button (click)="nextPage()">next</button>
To go to a page you need create a function
emitPageEvent(nextPage:any)
{
this.pageIndex=+nextPage
this.page.emit({
pageIndex: this.pageIndex,
pageSize: this.pageSize,
length: this.length,
});
}
}
You can use a simple input
<input [ngModel]="pageIndex"
(ngModelChange)="emitPageEvent($event)">
See that you has all the properties and methods of MatPaginatorBase, the most important:
Properties:
pageIndex : {{pageIndex}}
length : {{length}}
pageSize : {{pageSize}}
pageSizeOptions: [{{pageSizeOptions}}]
Functions:
hasPreviousPage() :{{ hasPreviousPage()}}
hasNextPage() :{{hasNextPage()}}
previousPage()
nextPage()
firstPage()
lastPage()
See a stackblitz
Upvotes: 2