- Row per page:
{{pagingBar.range}} of {{pagingBar.total}}
@@ -27,7 +27,7 @@
HTML:
Row per page:
{ {pagingBar.range} } of { {pagingBar.total} }
@@ -101,7 +101,7 @@
Example:
+ pageLinkCount="5" [initialPage]="1" [pageSize]="100" [total]="1345" (change)="change($event)">
Row per page:
{ {pagingBar.range} } of { {pagingBar.total} }
diff --git a/src/app/components/components/paging/paging.component.ts b/src/app/components/components/paging/paging.component.ts
index 5d36929feb..47caf600ec 100644
--- a/src/app/components/components/paging/paging.component.ts
+++ b/src/app/components/components/paging/paging.component.ts
@@ -35,6 +35,10 @@ export class PagingDemoComponent {
description: `Selected page size for the pagination. Defaults to first element of the [pageSizes] array.`,
name: 'pageSize?',
type: 'number',
+ }, {
+ description: `Defines the number of PageLinks to display. PageLinks are used to jump to a specific page, default is 0.`,
+ name: 'pageLinkCount?',
+ type: 'number',
}, {
description: `ets starting page for the paging bar. Defaults to '1'`,
name: 'initialPage?',
diff --git a/src/platform/core/paging/paging-bar.component.html b/src/platform/core/paging/paging-bar.component.html
index 680f365aef..f1e59a98a8 100644
--- a/src/platform/core/paging/paging-bar.component.html
+++ b/src/platform/core/paging/paging-bar.component.html
@@ -12,16 +12,19 @@
-
diff --git a/src/platform/core/paging/paging-bar.component.spec.ts b/src/platform/core/paging/paging-bar.component.spec.ts
new file mode 100644
index 0000000000..c8233cc832
--- /dev/null
+++ b/src/platform/core/paging/paging-bar.component.spec.ts
@@ -0,0 +1,222 @@
+import {
+ TestBed,
+ inject,
+ async,
+ ComponentFixture,
+} from '@angular/core/testing';
+import 'hammerjs';
+import { Component } from '@angular/core';
+import { By } from '@angular/platform-browser';
+import { TdPagingBarComponent } from './paging-bar.component';
+import { CovalentPagingModule } from './paging.module';
+import { NgModule, DebugElement } from '@angular/core';
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+
+describe('Component: TdPagingBarComponent', () => {
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ imports: [
+ BrowserAnimationsModule,
+ CovalentPagingModule,
+ ],
+ declarations: [
+ TestpageSizeAllTextComponent,
+ TestInitialPageComponent,
+ TestPageSizesComponent,
+ TestFirstLastComponent,
+ TestPageLinkCountComponent,
+ ],
+ });
+ TestBed.compileComponents();
+ }));
+
+ it('should create the component', (done: DoneFn) => {
+ let fixture: ComponentFixture = TestBed.createComponent(TestpageSizeAllTextComponent);
+ let component: TestpageSizeAllTextComponent = fixture.debugElement.componentInstance;
+
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ expect(component).toBeTruthy();
+ done();
+ });
+ });
+
+ it('should set pageSizeAllText, pageSizeAll and see it in markup', (done: DoneFn) => {
+ let fixture: ComponentFixture = TestBed.createComponent(TestpageSizeAllTextComponent);
+ let component: TestpageSizeAllTextComponent = fixture.debugElement.componentInstance;
+
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ let pageSizeAllText: string = fixture.debugElement.query(By.directive(TdPagingBarComponent)).componentInstance.pageSizeAllText;
+ expect(pageSizeAllText).toBe('SomeOtherText');
+
+ component.pageSizeAllText = 'aDifferentText';
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ pageSizeAllText = fixture.debugElement.query(By.directive(TdPagingBarComponent)).componentInstance.pageSizeAllText;
+ expect(pageSizeAllText).toBe('aDifferentText');
+
+ let pageSizeAll: boolean = fixture.debugElement.query(By.directive(TdPagingBarComponent)).componentInstance.pageSizeAll;
+ expect(pageSizeAll).toBe(true);
+
+ component.pageSizeAll = false;
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ pageSizeAll = fixture.debugElement.query(By.directive(TdPagingBarComponent)).componentInstance.pageSizeAll;
+ expect(pageSizeAll).toBe(false);
+ done();
+ });
+ });
+ });
+ });
+ });
+
+ it('should set pageSizes and then component instantiate with that pageSize', (done: DoneFn) => {
+ let fixture: ComponentFixture = TestBed.createComponent(TestPageSizesComponent);
+ let component: TestPageSizesComponent = fixture.debugElement.componentInstance;
+
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ let pageSize: number = fixture.debugElement.query(By.directive(TdPagingBarComponent)).componentInstance.pageSize;
+ expect(pageSize).toBe(37);
+
+ component.pageSizes = [55, 77];
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ pageSize = fixture.debugElement.query(By.directive(TdPagingBarComponent)).componentInstance.pageSize;
+ expect(pageSize).toBe(55);
+ done();
+ });
+ });
+ });
+ });
+
+ it('should set intialPage and then component instantiate with that page', (done: DoneFn) => {
+ let fixture: ComponentFixture = TestBed.createComponent(TestInitialPageComponent);
+ let component: TestInitialPageComponent = fixture.debugElement.componentInstance;
+
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ let page: number = fixture.debugElement.query(By.directive(TdPagingBarComponent)).componentInstance.page;
+ expect(page).toBe(3);
+ done();
+ });
+ });
+ });
+
+ it('should set firstLast and then see buttons in markup', (done: DoneFn) => {
+ let fixture: ComponentFixture = TestBed.createComponent(TestFirstLastComponent);
+ let component: TestFirstLastComponent = fixture.debugElement.componentInstance;
+
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ let id: string = fixture.debugElement.query(By.directive(TdPagingBarComponent)).componentInstance.id;
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-first-page'))).toBeTruthy();
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-last-page'))).toBeTruthy();
+
+ component.firstLast = false;
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ id = fixture.debugElement.query(By.directive(TdPagingBarComponent)).componentInstance.id;
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-first-page'))).toBeFalsy();
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-last-page'))).toBeFalsy();
+ done();
+ });
+ });
+ });
+ });
+
+ it('should set pageLinkCount and then see buttons in markup', (done: DoneFn) => {
+ let fixture: ComponentFixture = TestBed.createComponent(TestPageLinkCountComponent);
+ let component: TestPageLinkCountComponent = fixture.debugElement.componentInstance;
+
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ let id: string = fixture.debugElement.query(By.directive(TdPagingBarComponent)).componentInstance.id;
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-page-link-0'))).toBeTruthy();
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-page-link-1'))).toBeTruthy();
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-page-link-2'))).toBeTruthy();
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-page-link-3'))).toBeTruthy();
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-page-link-4'))).toBeTruthy();
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-page-link-5'))).toBeTruthy();
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-page-link-6'))).toBeTruthy();
+
+ component.pageLinkCount = 4;
+ component.pageSize = 50;
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ fixture.detectChanges();
+ fixture.whenStable().then(() => {
+ id = fixture.debugElement.query(By.directive(TdPagingBarComponent)).componentInstance.id;
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-page-link-0'))).toBeTruthy();
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-page-link-1'))).toBeTruthy();
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-page-link-2'))).toBeTruthy();
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-page-link-3'))).toBeTruthy();
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-page-link-4'))).toBeFalsy();
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-page-link-5'))).toBeFalsy();
+ expect(fixture.debugElement.query(By.css('#td-paging-bar-' + id + '-page-link-6'))).toBeFalsy();
+ done();
+ });
+ });
+ });
+ });
+ });
+});
+
+@Component({
+ template: `
+ `,
+})
+class TestpageSizeAllTextComponent {
+ pageSizeAllText: string = 'SomeOtherText';
+ pageSizeAll: boolean = true;
+}
+
+@Component({
+ template: `
+ `,
+})
+class TestPageSizesComponent {
+ pageSizes: number[] = [37, 48];
+}
+
+@Component({
+ template: `
+ `,
+})
+class TestInitialPageComponent {
+ initialPage: number = 3;
+}
+
+@Component({
+ template: `
+ `,
+})
+class TestFirstLastComponent {
+ firstLast: boolean = true;
+}
+
+@Component({
+ template: `
+ `,
+})
+class TestPageLinkCountComponent {
+ pageLinkCount: number = 7;
+ pageSize: number = 100;
+}
diff --git a/src/platform/core/paging/paging-bar.component.ts b/src/platform/core/paging/paging-bar.component.ts
index 66218344ff..ea38e41cc1 100644
--- a/src/platform/core/paging/paging-bar.component.ts
+++ b/src/platform/core/paging/paging-bar.component.ts
@@ -24,6 +24,13 @@ export class TdPagingBarComponent implements OnInit {
private _fromRow: number = 1;
private _toRow: number = 1;
private _initialized: boolean = false;
+ private _pageLinks: number[] = [];
+ private _pageLinkCount: number = 0;
+ private _id: string;
+ // special case when 2 pageLinks, detect when hit end of pages so can lead in correct direction
+ private _hitEnd: boolean = false;
+ // special case when 2 pageLinks, detect when hit start of pages so can lead in correct direction
+ private _hitStart: boolean = false;
/**
* pageSizeAll?: boolean
@@ -49,6 +56,19 @@ export class TdPagingBarComponent implements OnInit {
*/
@Input('initialPage') initialPage: number = 1;
+ /**
+ * pageLinkCount?: number
+ * Amount of page jump to links for the paging bar. Defaults to '0'
+ */
+ @Input('pageLinkCount')
+ set pageLinkCount(pageLinkCount: number) {
+ this._pageLinkCount = pageLinkCount;
+ this._calculatePageLinks();
+ }
+ get pageLinkCount(): number {
+ return this._pageLinkCount;
+ }
+
/**
* pageSizes?: number[]
* Array that populates page size menu. Defaults to [50, 100, 200, 500, 1000]
@@ -91,11 +111,20 @@ export class TdPagingBarComponent implements OnInit {
set total(total: number) {
this._total = total;
this._calculateRows();
+ this._calculatePageLinks();
}
get total(): number {
return this._total;
}
+ /**
+ * pageLinks: number[]
+ * Returns the pageLinks in an array
+ */
+ get pageLinks(): number[] {
+ return this._pageLinks;
+ }
+
/**
* range: string
* Returns the range of the rows.
@@ -120,6 +149,14 @@ export class TdPagingBarComponent implements OnInit {
return Math.ceil(this._total / this._pageSize);
}
+ /**
+ * id: string
+ * Returns the guid id for this paginator
+ */
+ get id(): string {
+ return this._id;
+ }
+
/**
* change?: function
* Method to be executed when page size changes or any button is clicked in the paging bar.
@@ -134,11 +171,14 @@ export class TdPagingBarComponent implements OnInit {
return false;
}
- constructor(@Optional() private _dir: Dir) {}
+ constructor(@Optional() private _dir: Dir) {
+ this._id = this.guid();
+ }
ngOnInit(): void {
this._page = this.initialPage;
this._calculateRows();
+ this._calculatePageLinks();
this._initialized = true;
}
@@ -201,8 +241,54 @@ export class TdPagingBarComponent implements OnInit {
this._toRow = this._total > top ? top : this._total;
}
+ /**
+ * _calculatePageLinks?: function
+ * Calculates the page links that should be shown to the user based on the current state of the paginator
+ */
+ private _calculatePageLinks(): void {
+ // special case when 2 pageLinks, detect when hit end of pages so can lead in correct direction
+ if (this.isMaxPage()) {
+ this._hitEnd = true;
+ this._hitStart = false;
+ }
+ // special case when 2 pageLinks, detect when hit start of pages so can lead in correct direction
+ if (this.isMinPage()) {
+ this._hitEnd = false;
+ this._hitStart = true;
+ }
+ // If the pageLinkCount goes above max possible pages based on perpage setting then reset it to maxPage
+ let actualPageLinkCount: number = this.pageLinkCount;
+ if (this.pageLinkCount > this.maxPage) {
+ actualPageLinkCount = this.maxPage;
+ }
+ // reset the pageLinks array
+ this._pageLinks = [];
+ // fill in the array with the pageLinks based on the current selected page
+ let middlePageLinks: number = Math.floor(actualPageLinkCount / 2);
+ for (let x: number = 0; x < actualPageLinkCount; x++) {
+ // don't go past the maxPage in the pageLinks
+ // have to handle even and odd pageLinkCounts differently so can still lead to the next numbers
+ if ((actualPageLinkCount % 2 === 0 && (this.page + middlePageLinks > this.maxPage)) ||
+ (actualPageLinkCount % 2 !== 0 && (this.page + middlePageLinks >= this.maxPage))) {
+ this._pageLinks[x] = this.maxPage - (actualPageLinkCount - (x + 1));
+ // if the selected page is after the middle then set that page as middle and get the correct balance on left and right
+ // special handling when there are only 2 pageLinks to just drop to next if block so can lead to next numbers when moving to right
+ // when moving to the left then go into this block
+ } else if ((actualPageLinkCount > 2 || actualPageLinkCount <= 2 && this._hitEnd) && (this.page - middlePageLinks) > 0) {
+ this._pageLinks[x] = (this.page - middlePageLinks) + x;
+ // if the selected page is before the middle then set the pages based on the x index leading up to and after selected page
+ } else if ((this.page - middlePageLinks) <= 0) {
+ this._pageLinks[x] = x + 1;
+ // other wise just set the array in order starting from the selected page
+ } else {
+ this._pageLinks[x] = this.page + x;
+ }
+ }
+ }
+
private _handleOnChange(): void {
this._calculateRows();
+ this._calculatePageLinks();
let event: IPageChangeEvent = {
page: this._page,
maxPage: this.maxPage,
@@ -214,4 +300,16 @@ export class TdPagingBarComponent implements OnInit {
this.onChange.emit(event);
}
+ /**
+ * guid?: function
+ * Returns RFC4122 random ("version 4") GUIDs
+ */
+ private guid(): string {
+ return this.s4() + this.s4() + '-' + this.s4() + '-' + this.s4() + '-' + this.s4() + '-' + this.s4() + this.s4() + this.s4();
+ }
+
+ private s4(): string {
+ return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
+ }
+
}