import { Component , ModuleDeclaration , L10n , EmitType , Browser } from '@syncfusion/ej2-base' ; import { createElement , remove , classList , compile as templateCompiler } from '@syncfusion/ej2-base' ; import { isNullOrUndefined } from '@syncfusion/ej2-base' ; import { Property , Event , NotifyPropertyChanges , INotifyPropertyChanged } from '@syncfusion/ej2-base' ; import { PagerModel } from './pager-model' ; import { PagerDropDown } from './pager-dropdown' ; import { NumericContainer } from './numeric-container' ; import { PagerMessage } from './pager-message' ; import { ExternalMessage } from './external-message' ; import { appendChildren } from '../grid/base/util' ; hidden export interface IRender { render ( ) : void ; refresh ( ) : void ; } /**
 * Represents the `Pager` component.
 * ```html
 * <div id="pager"/>
 * ```
 * ```typescript
 * <script>
 *   var pagerObj = new Pager({ totalRecordsCount: 50, pageSize:10 });
 *   pagerObj.appendTo("#pager");
 * </script>
 * ```
 */ @ NotifyPropertyChanges export class Pager extends Component < HTMLElement > implements INotifyPropertyChanged { /*** @hidden */ public totalPages : number ; private templateFn : Function ; /*** @hidden */ public previousPageNo : number ; private defaultConstants : Object = { currentPageInfo : '{0} of {1} pages' , totalItemsInfo : '({0} items)' , firstPageTooltip : 'Go to first page' , lastPageTooltip : 'Go to last page' , nextPageTooltip : 'Go to next page' , previousPageTooltip : 'Go to previous page' , nextPagerTooltip : 'Go to next pager' , previousPagerTooltip : 'Go to previous pager' , pagerDropDown : 'Items per page' , pagerAllDropDown : 'Items' , All : 'All' } ; /*** @hidden */ public localeObj : L10n ; /**
     * `containerModule` is used to manipulate numeric container behavior of Pager.
     */ public containerModule : NumericContainer = new NumericContainer ( this ) ; /**
     * `pagerMessageModule` is used to manipulate pager message of Pager.
     */ public pagerMessageModule : PagerMessage = new PagerMessage ( this ) ; /**
     * `externalMessageModule` is used to manipulate external message of Pager.
     */ public externalMessageModule : ExternalMessage ; hidden public pagerdropdownModule : PagerDropDown ; default @ Property ( false ) public enableQueryString : boolean ; default @ Property ( false ) public enableExternalMessage : boolean ; default @ Property ( true ) public enablePagerMessage : boolean ; default @ Property ( 12 ) public pageSize : number ; default @ Property ( 10 ) public pageCount : number ; default @ Property ( 1 ) public currentPage : number ; default @ Property ( ) public totalRecordsCount : number ; default @ Property ( ) public externalMessage : string ; default @ Property ( false ) public pageSizes : boolean | ( number | string ) [ ] ; default @ Property ( ) public template : string ; default @ Property ( '' ) public customText : string ; default @ Event ( ) public click : EmitType < Object > ; default @ Event ( ) public dropDownChanged : EmitType < Object > ; default @ Event ( ) public created : EmitType < Object > ; hidden constructor ( options ? , element ? ) { super ( options , < HTMLElement | string > element ) ; } hidden protected requiredModules ( ) { let modules = [ ] ; if ( this . enableExternalMessage ) { modules . push ( { member : 'externalMessage' , args : [ this ] } ) ; } if ( this . checkpagesizes ( ) ) { modules . push ( { member : 'pagerdropdown' , args : [ this ] } ) ; } return modules ; } hidden protected preRender ( ) { } /**
     * To Initialize the component rendering
     */ protected render ( ) { if ( this . template ) { this . pagerTemplate ( ) ; } else { this . initLocalization ( ) ; this . updateRTL ( ) ; this . totalRecordsCount = this . totalRecordsCount || 0 ; this . renderFirstPrevDivForDevice ( ) ; this . containerModule . render ( ) ; if ( this . enablePagerMessage ) { this . pagerMessageModule . render ( ) ; } this . renderNextLastDivForDevice ( ) ; if ( this . checkpagesizes ( ) && this . pagerdropdownModule ) { this . pagerdropdownModule . render ( ) ; } this . addAriaLabel ( ) ; if ( this . enableExternalMessage && this . externalMessageModule ) { this . externalMessageModule . render ( ) ; } this . refresh ( ) ; this . trigger ( 'created' , { 'currentPage' : this . currentPage , 'totalRecordsCount' : this . totalRecordsCount } ) ; } } hidden public getPersistData ( ) { let keyEntity = [ 'currentPage' , 'pageSize' ] ; return this . addOnPersist ( keyEntity ) ; } method return { void } public destroy ( ) { super . destroy ( ) ; this . containerModule . destroy ( ) ; this . pagerMessageModule . destroy ( ) ; this . element . innerHTML = '' ; } private protected getModuleName ( ) { return 'pager' ; } hidden public onPropertyChanged ( newProp , oldProp ) { if ( this . isDestroyed ) { return ; } if ( newProp . pageCount !== oldProp . pageCount ) { this . containerModule . refreshNumericLinks ( ) ; this . containerModule . refresh ( ) ; } for ( let prop of Object . keys ( newProp ) ) { switch ( prop ) { case 'currentPage' : if ( this . checkGoToPage ( newProp . currentPage , oldProp . currentPage ) ) { this . currentPageChanged ( ) ; } break ; case 'pageSize' : case 'totalRecordsCount' : case 'customText' : if ( this . checkpagesizes ( ) && this . pagerdropdownModule ) { this . pagerdropdownModule . setDropDownValue ( 'value' , this . pageSize ) ; } this . refresh ( ) ; break ; case 'pageSizes' : if ( this . checkpagesizes ( ) ) { this . pagerdropdownModule . destroy ( ) ; this . pagerdropdownModule . render ( ) ; } this . refresh ( ) ; break ; case 'template' : this . templateFn = this . compile ( this . template ) ; this . refresh ( ) ; break ; case 'locale' : this . initLocalization ( ) ; this . refresh ( ) ; break ; case 'enableExternalMessage' : if ( this . enableExternalMessage && this . externalMessageModule ) { this . externalMessageModule . render ( ) ; } break ; case 'externalMessage' : if ( this . externalMessageModule ) { this . externalMessageModule . refresh ( ) ; } break ; case 'enableRtl' : this . updateRTL ( ) ; break ; case 'enablePagerMessage' : if ( this . enablePagerMessage ) { this . pagerMessageModule . showMessage ( ) ; } else { this . pagerMessageModule . hideMessage ( ) ; } break ; } } } param { string } key return { string } public getLocalizedLabel ( key ) { return this . localeObj . getConstant ( key ) ; } param { number } pageNo return { void } public goToPage ( pageNo ) { if ( this . checkGoToPage ( pageNo ) ) { this . currentPage = pageNo ; this . dataBind ( ) ; } } private checkpagesizes ( ) { if ( this . pageSizes === true || ( < number [ ] > this . pageSizes ) . length ) { return true ; } return false ; } private checkGoToPage ( newPageNo , oldPageNo ? ) { if ( newPageNo !== this . currentPage ) { this . previousPageNo = this . currentPage ; } if ( ! isNullOrUndefined ( oldPageNo ) ) { this . previousPageNo = oldPageNo ; } if ( this . previousPageNo !== newPageNo && ( newPageNo >= 1 && newPageNo <= this . totalPages ) ) { return true ; } return false ; } private currentPageChanged ( ) { if ( this . enableQueryString ) { this . updateQueryString ( this . currentPage ) ; } let args = { currentPage : this . currentPage , cancel : false } ; this . trigger ( 'click' , args ) ; if ( ! args . cancel ) { this . refresh ( ) ; } } private pagerTemplate ( ) { let result ; this . element . classList . add ( 'e-pagertemplate' ) ; this . compile ( this . template ) ; let data = { currentPage : this . currentPage , pageSize : this . pageSize , pageCount : this . pageCount , totalRecordsCount : this . totalRecordsCount , totalPages : this . totalPages } ; result = this . getPagerTemplate ( ) ( data ) as Element [ ] ; appendChildren ( this . element , result ) ; } hidden public updateTotalPages ( ) { this . totalPages = ( this . totalRecordsCount % this . pageSize === 0 ) ? ( this . totalRecordsCount / this . pageSize ) : ( parseInt ( ( this . totalRecordsCount / this . pageSize ) . toString ( ) , 10 ) + 1 ) ; } hidden public getPagerTemplate ( ) { return this . templateFn ; } private compile ( template ) { if ( template ) { let e ; try { if ( document . querySelectorAll ( template ) . length ) { this . templateFn = templateCompiler ( document . querySelector ( template ) . innerHTML . trim ( ) ) ; } } catch ( e ) { this . templateFn = templateCompiler ( template ) ; } } return undefined ; } return { void } public refresh ( ) { if ( this . template ) { this . element . innerHTML = '' ; this . updateTotalPages ( ) ; this . pagerTemplate ( ) ; } else { this . updateRTL ( ) ; this . containerModule . refresh ( ) ; if ( this . enablePagerMessage ) { this . pagerMessageModule . refresh ( ) ; } if ( this . enableExternalMessage && this . externalMessageModule ) { this . externalMessageModule . refresh ( ) ; } } } private updateRTL ( ) { if ( this . enableRtl ) { this . element . classList . add ( 'e-rtl' ) ; } else { this . element . classList . remove ( 'e-rtl' ) ; } } private initLocalization ( ) { this . localeObj = new L10n ( this . getModuleName ( ) , this . defaultConstants , this . locale ) ; } private updateQueryString ( value ) { let updatedUrl = this . getUpdatedURL ( window . location . href , 'page' , value . toString ( ) ) ; window . history . pushState ( { path : updatedUrl } , '' , updatedUrl ) ; } private getUpdatedURL ( uri , key , value ) { let regx = new RegExp ( '([?|&])' + key + '=.*?(&|#|$)' , 'i' ) ; if ( uri . match ( regx ) ) { return uri . replace ( regx , '$1' + key + '=' + value + '$2' ) ; } else { let hash = '' ; if ( uri . indexOf ( '#' ) !== - 1 ) { hash = uri . replace ( /.*#/ , '#' ) ; uri = uri . replace ( /#.*/ , '' ) ; } return uri + ( uri . indexOf ( '?' ) !== - 1 ? '&' : '?' ) + key + '=' + value + hash ; } } private renderFirstPrevDivForDevice ( ) { this . element . appendChild ( createElement ( 'div' , { className : 'e-mfirst e-icons e-icon-first' , attrs : { title : this . getLocalizedLabel ( 'firstPageTooltip' ) , tabindex : '-1' } } ) ) ; this . element . appendChild ( createElement ( 'div' , { className : 'e-mprev e-icons e-icon-prev' , attrs : { title : this . getLocalizedLabel ( 'previousPageTooltip' ) , tabindex : '-1' } } ) ) ; } private renderNextLastDivForDevice ( ) { this . element . appendChild ( createElement ( 'div' , { className : 'e-mnext e-icons e-icon-next' , attrs : { title : this . getLocalizedLabel ( 'nextPageTooltip' ) , tabindex : '-1' } } ) ) ; this . element . appendChild ( createElement ( 'div' , { className : 'e-mlast e-icons e-icon-last' , attrs : { title : this . getLocalizedLabel ( 'lastPageTooltip' ) , tabindex : '-1' } } ) ) ; } private addAriaLabel ( ) { let classList = [ '.e-mfirst' , '.e-mprev' , '.e-mnext' , '.e-mlast' ] ; if ( ! Browser . isDevice ) { classList . forEach ( ( value ) => { let element = this . element . querySelector ( value ) ; element . setAttribute ( 'aria-label' , element . getAttribute ( 'title' ) ) ; } ) ; } } }