Skip to content

Commit

Permalink
Merge pull request #1485 from ghiscoding/feat/custom-pagination
Browse files Browse the repository at this point in the history
feat: allow providing a Custom Pagination Component
  • Loading branch information
ghiscoding authored Oct 19, 2024
2 parents f698ae8 + 036c25a commit d549239
Show file tree
Hide file tree
Showing 14 changed files with 695 additions and 151 deletions.
28 changes: 14 additions & 14 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@
},
"dependencies": {
"@ngx-translate/core": "^15.0.0",
"@slickgrid-universal/common": "~5.8.0",
"@slickgrid-universal/custom-footer-component": "~5.8.0",
"@slickgrid-universal/empty-warning-component": "~5.8.0",
"@slickgrid-universal/event-pub-sub": "~5.8.0",
"@slickgrid-universal/pagination-component": "~5.8.0",
"@slickgrid-universal/row-detail-view-plugin": "~5.8.0",
"@slickgrid-universal/rxjs-observable": "~5.8.0",
"@slickgrid-universal/common": "~5.9.0",
"@slickgrid-universal/custom-footer-component": "~5.9.0",
"@slickgrid-universal/empty-warning-component": "~5.9.0",
"@slickgrid-universal/event-pub-sub": "~5.9.0",
"@slickgrid-universal/pagination-component": "~5.9.0",
"@slickgrid-universal/row-detail-view-plugin": "~5.9.0",
"@slickgrid-universal/rxjs-observable": "~5.9.0",
"dequal": "^2.0.3",
"rxjs": "^7.8.1"
},
Expand Down Expand Up @@ -87,12 +87,12 @@
"@ngx-translate/http-loader": "^8.0.0",
"@popperjs/core": "^2.11.8",
"@release-it/conventional-changelog": "^8.0.2",
"@slickgrid-universal/composite-editor-component": "~5.8.0",
"@slickgrid-universal/custom-tooltip-plugin": "~5.8.0",
"@slickgrid-universal/excel-export": "~5.8.0",
"@slickgrid-universal/graphql": "~5.8.0",
"@slickgrid-universal/odata": "~5.8.0",
"@slickgrid-universal/text-export": "~5.8.0",
"@slickgrid-universal/composite-editor-component": "~5.9.0",
"@slickgrid-universal/custom-tooltip-plugin": "~5.9.0",
"@slickgrid-universal/excel-export": "~5.9.0",
"@slickgrid-universal/graphql": "~5.9.0",
"@slickgrid-universal/odata": "~5.9.0",
"@slickgrid-universal/text-export": "~5.9.0",
"@types/dompurify": "^3.0.5",
"@types/fnando__sparkline": "^0.3.7",
"@types/jest": "^29.5.13",
Expand All @@ -106,7 +106,7 @@
"cypress-real-events": "^1.13.0",
"dompurify": "^3.1.7",
"eslint": "^9.13.0",
"eslint-plugin-cypress": "^3.6.0",
"eslint-plugin-cypress": "^4.0.0",
"eslint-plugin-n": "^17.11.1",
"fetch-jsonp": "^1.3.0",
"jest": "^29.7.0",
Expand Down
2 changes: 2 additions & 0 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { GridClientSideComponent } from './examples/grid-clientside.component';
import { GridColspanComponent } from './examples/grid-colspan.component';
import { GridCompositeEditorComponent } from './examples/grid-composite-editor.component';
import { GridContextMenuComponent } from './examples/grid-contextmenu.component';
import { GridCustomPaginationComponent } from './examples/grid-custom-pagination.component';
import { GridCustomTooltipComponent } from './examples/grid-custom-tooltip.component';
import { GridDraggableGroupingComponent } from './examples/grid-draggrouping.component';
import { GridDragRecycleComponent } from './examples/grid-drag-recycle.component';
Expand Down Expand Up @@ -55,6 +56,7 @@ const routes: Routes = [
{ path: 'colspan', component: GridColspanComponent },
{ path: 'composite-editor', component: GridCompositeEditorComponent },
{ path: 'context', component: GridContextMenuComponent },
{ path: 'custom-pagination', component: GridCustomPaginationComponent },
{ path: 'custom-tooltip', component: GridCustomTooltipComponent },
{ path: 'drag-recycle', component: GridDragRecycleComponent },
{ path: 'editor', component: GridEditorComponent },
Expand Down
5 changes: 5 additions & 0 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,11 @@
41- Drag & Drop
</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLinkActive="active" [routerLink]="['/custom-pagination']">
42- Custom Pagination
</a>
</li>
</ul>
</section>

Expand Down
4 changes: 4 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { GridClientSideComponent } from './examples/grid-clientside.component';
import { GridColspanComponent } from './examples/grid-colspan.component';
import { GridContextMenuComponent } from './examples/grid-contextmenu.component';
import { GridCompositeEditorComponent } from './examples/grid-composite-editor.component';
import { GridCustomPaginationComponent } from './examples/grid-custom-pagination.component';
import { GridCustomTooltipComponent } from './examples/grid-custom-tooltip.component';
import { GridDraggableGroupingComponent } from './examples/grid-draggrouping.component';
import { GridDragRecycleComponent } from './examples/grid-drag-recycle.component';
Expand Down Expand Up @@ -56,6 +57,7 @@ import { GridTradingComponent } from './examples/grid-trading.component';
import { GridTreeDataHierarchicalComponent } from './examples/grid-tree-data-hierarchical.component';
import { GridTreeDataParentChildComponent } from './examples/grid-tree-data-parent-child.component';
import { HomeComponent } from './examples/home.component';
import { CustomPagerComponent } from './examples/grid-custom-pager.component';
import { RowDetailPreloadComponent } from './examples/rowdetail-preload.component';
import { RowDetailViewComponent } from './examples/rowdetail-view.component';

Expand Down Expand Up @@ -97,6 +99,7 @@ export function appInitializerFactory(translate: TranslateService, injector: Inj
AppComponent,
CustomButtonFormatterComponent,
CustomFooterComponent,
CustomPagerComponent,
CustomTitleFormatterComponent,
EditorNgSelectComponent,
FilterNgSelectComponent,
Expand All @@ -109,6 +112,7 @@ export function appInitializerFactory(translate: TranslateService, injector: Inj
GridColspanComponent,
GridCompositeEditorComponent,
GridContextMenuComponent,
GridCustomPaginationComponent,
GridCustomTooltipComponent,
GridDraggableGroupingComponent,
GridDragRecycleComponent,
Expand Down
47 changes: 47 additions & 0 deletions src/app/examples/grid-custom-pager.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<div class="custom-pagination">
<span class="custom-pagination-settings">
<span class="custom-pagination-count">
<span class="page-info-from-to">
<span class="item-from" aria-label="Page Item From" data-test="item-from">
{{currentPagination?.dataFrom}}
</span>-
<span class="item-to" aria-label="Page Item To" data-test="item-to">
{{currentPagination?.dataTo}}
</span>
of
</span>
<span class="page-info-total-items">
<span class="total-items" aria-label="Total Items" data-test="total-items">{{currentPagination?.totalItems}}</span>
<span class="text-items"> items</span>
</span>
</span>
</span>
<div class="custom-pagination-nav">
<nav aria-label="Page navigation">
<ul class="custom-pagination-ul">
<li class="li page-item seek-first" [class]="{ 'disabled' : isLeftPaginationDisabled() }">
<a class="pagination-link mdi mdi-page-first icon-seek-first mdi-22px" aria-label="First Page" role="button" (click)="onFirstPageClicked($event)"></a>
</li>
<li class="li page-item seek-prev" [class]="{ 'disabled' : isLeftPaginationDisabled() }">
<a class="pagination-link icon-seek-prev mdi mdi-chevron-down mdi-22px mdi-rotate-90" aria-label="Previous Page" role="button" (click)="onPreviousPageClicked($event)"></a>
</li>
</ul>
</nav>
<div class="page-number">
<span class="text-page">Page</span>
<span class="page-number" aria-label="Page Number" data-test="page-number-label">{{currentPagination?.pageNumber}}</span>
of
<span class="page-count" data-test="page-count">{{currentPagination?.pageCount}}</span>
</div>
<nav aria-label="Page navigation">
<ul class="custom-pagination-ul">
<li class="li page-item seek-next" [class]="{ 'disabled' : isRightPaginationDisabled() }" (click)="onNextPageClicked($event)">
<a class="pagination-link icon-seek-next mdi mdi-chevron-down mdi-22px mdi-rotate-270" aria-label="Next Page" role="button" ></a>
</li>
<li class="li page-item seek-end" [class]="{ 'disabled' : isRightPaginationDisabled() }">
<a class="pagination-link icon-seek-end mdi mdi-page-last mdi-22px" aria-label="Last Page" role="button" (click)="onLastPageClicked($event)"></a>
</li>
</ul>
</nav>
</div>
</div>
57 changes: 57 additions & 0 deletions src/app/examples/grid-custom-pager.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
@use 'sass:color';

.custom-pagination {
display: flex;
justify-content: flex-end;
margin: 10px;
font-size: 13px;

.custom-pagination-settings {
display: inline-flex;
align-items: center;
margin-right: 30px;
}

.custom-pagination-nav {
display: flex;
align-items: center;
list-style-type: none;

.page-item {
display: flex;
width: 26px;
justify-content: center;
margin: 0;
&.disabled .pagination-link {
color: rgb(180, 179, 179);
background-color: rgb(180, 179, 179);
}
}

.page-number {
padding: 0 5px;
.page-number {
display: inline-flex;
justify-content: center;
width: 20px;
}
}

nav {
ul.custom-pagination-ul {
display: flex;
list-style-type: none;
margin: 0;
padding: 0 5px;
color: #0d6efd;

.pagination-link {
color: #0d6efd;
&:hover {
color: color.adjust(#0d6efd, $lightness: 10%);
}
}
}
}
}
}
99 changes: 99 additions & 0 deletions src/app/examples/grid-custom-pager.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { Component, ElementRef } from '@angular/core';
import type { BasePaginationComponent, PaginationMetadata, PaginationService, PubSubService, SlickGrid, Subscription } from '@slickgrid-universal/common';

/** Custom Pagination Componnet, please note that you MUST `implements BasePaginationComponent` with required functions */
@Component({
templateUrl: './grid-custom-pager.component.html',
styleUrls: ['./grid-custom-pager.component.scss'],
})
export class CustomPagerComponent implements BasePaginationComponent {
protected _paginationElement!: HTMLDivElement;
protected _subscriptions: Subscription[] = [];
protected _gridContainerElm?: HTMLElement;
protected _grid!: SlickGrid;
protected _paginationService!: PaginationService;
protected _pubSubService!: PubSubService;
currentPagination = {} as PaginationMetadata;

constructor(protected readonly elm: ElementRef) { }

init(grid: SlickGrid, paginationService: PaginationService, pubSubService: PubSubService) {
this._grid = grid;
this._paginationService = paginationService;
this._pubSubService = pubSubService;
this.currentPagination = this._paginationService.getFullPagination();

// Anytime the pagination is initialized or has changes,
// we'll copy the data into a local object so that we can add binding to this local object
this._subscriptions.push(
this._pubSubService.subscribe<PaginationMetadata>('onPaginationRefreshed', paginationChanges => {
this.currentPagination.dataFrom = paginationChanges.dataFrom;
this.currentPagination.dataTo = paginationChanges.dataTo;
this.currentPagination.pageCount = paginationChanges.pageCount;
this.currentPagination.pageNumber = paginationChanges.pageNumber;
this.currentPagination.pageSize = paginationChanges.pageSize;
this.currentPagination.pageSizes = paginationChanges.pageSizes;
this.currentPagination.totalItems = paginationChanges.totalItems;
})
);
}

dispose() {
this._pubSubService.unsubscribeAll(this._subscriptions);
this.disposeElement();
}

disposeElement() {
this._paginationElement.remove();
}

renderPagination(containerElm: HTMLElement, position: 'top' | 'bottom' = 'top') {
this._gridContainerElm = containerElm;
this._paginationElement = this.elm.nativeElement;
this._paginationElement.id = 'pager';
this._paginationElement.className = `pagination-container pager ${this._grid.getUID()}`;
this._paginationElement.style.width = '100%';

if (position === 'top') {
// we can prepend the grid if we wish
this._paginationElement.classList.add('top');
containerElm.prepend(this._paginationElement);
} else {
// or append it at the bottom
this._paginationElement.classList.add('bottom');
containerElm.appendChild(this._paginationElement);
}
}

onFirstPageClicked(event: MouseEvent): void {
if (!this.isLeftPaginationDisabled()) {
this._paginationService.goToFirstPage(event);
}
}

onLastPageClicked(event: MouseEvent): void {
if (!this.isRightPaginationDisabled()) {
this._paginationService.goToLastPage(event);
}
}

onNextPageClicked(event: MouseEvent): void {
if (!this.isRightPaginationDisabled()) {
this._paginationService.goToNextPage(event);
}
}

onPreviousPageClicked(event: MouseEvent): void {
if (!this.isLeftPaginationDisabled()) {
this._paginationService.goToPreviousPage(event);
}
}

isLeftPaginationDisabled(): boolean {
return this.currentPagination.pageNumber === 1 || this.currentPagination.totalItems === 0;
}

isRightPaginationDisabled(): boolean {
return this.currentPagination.pageNumber === this.currentPagination.pageCount || this.currentPagination.totalItems === 0;
}
}
35 changes: 35 additions & 0 deletions src/app/examples/grid-custom-pagination.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<div id="demo-container" class="container-fluid">
<h2>
Example 42: Custom Pagination
<span class="float-end">
<a style="font-size: 18px"
target="_blank"
href="https://github.com/ghiscoding/Angular-Slickgrid/blob/master/src/app/examples/grid-custom-pagination.component.ts">
<span class="mdi mdi-link-variant"></span> code
</a>
</span>
</h2>
<div class="subtitle">
You can create a Custom Pagination by passing an Angular Custom Component and it must <code>implements BasePaginationComponent</code>.
Any of the pagination controls could be moved anywhere on the page (for example we purposely moved the page size away from the rest of the pagination elements).
</div>

<div>
<button class="btn btn-outline-secondary btn-icon" (click)="togglePaginationPosition()" data-text="toggle-pagination-btn">
<span class="mdi mdi-swap-vertical"></span>
<span>Toggle Pagination Position</span>
</button>

<span class="margin-15px">
Page Size
<input type="text" class="input is-small is-narrow" data-test="page-size-input" [(ngModel)]="pageSize" (ngModelChange)="setPaginationSize($event)" style="width: 55px">
</span>
</div>

<angular-slickgrid gridId="grid42"
[columnDefinitions]="columnDefinitions"
[gridOptions]="gridOptions"
[dataset]="dataset"
(onAngularGridCreated)="angularGridReady($event.detail)">
</angular-slickgrid>
</div>
Loading

0 comments on commit d549239

Please sign in to comment.