projects/rebirth-ng/src/lib/pagination/pagination.component.ts
| changeDetection | ChangeDetectionStrategy.OnPush | 
            
| exportAs | pagination | 
            
| selector | re-pagination | 
            
| styleUrls | pagination.component.scss | 
            
| templateUrl | ./pagination.component.html | 
            
                        Properties | 
                
                        Methods | 
                
                        
  | 
                
                        Inputs | 
                
                        Outputs | 
                
constructor(rebirthNGConfig: RebirthNGConfig)
                     | 
                ||||||
| 
                             
                                    Parameters :
                                     
                    
  | 
                
                        
                        boundary
                     | 
                    
                             
                            Type:      | 
                
                        
                        cssClass
                     | 
                    
                             
                            Type:      | 
                
                        
                        firstLink
                     | 
                    
                             
                            Type:      | 
                
                        
                        firstLinkCssClass
                     | 
                    
                             
                            Type:      | 
                
                        
                        headTemplate
                     | 
                    
                             
                            Type:      | 
                
                        
                        lastLink
                     | 
                    
                             
                            Type:      | 
                
                        
                        lastLinkCssClass
                     | 
                    
                             
                            Type:      | 
                
                        
                        maxItems
                     | 
                    
                             
                            Type:      | 
                
                        
                        nextLink
                     | 
                    
                             
                            Type:      | 
                
                        
                        nextLinkCssClass
                     | 
                    
                             
                            Type:      | 
                
                        
                        pageIndex
                     | 
                    
                         
                            Default value:   | 
                
                        
                        pageSize
                     | 
                    
                             
                            Type:      | 
                
                        
                        preLink
                     | 
                    
                             
                            Type:      | 
                
                        
                        preLinkCssClass
                     | 
                    
                             
                            Type:      | 
                
                        
                        size
                     | 
                    
                             
                            Type:      | 
                
                        
                        tailTemplate
                     | 
                    
                             
                            Type:      | 
                
                        
                        total
                     | 
                    
                         
                            Default value:   | 
                
                        
                        pageIndexChange
                     | 
                    
                        $event type:    EventEmitter
                     | 
                
| Private extractRange | 
                            
                        extractRange()
                     | 
                
| 
                             
                                Returns :      
                    {}
                             | 
                
| first | 
first()
                     | 
                
| 
                             
                                Returns :      
                    void
                             | 
                
| Private getTotalPage | 
                            
                        getTotalPage()
                     | 
                
| 
                             
                                Returns :      
                    number
                             | 
                
| hasNext | 
hasNext()
                     | 
                
| 
                             
                                Returns :      
                    boolean
                             | 
                
| hasPrev | 
hasPrev()
                     | 
                
| 
                             
                                Returns :      
                    boolean
                             | 
                
| last | 
last()
                     | 
                
| 
                             
                                Returns :      
                    void
                             | 
                
| next | 
next()
                     | 
                
| 
                             
                                Returns :      
                    void
                             | 
                
| nextRange | 
nextRange()
                     | 
                
| 
                             
                                Returns :      
                    void
                             | 
                
| ngOnChanges | ||||||
ngOnChanges(changes: SimpleChanges)
                     | 
                ||||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                void
                             | 
                
| onPageIndexChange | ||||||
onPageIndexChange(pageIndex: number)
                     | 
                ||||||
| 
                             
                                    Parameters :
                                     
                            
 
                                Returns :      
                                void
                             | 
                
| preRange | 
preRange()
                     | 
                
| 
                             
                                Returns :      
                    void
                             | 
                
| prev | 
prev()
                     | 
                
| 
                             
                                Returns :      
                    void
                             | 
                
| Private updateShowPageRange | 
                            
                        updateShowPageRange()
                     | 
                
| 
                             
                                Returns :      
                    void
                             | 
                
| Static EFFECT_PAGE_RANGE_KEYS | 
                        EFFECT_PAGE_RANGE_KEYS:     
                     | 
                
                            Type :     []
                         | 
                    
                            Default value : ['total', 'pageSize', 'pageIndex', 'maxItems']
                         | 
                    
| showPages | 
                        showPages:     
                     | 
                
                            Type :     []
                         | 
                    
                            Default value : []
                         | 
                    
| totalPage | 
                        totalPage:     
                     | 
                
                            Type :     number
                         | 
                    
                            Default value : 0
                         | 
                    
import {
  Component, Input, Output, EventEmitter, OnChanges, ChangeDetectionStrategy,
  SimpleChanges, TemplateRef
} from '@angular/core';
import { RebirthNGConfig } from '../rebirth-ng.config';
@Component({
  selector: 're-pagination',
  templateUrl: './pagination.component.html',
  styleUrls: ['./pagination.component.scss'],
  exportAs: 'pagination',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class PaginationComponent implements OnChanges {
  static EFFECT_PAGE_RANGE_KEYS = ['total', 'pageSize', 'pageIndex', 'maxItems'];
  @Input() boundary: boolean;
  @Input() total = 0;
  @Input() pageSize: number;
  @Input() pageIndex = 1;
  @Output() pageIndexChange = new EventEmitter<number>();
  @Input() maxItems: number;
  @Input() firstLink: string;
  @Input() lastLink: string;
  @Input() preLink: string;
  @Input() nextLink: string;
  @Input() size: '' | 'lg' | 'sm';
  @Input() cssClass: string;
  @Input() headTemplate: TemplateRef<any>;
  @Input() tailTemplate: TemplateRef<any>;
  @Input() firstLinkCssClass: string;
  @Input() preLinkCssClass: string;
  @Input() nextLinkCssClass: string;
  @Input() lastLinkCssClass: string;
  showPages = [];
  totalPage = 0;
  constructor(rebirthNGConfig: RebirthNGConfig) {
    this.boundary = rebirthNGConfig.pagination.boundary;
    this.pageSize = rebirthNGConfig.pagination.pageSize;
    this.maxItems = rebirthNGConfig.pagination.maxItems;
    this.firstLink = rebirthNGConfig.pagination.button.first;
    this.lastLink = rebirthNGConfig.pagination.button.last;
    this.preLink = rebirthNGConfig.pagination.button.pre;
    this.nextLink = rebirthNGConfig.pagination.button.next;
    this.firstLinkCssClass = rebirthNGConfig.pagination.button.firstLinkCssClass;
    this.preLinkCssClass = rebirthNGConfig.pagination.button.preLinkCssClass;
    this.nextLinkCssClass = rebirthNGConfig.pagination.button.nextLinkCssClass;
    this.lastLinkCssClass = rebirthNGConfig.pagination.button.lastLinkCssClass;
    this.size = <any>rebirthNGConfig.pagination.size;
  }
  first() {
    if (this.pageIndex !== 1) {
      this.onPageIndexChange(1);
    }
  }
  last() {
    const last = Math.max(this.totalPage, 1);
    if (this.pageIndex !== last) {
      this.onPageIndexChange(last);
    }
  }
  prev(): void {
    if (this.hasPrev()) {
      this.onPageIndexChange(this.pageIndex - 1);
    }
  }
  next(): void {
    if (this.hasNext()) {
      this.onPageIndexChange(this.pageIndex + 1);
    }
  }
  preRange() {
    const pre = this.showPages[0] - 1;
    this.onPageIndexChange(Math.max(pre, 1));
  }
  nextRange() {
    const next = this.showPages[this.showPages.length - 1] + 1;
    this.onPageIndexChange(Math.min(next, this.totalPage));
  }
  onPageIndexChange(pageIndex: number) {
    if (this.pageIndex !== pageIndex) {
      this.pageIndexChange.emit(pageIndex);
    }
  }
  hasPrev(): boolean {
    return this.pageIndex > 1;
  }
  hasNext(): boolean {
    return this.pageIndex < this.totalPage;
  }
  private getTotalPage(): number {
    return Math.ceil(this.total / this.pageSize);
  }
  ngOnChanges(changes: SimpleChanges): void {
    const shouldUpdateRanges = PaginationComponent.EFFECT_PAGE_RANGE_KEYS.some(key => !!changes[key]);
    if (shouldUpdateRanges) {
      this.totalPage = this.getTotalPage();
      this.pageIndex = Math.max(Math.min(this.pageIndex, this.totalPage), 1);
      this.updateShowPageRange();
    }
  }
  private updateShowPageRange() {
    if (!this.totalPage) {
      this.showPages = [];
      return;
    }
    if (this.totalPage <= this.maxItems) {
      this.showPages = new Array<number>(this.totalPage).fill(0).map((_, i) => i + 1);
      return;
    }
    this.showPages = this.extractRange();
  }
  private extractRange() {
    const showPages = [this.pageIndex];
    let start = this.pageIndex - 1;
    let end = this.pageIndex + 1;
    const arriveLeftBound = index => index < 1;
    const arriveRightBound = (index) => index > this.totalPage;
    const fullPageRang = (pages) => pages.length >= this.maxItems;
    while (!(fullPageRang(showPages) || (arriveLeftBound(start) && arriveRightBound(end)))) {
      if (!arriveLeftBound(start)) {
        showPages.unshift((start--));
      }
      if (!fullPageRang(showPages) && !arriveRightBound(end)) {
        showPages.push(end++);
      }
    }
    return showPages;
  }
}
    <nav aria-label="Pagination" class="{{cssClass}}">
  <ng-template *ngIf="headTemplate" [ngTemplateOutlet]="headTemplate"
               [ngTemplateOutletContext]="{ $implicit: this }"></ng-template>
  <ul class="pagination {{size? 'pagination-' + size: ''}}">
    <li *ngIf="boundary" [ngClass]="{disabled: pageIndex == 1}">
      <a [attr.aria-label]="firstLink" (click)="first()">
        <span aria-hidden="true" class="{{firstLinkCssClass}}">{{firstLink}}</span></a>
    </li>
    <li [ngClass]="{disabled: pageIndex == 1}">
      <a (click)="prev()" [attr.aria-label]="preLink">
        <span aria-hidden="true" class="{{preLinkCssClass}}">{{preLink}}</span></a>
    </li>
    <li *ngIf="showPages[0] > 1" (click)="preRange()">
      <a class="ellipsis">...</a>
    </li>
    <li *ngFor="let item of showPages" [ngClass]="{active: item == pageIndex}">
      <a (click)="onPageIndexChange(item)" class="page-item">{{item}} <span class="sr-only" *ngIf="item == pageIndex">(current)</span></a>
    </li>
    <li *ngIf="showPages[showPages.length -1] < totalPage" (click)="nextRange()">
      <a class="ellipsis">...</a>
    </li>
    <li [ngClass]="{disabled: pageIndex == totalPage}">
      <a (click)="next()" [attr.aria-label]="nextLink">
        <span aria-hidden="true" class="{{nextLinkCssClass}}">{{nextLink}}</span></a>
    </li>
    <li *ngIf="boundary" [ngClass]="{disabled: pageIndex == totalPage}">
      <a [attr.aria-label]="lastLink" (click)="last()">
        <span aria-hidden="true" class="{{lastLinkCssClass}}">{{lastLink}}</span></a>
    </li>
  </ul>
  <ng-template *ngIf="tailTemplate" [ngTemplateOutlet]="tailTemplate"
               [ngTemplateOutletContext]="{ $implicit: this }"></ng-template>
</nav>