From cb4f5a07d51769d3feca972d1bbd29e2d01fd2ff Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Tue, 23 Oct 2018 20:02:50 +0200 Subject: [PATCH] feat(paginator): allow paginator to be disabled (#13146) Adds the ability for the paginator to be disabled. This is useful for cases like long-running HTTP requests where the user shouldn't be able to change the current page while the data is still loading. Fixes #13145. --- src/demo-app/paginator/paginator-demo.html | 2 ++ src/demo-app/paginator/paginator-demo.ts | 1 + src/lib/paginator/paginator.html | 17 ++++++------ src/lib/paginator/paginator.spec.ts | 31 +++++++++++++++++++--- src/lib/paginator/paginator.ts | 21 ++++++++++++--- 5 files changed, 58 insertions(+), 14 deletions(-) diff --git a/src/demo-app/paginator/paginator-demo.html b/src/demo-app/paginator/paginator-demo.html index d75b72294f9..af3c21879c1 100644 --- a/src/demo-app/paginator/paginator-demo.html +++ b/src/demo-app/paginator/paginator-demo.html @@ -20,12 +20,14 @@ Hide page size Show multiple page size options Show first/last buttons + Disabled @@ -32,9 +33,9 @@ (click)="firstPage()" [attr.aria-label]="_intl.firstPageLabel" [matTooltip]="_intl.firstPageLabel" - [matTooltipDisabled]="!hasPreviousPage()" + [matTooltipDisabled]="_previousButtonsDisabled()" [matTooltipPosition]="'above'" - [disabled]="!hasPreviousPage()" + [disabled]="_previousButtonsDisabled()" *ngIf="showFirstLastButtons"> @@ -45,9 +46,9 @@ (click)="previousPage()" [attr.aria-label]="_intl.previousPageLabel" [matTooltip]="_intl.previousPageLabel" - [matTooltipDisabled]="!hasPreviousPage()" + [matTooltipDisabled]="_previousButtonsDisabled()" [matTooltipPosition]="'above'" - [disabled]="!hasPreviousPage()"> + [disabled]="_previousButtonsDisabled()"> @@ -57,9 +58,9 @@ (click)="nextPage()" [attr.aria-label]="_intl.nextPageLabel" [matTooltip]="_intl.nextPageLabel" - [matTooltipDisabled]="!hasNextPage()" + [matTooltipDisabled]="_nextButtonsDisabled()" [matTooltipPosition]="'above'" - [disabled]="!hasNextPage()"> + [disabled]="_nextButtonsDisabled()"> @@ -69,9 +70,9 @@ (click)="lastPage()" [attr.aria-label]="_intl.lastPageLabel" [matTooltip]="_intl.lastPageLabel" - [matTooltipDisabled]="!hasNextPage()" + [matTooltipDisabled]="_nextButtonsDisabled()" [matTooltipPosition]="'above'" - [disabled]="!hasNextPage()" + [disabled]="_nextButtonsDisabled()" *ngIf="showFirstLastButtons"> diff --git a/src/lib/paginator/paginator.spec.ts b/src/lib/paginator/paginator.spec.ts index f3a2b3e08b2..c290748db41 100644 --- a/src/lib/paginator/paginator.spec.ts +++ b/src/lib/paginator/paginator.spec.ts @@ -1,11 +1,11 @@ import {async, ComponentFixture, TestBed, inject, tick, fakeAsync} from '@angular/core/testing'; -import {MatPaginatorModule} from './index'; -import {MatPaginator} from './paginator'; import {Component, ViewChild} from '@angular/core'; -import {MatPaginatorIntl} from './paginator-intl'; import {NoopAnimationsModule} from '@angular/platform-browser/animations'; import {dispatchMouseEvent} from '@angular/cdk/testing'; import {ThemePalette} from '@angular/material/core'; +import {MatSelect} from '@angular/material/select'; +import {By} from '@angular/platform-browser'; +import {MatPaginatorModule, MatPaginator, MatPaginatorIntl} from './index'; describe('MatPaginator', () => { @@ -391,6 +391,29 @@ describe('MatPaginator', () => { .toBeNull('Expected select to be removed.'); }); + it('should be able to disable all the controls in the paginator via the binding', () => { + const select: MatSelect = fixture.debugElement.query(By.directive(MatSelect)).componentInstance; + + fixture.componentInstance.pageIndex = 1; + fixture.componentInstance.showFirstLastButtons = true; + fixture.detectChanges(); + + expect(select.disabled).toBe(false); + expect(getPreviousButton(fixture).hasAttribute('disabled')).toBe(false); + expect(getNextButton(fixture).hasAttribute('disabled')).toBe(false); + expect(getFirstButton(fixture).hasAttribute('disabled')).toBe(false); + expect(getLastButton(fixture).hasAttribute('disabled')).toBe(false); + + fixture.componentInstance.disabled = true; + fixture.detectChanges(); + + expect(select.disabled).toBe(true); + expect(getPreviousButton(fixture).hasAttribute('disabled')).toBe(true); + expect(getNextButton(fixture).hasAttribute('disabled')).toBe(true); + expect(getFirstButton(fixture).hasAttribute('disabled')).toBe(true); + expect(getLastButton(fixture).hasAttribute('disabled')).toBe(true); + }); + }); function getPreviousButton(fixture: ComponentFixture) { @@ -418,6 +441,7 @@ function getLastButton(fixture: ComponentFixture) { [showFirstLastButtons]="showFirstLastButtons" [length]="length" [color]="color" + [disabled]="disabled" (page)="pageEvent($event)"> `, @@ -429,6 +453,7 @@ class MatPaginatorApp { hidePageSize = false; showFirstLastButtons = false; length = 100; + disabled: boolean; pageEvent = jasmine.createSpy('page event'); color: ThemePalette; diff --git a/src/lib/paginator/paginator.ts b/src/lib/paginator/paginator.ts index f6eefab4bce..0445dcd9f50 100644 --- a/src/lib/paginator/paginator.ts +++ b/src/lib/paginator/paginator.ts @@ -25,6 +25,9 @@ import { HasInitializedCtor, mixinInitialized, ThemePalette, + mixinDisabled, + CanDisableCtor, + CanDisable, } from '@angular/material/core'; /** The default page size if there is no page size and there are no provided page size options. */ @@ -54,8 +57,8 @@ export class PageEvent { // Boilerplate for applying mixins to MatPaginator. /** @docs-private */ export class MatPaginatorBase {} -export const _MatPaginatorBase: HasInitializedCtor & typeof MatPaginatorBase = - mixinInitialized(MatPaginatorBase); +export const _MatPaginatorBase: CanDisableCtor & HasInitializedCtor & typeof MatPaginatorBase = + mixinDisabled(mixinInitialized(MatPaginatorBase)); /** * Component to provide navigation between paged information. Displays the size of the current @@ -68,13 +71,15 @@ export const _MatPaginatorBase: HasInitializedCtor & typeof MatPaginatorBase = exportAs: 'matPaginator', templateUrl: 'paginator.html', styleUrls: ['paginator.css'], + inputs: ['disabled'], host: { 'class': 'mat-paginator', }, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, }) -export class MatPaginator extends _MatPaginatorBase implements OnInit, OnDestroy, HasInitialized { +export class MatPaginator extends _MatPaginatorBase implements OnInit, OnDestroy, CanDisable, + HasInitialized { private _initialized: boolean; private _intlChanges: Subscription; @@ -234,6 +239,16 @@ export class MatPaginator extends _MatPaginatorBase implements OnInit, OnDestroy this._emitPageEvent(previousPageIndex); } + /** Checks whether the buttons for going forwards should be disabled. */ + _nextButtonsDisabled() { + return this.disabled || !this.hasNextPage(); + } + + /** Checks whether the buttons for going backwards should be disabled. */ + _previousButtonsDisabled() { + return this.disabled || !this.hasPreviousPage(); + } + /** * Updates the list of page size options to display to the user. Includes making sure that * the page size is an option and that the list is sorted.