import { Component , ModuleDeclaration , ChildProperty , Browser , closest , extend } from '@syncfusion/ej2-base' ; import { isNullOrUndefined , setValue , getValue } from '@syncfusion/ej2-base' ; import { addClass , removeClass , append , remove , classList } from '@syncfusion/ej2-base' ; import { Property , Collection , Complex , Event , NotifyPropertyChanges , INotifyPropertyChanged , L10n } from '@syncfusion/ej2-base' ; import { EventHandler , KeyboardEvents , KeyboardEventArgs , EmitType } from '@syncfusion/ej2-base' ; import { Query , DataManager , DataUtil } from '@syncfusion/ej2-data' ; import { ItemModel , ClickEventArgs } from '@syncfusion/ej2-navigations' ; import { createSpinner , hideSpinner , showSpinner , Tooltip } from '@syncfusion/ej2-popups' ; import { GridModel } from './grid-model' ; import { iterateArrayOrObject , prepareColumns , parentsUntil , wrap , templateCompiler , refreshForeignData , getRowHeight } from './util' ; import * as events from '../base/constant' ; import { IRenderer , IValueFormatter , IFilterOperator , IIndex , RowDataBoundEventArgs , QueryCellInfoEventArgs } from './interface' ; import { CellDeselectEventArgs , CellSelectEventArgs , CellSelectingEventArgs , ParentDetails , ContextMenuItemModel } from './interface' ; import { PdfQueryCellInfoEventArgs , ExcelQueryCellInfoEventArgs , ExcelExportProperties , PdfExportProperties } from './interface' ; import { PdfHeaderQueryCellInfoEventArgs , ExcelHeaderQueryCellInfoEventArgs } from './interface' ; import { ColumnMenuOpenEventArgs , BatchCancelArgs , RecordDoubleClickEventArgs , DataResult , PendingState } from './interface' ; import { HeaderCellInfoEventArgs } from './interface' ; import { FailureEventArgs , FilterEventArgs , ColumnDragEventArgs , GroupEventArgs , PrintEventArgs , ICustomOptr } from './interface' ; import { RowDeselectEventArgs , RowSelectEventArgs , RowSelectingEventArgs , PageEventArgs , RowDragEventArgs } from './interface' ; import { BeforeBatchAddArgs , BeforeBatchDeleteArgs , BeforeBatchSaveArgs , ResizeArgs , ColumnMenuItemModel } from './interface' ; import { BatchAddArgs , BatchDeleteArgs , BeginEditArgs , CellEditArgs , CellSaveArgs , BeforeDataBoundArgs , RowInfo } from './interface' ; import { DetailDataBoundEventArgs , ColumnChooserEventArgs , AddEventArgs , SaveEventArgs , EditEventArgs , DeleteEventArgs } from './interface' ; import { ExcelExportCompleteArgs , PdfExportCompleteArgs , DataStateChangeEventArgs , DataSourceChangedEventArgs } from './interface' ; import { SearchEventArgs , SortEventArgs , ISelectedCell , EJ2Intance , BeforeCopyEventArgs , CheckBoxChangeEventArgs } from './interface' ; import { Render } from '../renderer/render' ; import { Column , ColumnModel } from '../models/column' ; import { Action , SelectionType , GridLine , RenderType , SortDirection , SelectionMode , PrintMode , FilterType , FilterBarMode } from './enum' ; import { CheckboxSelectionType } from './enum' ; import { WrapMode , ToolbarItems , ContextMenuItem , ColumnMenuItem , ToolbarItem , CellSelectionMode , EditMode } from './enum' ; import { ColumnQueryModeType } from './enum' ; import { Data } from '../actions/data' ; import { Cell } from '../models/cell' ; import { RowRenderer } from '../renderer/row-renderer' ; import { CellRenderer } from '../renderer/cell-renderer' ; import { CellRendererFactory } from '../services/cell-render-factory' ; import { ServiceLocator } from '../services/service-locator' ; import { ValueFormatter } from '../services/value-formatter' ; import { RendererFactory } from '../services/renderer-factory' ; import { ColumnWidthService } from '../services/width-controller' ; import { AriaService } from '../services/aria-service' ; import { FocusStrategy } from '../services/focus-strategy' ; import { SortSettingsModel , SelectionSettingsModel , FilterSettingsModel , SearchSettingsModel , EditSettingsModel } from './grid-model' ; import { SortDescriptorModel , PredicateModel , RowDropSettingsModel , GroupSettingsModel , TextWrapSettingsModel } from './grid-model' ; import { PageSettingsModel , AggregateRowModel } from '../models/models' ; import { PageSettings } from '../models/page-settings' ; import { Sort } from '../actions/sort' ; import { Page } from '../actions/page' ; import { Selection } from '../actions/selection' ; import { Filter } from '../actions/filter' ; import { Search } from '../actions/search' ; import { Resize } from '../actions/resize' ; import { Reorder } from '../actions/reorder' ; import { RowDD } from '../actions/row-reorder' ; import { ShowHide } from '../actions/show-hide' ; import { Scroll } from '../actions/scroll' ; import { Group } from '../actions/group' ; import { Print } from '../actions/print' ; import { DetailRow } from '../actions/detail-row' ; import { Toolbar } from '../actions/toolbar' ; import { AggregateRow } from '../models/aggregate' ; import { Edit } from '../actions/edit' ; import { Row } from '../models/row' ; import { ColumnChooser } from '../actions/column-chooser' ; import { ExcelExport } from '../actions/excel-export' ; import { PdfExport } from '../actions/pdf-export' ; import { Clipboard } from '../actions/clipboard' ; import { CommandColumn } from '../actions/command-column' ; import { ContextMenu } from '../actions/context-menu' ; import { BeforeOpenCloseMenuEventArgs , MenuEventArgs } from '@syncfusion/ej2-navigations' ; import { ColumnMenu } from '../actions/column-menu' ; import { CheckState } from './enum' ; /**
 * Represents the field name and direction of sort column.
 */ export class SortDescriptor extends ChildProperty < SortDescriptor > { default @ Property ( ) public field : string ; default @ Property ( ) public direction : SortDirection ; } /**
 * Configures the sorting behavior of Grid.
 */ export class SortSettings extends ChildProperty < SortSettings > { default @ Collection < SortDescriptorModel > ( [ ] , SortDescriptor ) public columns : SortDescriptorModel [ ] ; default @ Property ( true ) public allowUnsort : boolean ; } /**
 * Represents the predicate for the filter column.
 */ export class Predicate extends ChildProperty < Predicate > { default @ Property ( ) public field : string ; default @ Property ( ) public operator : string ; default @ Property ( ) public value : string | number | Date | boolean ; default @ Property ( ) public matchCase : boolean ; default @ Property ( ) public ignoreAccent : boolean ; default @ Property ( ) public predicate : string ; hidden @ Property ( { } ) public actualFilterValue : Object ; hidden @ Property ( { } ) public actualOperator : Object ; hidden @ Property ( ) public type : string ; hidden @ Property ( ) public ejpredicate : Object ; } /**
 * Configures the filtering behavior of the Grid.
 */ export class FilterSettings extends ChildProperty < FilterSettings > { default @ Collection < PredicateModel [ ] > ( [ ] , Predicate ) public columns : PredicateModel [ ] ; default @ Property ( 'FilterBar' ) public type : FilterType ; default @ Property ( ) public mode : FilterBarMode ; default @ Property ( true ) public showFilterBarStatus : boolean ; default @ Property ( 1500 ) public immediateModeDelay : number ; default @ Property ( ) public operators : ICustomOptr ; default @ Property ( false ) public ignoreAccent : boolean ; } /**
 * Configures the selection behavior of the Grid.
 */ export class SelectionSettings extends ChildProperty < SelectionSettings > { default @ Property ( 'Row' ) public mode : SelectionMode ; default @ Property ( 'Flow' ) public cellSelectionMode : CellSelectionMode ; default @ Property ( 'Single' ) public type : SelectionType ; default @ Property ( false ) public checkboxOnly : boolean ; default @ Property ( false ) public persistSelection : boolean ; default @ Property ( 'Default' ) public checkboxMode : CheckboxSelectionType ; } /**
 * Configures the search behavior of the Grid.
 */ export class SearchSettings extends ChildProperty < SearchSettings > { default @ Property ( [ ] ) public fields : string [ ] ; default @ Property ( '' ) public key : string ; default @ Property ( 'contains' ) public operator : string ; default @ Property ( true ) public ignoreCase : boolean ; default @ Property ( false ) public ignoreAccent : boolean ; } /**
 * Configures the row drop settings of the Grid.
 */ export class RowDropSettings extends ChildProperty < RowDropSettings > { default @ Property ( ) public targetID : string ; } /**
 * Configures the text wrap settings of the Grid.
 */ export class TextWrapSettings extends ChildProperty < TextWrapSettings > { default @ Property ( 'Both' ) public wrapMode : WrapMode ; } /**
 * Configures the group behavior of the Grid.
 */ export class GroupSettings extends ChildProperty < GroupSettings > { default @ Property ( true ) public showDropArea : boolean ; default @ Property ( false ) public showToggleButton : boolean ; default @ Property ( false ) public showGroupedColumn : boolean ; default @ Property ( true ) public showUngroupButton : boolean ; default @ Property ( false ) public disablePageWiseAggregates : boolean ; default @ Property ( [ ] ) public columns : string [ ] ; default @ Property ( ) public captionTemplate : string ; } /**
 * Configures the edit behavior of the Grid.
 */ export class EditSettings extends ChildProperty < EditSettings > { default @ Property ( false ) public allowAdding : boolean ; default @ Property ( false ) public allowEditing : boolean ; default @ Property ( false ) public allowDeleting : boolean ; default @ Property ( 'Normal' ) public mode : EditMode ; default @ Property ( true ) public allowEditOnDblClick : boolean ; default @ Property ( true ) public showConfirmDialog : boolean ; default @ Property ( false ) public showDeleteConfirmDialog : boolean ; default @ Property ( '' ) public template : string ; } /**
 * Represents the Grid component.
 * ```html
 * <div id="grid"></div>
 * <script>
 *  var gridObj = new Grid({ allowPaging: true });
 *  gridObj.appendTo("#grid");
 * </script>
 * ```
 */ @ NotifyPropertyChanges export class Grid extends Component < HTMLElement > implements INotifyPropertyChanged { private gridPager : Element ; private isInitial : boolean ; public isPreventScrollEvent : boolean = false ; private columnModel : Column [ ] ; private rowTemplateFn : Function ; private editTemplateFn : Function ; private detailTemplateFn : Function ; private sortedColumns : string [ ] ; private footerElement : Element ; private inViewIndexes : number [ ] = [ ] ; private mediaCol : Column [ ] ; private getShowHideService : ShowHide ; private mediaColumn : Column [ ] ; private isInitialLoad : boolean ; private dataBoundFunction : Function ; private freezeRefresh : Function = Component . prototype . refresh ; hidden public recordsCount : number ; hidden public mergeCells : { [ key ] : number ; } ; hidden public checkAllRows : CheckState ; hidden public isCheckBoxSelection : boolean ; hidden public isPersistSelection : boolean ; /**
     * Gets the currently visible records of the Grid.
     */ public currentViewData : Object [ ] = [ ] ; hidden public parentDetails : ParentDetails ; hidden public currentAction : Action ; hidden public isEdit : boolean ; hidden public isLastCellPrimaryKey : boolean ; hidden public filterOperators : IFilterOperator ; hidden public localeObj : L10n ; private defaultLocale : Object ; private keyConfigs : { [ key ] : string ; } ; private toolTipObj : Tooltip ; private keyPress : boolean ; private stackedColumn : Column ; hidden public prevPageMoving : boolean = false ; hidden public renderModule : Render ; hidden public headerModule : IRenderer ; hidden public contentModule : IRenderer ; hidden public valueFormatterService : IValueFormatter ; hidden public serviceLocator : ServiceLocator ; hidden public ariaService : AriaService ; /**
     * The `keyboardModule` is used to manipulate keyboard interactions in the Grid.
     */ public keyboardModule : KeyboardEvents ; hidden public widthService : ColumnWidthService ; /**
     * The `rowDragAndDropModule` is used to manipulate row reordering in the Grid.
     */ public rowDragAndDropModule : RowDD ; /**
     * The `pagerModule` is used to manipulate paging in the Grid.
     */ public pagerModule : Page ; /**
     * The `sortModule` is used to manipulate sorting in the Grid.
     */ public sortModule : Sort ; /**
     * The `filterModule` is used to manipulate filtering in the Grid.
     */ public filterModule : Filter ; /**
     * The `selectionModule` is used to manipulate selection behavior in the Grid.
     */ public selectionModule : Selection ; /**
     * The `showHider` is used to manipulate column's show/hide operation in the Grid.
     */ public showHider : ShowHide ; /**
     * The `searchModule` is used to manipulate searching in the Grid.
     */ public searchModule : Search ; /**
     * The `scrollModule` is used to manipulate scrolling in the Grid.
     */ public scrollModule : Scroll ; /**
     * The `reorderModule` is used to manipulate reordering in the Grid.
     */ public reorderModule : Reorder ; hidden public resizeModule : Resize ; /**
     * The `groupModule` is used to manipulate grouping behavior in the Grid.
     */ public groupModule : Group ; /**
     * The `printModule` is used to handle the printing feature of the Grid.
     */ public printModule : Print ; /**
     * The `excelExportModule` is used to handle Excel exporting feature in the Grid.
     */ public excelExportModule : ExcelExport ; /**
     * The `pdfExportModule` is used to handle PDF exporting feature in the Grid.
     */ public pdfExportModule : PdfExport ; hidden public detailRowModule : DetailRow ; /**
     * The `toolbarModule` is used to manipulate ToolBar items and its action in the Grid.
     */ public toolbarModule : Toolbar ; /**
     * The `contextMenuModule` is used to handle context menu items and its action in the Grid.
     */ public contextMenuModule : ContextMenu ; /**
     * The `columnMenuModule` is used to manipulate column menu items and its action in the Grid.
     */ public columnMenuModule : ColumnMenu ; /**
     * The `editModule` is used to handle Grid content manipulation.
     */ public editModule : Edit ; /**
     * `clipboardModule` is used to handle Grid copy action.
     */ public clipboardModule : Clipboard ; hidden public columnChooserModule : ColumnChooser ; private commandColumnModule : CommandColumn ; private focusModule : FocusStrategy ; protected needsID : boolean = true ; default @ Property ( [ ] ) public columns : Column [ ] | string [ ] | ColumnModel [ ] ; default @ Property ( true ) public enableAltRow : boolean ; default @ Property ( true ) public enableHover : boolean ; hidden default @ Property ( true ) public allowKeyboard : boolean ; default @ Property ( false ) public allowTextWrap : boolean ; default @ Complex < TextWrapSettingsModel > ( { } , TextWrapSettings ) public textWrapSettings : TextWrapSettingsModel ; default @ Property ( false ) public allowPaging : boolean ; default @ Complex < PageSettingsModel > ( { } , PageSettings ) public pageSettings : PageSettingsModel ; default @ Property ( false ) public enableVirtualization : boolean ; default @ Property ( false ) public enableColumnVirtualization : boolean ; default @ Complex < SearchSettingsModel > ( { } , SearchSettings ) public searchSettings : SearchSettingsModel ; default @ Property ( false ) public allowSorting : boolean ; default @ Property ( true ) public allowMultiSorting : boolean ; default @ Property ( false ) public allowExcelExport : boolean ; default @ Property ( false ) public allowPdfExport : boolean ; default @ Complex < SortSettingsModel > ( { } , SortSettings ) public sortSettings : SortSettingsModel ; default @ Property ( true ) public allowSelection : boolean ; default @ Property ( - 1 ) public selectedRowIndex : number ; default @ Complex < SelectionSettingsModel > ( { } , SelectionSettings ) public selectionSettings : SelectionSettingsModel ; default @ Property ( false ) public allowFiltering : boolean ; default @ Property ( false ) public allowReordering : boolean ; default @ Property ( false ) public allowResizing : boolean ; default @ Property ( false ) public allowRowDragAndDrop : boolean ; default @ Complex < RowDropSettingsModel > ( { } , RowDropSettings ) public rowDropSettings : RowDropSettingsModel ; default @ Complex < FilterSettingsModel > ( { } , FilterSettings ) public filterSettings : FilterSettingsModel ; default @ Property ( false ) public allowGrouping : boolean ; default @ Property ( false ) public showColumnMenu : boolean ; default @ Complex < GroupSettingsModel > ( { } , GroupSettings ) public groupSettings : GroupSettingsModel ; default @ Complex < EditSettingsModel > ( { } , EditSettings ) public editSettings : EditSettingsModel ; default @ Collection < AggregateRowModel > ( [ ] , AggregateRow ) public aggregates : AggregateRowModel [ ] ; default @ Property ( false ) public showColumnChooser : boolean ; default @ Property ( 'auto' ) public height : string | number ; default @ Property ( 'auto' ) public width : string | number ; default @ Property ( 'Default' ) public gridLines : GridLine ; /**
     * The row template that renders customized rows from the given template.
     * By default, Grid renders a table row for every data source item.
     * > * It accepts either [template string](../common/template-engine.html) or HTML element ID.
     * > * The row template must be a table row.
     *
     * > Check the [`Row Template`](./row.html) customization.
     */ @ Property ( ) public rowTemplate : string ; /**
     * The detail template allows you to show or hide additional information about a particular row.
     *
     * > It accepts either the [template string](../common/template-engine.html) or the HTML element ID.
     *
     * {% codeBlock src="grid/detail-template-api/index.ts" %}{% endcodeBlock %}
     */ @ Property ( ) public detailTemplate : string ; /**
     * Defines Grid options to render child Grid.
     * It requires the [`queryString`](./api-grid.html#querystring-string) for parent
     * and child relationship.
     *
     * > Check the [`Child Grid`](./hierarchy-grid.html) for its configuration.
     */ @ Property ( ) public childGrid : GridModel ; /**
     * Defines the relationship between parent and child datasource. It acts as the foreign key for parent datasource.
     */ @ Property ( ) public queryString : string ; default @ Property ( 'AllPages' ) public printMode : PrintMode ; default @ Property ( [ ] ) public dataSource : Object | DataManager | DataResult ; default @ Property ( null ) public rowHeight : number ; default @ Property ( ) public query : Query ; private @ Property ( 'USD' ) private currencyCode : string ; default @ Property ( ) public toolbar : ( ToolbarItems | string | ItemModel | ToolbarItem ) [ ] ; default @ Property ( ) public contextMenuItems : ContextMenuItem [ ] | ContextMenuItemModel [ ] ; default @ Property ( ) public columnMenuItems : ColumnMenuItem [ ] | ColumnMenuItemModel [ ] ; hidden default @ Property ( ) public toolbarTemplate : string ; hidden default @ Property ( ) public pagerTemplate : string ; default @ Property ( 0 ) public frozenRows : number ; default @ Property ( 0 ) public frozenColumns : number ; default @ Property ( 'All' ) public columnQueryMode : ColumnQueryModeType ; event @ Event ( ) public created : EmitType < Object > ; event @ Event ( ) public destroyed : EmitType < Object > ; event @ Event ( ) public load : EmitType < Object > ; event @ Event ( ) public rowDataBound : EmitType < RowDataBoundEventArgs > ; event @ Event ( ) public queryCellInfo : EmitType < QueryCellInfoEventArgs > ; event @ Event ( ) public headerCellInfo : EmitType < HeaderCellInfoEventArgs > ; event @ Event ( ) public actionBegin : EmitType < PageEventArgs | GroupEventArgs | FilterEventArgs | SearchEventArgs | SortEventArgs | AddEventArgs | SaveEventArgs | EditEventArgs | DeleteEventArgs > ; event @ Event ( ) public actionComplete : EmitType < PageEventArgs | GroupEventArgs | FilterEventArgs | SearchEventArgs | SortEventArgs | AddEventArgs | SaveEventArgs | EditEventArgs | DeleteEventArgs > ; event @ Event ( ) public actionFailure : EmitType < FailureEventArgs > ; event @ Event ( ) public dataBound : EmitType < Object > ; event @ Event ( ) public recordDoubleClick : EmitType < RecordDoubleClickEventArgs > ; event @ Event ( ) public rowSelecting : EmitType < RowSelectingEventArgs > ; event @ Event ( ) public rowSelected : EmitType < RowSelectEventArgs > ; event @ Event ( ) public rowDeselecting : EmitType < RowDeselectEventArgs > ; event @ Event ( ) public rowDeselected : EmitType < RowDeselectEventArgs > ; event @ Event ( ) public cellSelecting : EmitType < CellSelectingEventArgs > ; event @ Event ( ) public cellSelected : EmitType < CellSelectEventArgs > ; event @ Event ( ) public cellDeselecting : EmitType < CellDeselectEventArgs > ; event @ Event ( ) public cellDeselected : EmitType < CellDeselectEventArgs > ; event @ Event ( ) public columnDragStart : EmitType < ColumnDragEventArgs > ; event @ Event ( ) public columnDrag : EmitType < ColumnDragEventArgs > ; event @ Event ( ) public columnDrop : EmitType < ColumnDragEventArgs > ; event @ Event ( ) public printComplete : EmitType < PrintEventArgs > ; event @ Event ( ) public beforePrint : EmitType < PrintEventArgs > ; event @ Event ( ) public pdfQueryCellInfo : EmitType < PdfQueryCellInfoEventArgs > ; event @ Event ( ) public pdfHeaderQueryCellInfo : EmitType < PdfHeaderQueryCellInfoEventArgs > ; event @ Event ( ) public excelQueryCellInfo : EmitType < ExcelQueryCellInfoEventArgs > ; event @ Event ( ) public excelHeaderQueryCellInfo : EmitType < ExcelHeaderQueryCellInfoEventArgs > ; event @ Event ( ) public beforeExcelExport : EmitType < Object > ; event @ Event ( ) public excelExportComplete : EmitType < ExcelExportCompleteArgs > ; event @ Event ( ) public beforePdfExport : EmitType < Object > ; event @ Event ( ) public pdfExportComplete : EmitType < PdfExportCompleteArgs > ; event @ Event ( ) public detailDataBound : EmitType < DetailDataBoundEventArgs > ; event @ Event ( ) public rowDragStart : EmitType < RowDragEventArgs > ; event @ Event ( ) public rowDrag : EmitType < RowDragEventArgs > ; event @ Event ( ) public rowDrop : EmitType < RowDragEventArgs > ; event @ Event ( ) public toolbarClick : EmitType < ClickEventArgs > ; event @ Event ( ) public beforeOpenColumnChooser : EmitType < ColumnChooserEventArgs > ; event @ Event ( ) public batchAdd : EmitType < BatchAddArgs > ; event @ Event ( ) public batchDelete : EmitType < BatchDeleteArgs > ; event @ Event ( ) public batchCancel : EmitType < BatchCancelArgs > ; event @ Event ( ) public beforeBatchAdd : EmitType < BeforeBatchAddArgs > ; event @ Event ( ) public beforeBatchDelete : EmitType < BeforeBatchDeleteArgs > ; event @ Event ( ) public beforeBatchSave : EmitType < BeforeBatchSaveArgs > ; event @ Event ( ) public beginEdit : EmitType < BeginEditArgs > ; event @ Event ( ) public cellEdit : EmitType < CellEditArgs > ; event @ Event ( ) public cellSave : EmitType < CellSaveArgs > ; event @ Event ( ) public cellSaved : EmitType < CellSaveArgs > ; event @ Event ( ) public resizeStart : EmitType < ResizeArgs > ; event @ Event ( ) public resizing : EmitType < ResizeArgs > ; event @ Event ( ) public resizeStop : EmitType < ResizeArgs > ; event @ Event ( ) public beforeDataBound : EmitType < BeforeDataBoundArgs > ; event @ Event ( ) public contextMenuOpen : EmitType < BeforeOpenCloseMenuEventArgs > ; event @ Event ( ) public contextMenuClick : EmitType < MenuEventArgs > ; event @ Event ( ) public columnMenuOpen : EmitType < ColumnMenuOpenEventArgs > ; event @ Event ( ) public columnMenuClick : EmitType < MenuEventArgs > ; event @ Event ( ) public checkBoxChange : EmitType < CheckBoxChangeEventArgs > ; event @ Event ( ) public beforeCopy : EmitType < BeforeCopyEventArgs > ; event @ Event ( ) public dataStateChange : EmitType < DataStateChangeEventArgs > ; event @ Event ( ) public dataSourceChanged : EmitType < DataSourceChangedEventArgs > ; hidden constructor ( options ? , element ? ) { super ( options , < HTMLElement | string > element ) ; setValue ( 'mergePersistData' , this . mergePersistGridData , this ) ; } return { string } hidden public getPersistData ( ) { let keyEntity = [ 'pageSettings' , 'sortSettings' , 'filterSettings' , 'groupSettings' , 'columns' , 'searchSettings' , 'selectedRowIndex' ] ; let ignoreOnPersist = { pageSettings : [ 'template' , 'pageSizes' , 'enableQueryString' , 'totalRecordsCount' , 'pageCount' ] , filterSettings : [ 'type' , 'mode' , 'showFilterBarStatus' , 'immediateModeDelay' , 'ignoreAccent' ] , groupSettings : [ 'showDropArea' , 'showToggleButton' , 'showGroupedColumn' , 'showUngroupButton' , 'disablePageWiseAggregates' , 'hideCaptionCount' ] , searchSettings : [ 'fields' , 'operator' , 'ignoreCase' ] , sortSettings : [ ] , columns : [ ] , selectedRowIndex : [ ] } ; let ignoreOnColumn = [ 'filter' , 'edit' , 'filterBarTemplate' , 'headerTemplate' , 'template' , 'commandTemplate' , 'commands' , 'dataSource' ] ; keyEntity . forEach ( ( value ) => { let currentObject = this [ value ] ; for ( let val of ignoreOnPersist [ value ] ) { delete currentObject [ val ] ; } } ) ; this . ignoreInArrays ( ignoreOnColumn , < Column [ ] > this . columns ) ; return this . addOnPersist ( keyEntity ) ; } private ignoreInArrays ( ignoreOnColumn , columns ) { columns . forEach ( ( column ) => { if ( column . columns ) { this . ignoreInColumn ( ignoreOnColumn , column ) ; this . ignoreInArrays ( ignoreOnColumn , < Column [ ] > column . columns ) ; } else { this . ignoreInColumn ( ignoreOnColumn , column ) ; } } ) ; } private ignoreInColumn ( ignoreOnColumn , column ) { ignoreOnColumn . forEach ( ( val ) => { delete column [ val ] ; column . filter = { } ; } ) ; } return { ModuleDeclaration [ ] } hidden public requiredModules ( ) { let modules = [ ] ; if ( this . isDestroyed ) { return modules ; } if ( this . allowFiltering ) { modules . push ( { member : 'filter' , args : [ this , this . filterSettings , this . serviceLocator ] } ) ; } if ( this . allowExcelExport ) { modules . push ( { member : 'ExcelExport' , args : [ this ] } ) ; } if ( this . allowPdfExport ) { modules . push ( { member : 'PdfExport' , args : [ this ] } ) ; } if ( this . allowSorting ) { modules . push ( { member : 'sort' , args : [ this , this . sortSettings , this . sortedColumns , this . serviceLocator ] } ) ; } if ( this . allowPaging ) { modules . push ( { member : 'pager' , args : [ this , this . pageSettings ] } ) ; } if ( this . allowSelection ) { modules . push ( { member : 'selection' , args : [ this , this . selectionSettings , this . serviceLocator ] } ) ; } modules . push ( { member : 'resize' , args : [ this ] } ) ; if ( this . allowReordering ) { modules . push ( { member : 'reorder' , args : [ this ] } ) ; } if ( this . allowRowDragAndDrop ) { modules . push ( { member : 'rowDragAndDrop' , args : [ this ] } ) ; } if ( this . allowGrouping ) { modules . push ( { member : 'group' , args : [ this , this . groupSettings , this . sortedColumns , this . serviceLocator ] } ) ; } if ( this . aggregates . length ) { modules . push ( { member : 'aggregate' , args : [ this , this . serviceLocator ] } ) ; } if ( this . isDetail ( ) ) { modules . push ( { member : 'detailRow' , args : [ this , this . serviceLocator ] } ) ; } if ( this . toolbar || this . toolbarTemplate ) { modules . push ( { member : 'toolbar' , args : [ this , this . serviceLocator ] } ) ; } if ( this . enableVirtualization || this . enableColumnVirtualization ) { modules . push ( { member : 'virtualscroll' , args : [ this , this . serviceLocator ] } ) ; } if ( this . getFrozenColumns ( ) || this . frozenRows ) { modules . push ( { member : 'freeze' , args : [ this , this . serviceLocator ] } ) ; } if ( this . isCommandColumn ( < Column [ ] > this . columns ) ) { modules . push ( { member : 'commandColumn' , args : [ this , this . serviceLocator ] } ) ; } if ( this . editSettings . allowAdding || this . editSettings . allowDeleting || this . editSettings . allowEditing ) { modules . push ( { member : 'edit' , args : [ this , this . serviceLocator ] } ) ; } this . extendRequiredModules ( modules ) ; return modules ; } public extendRequiredModules ( modules ) { if ( this . contextMenuItems ) { modules . push ( { member : 'contextMenu' , args : [ this , this . serviceLocator ] } ) ; } if ( this . showColumnMenu ) { modules . push ( { member : 'columnMenu' , args : [ this , this . serviceLocator ] } ) ; } if ( this . showColumnChooser ) { modules . push ( { member : 'columnChooser' , args : [ this , this . serviceLocator ] } ) ; } if ( this . isForeignKeyEnabled ( this . columns as Column [ ] ) ) { modules . push ( { member : 'foreignKey' , args : [ this , this . serviceLocator ] } ) ; } } private protected preRender ( ) { this . serviceLocator = new ServiceLocator ; this . initProperties ( ) ; this . initializeServices ( ) ; } private initProperties ( ) { this . isInitial = true ; this . sortedColumns = [ ] ; this . inViewIndexes = [ ] ; this . mediaCol = [ ] ; this . isInitialLoad = false ; this . mergeCells = { } ; this . isEdit = false ; this . checkAllRows = 'None' ; this . isCheckBoxSelection = false ; this . isPersistSelection = false ; this . freezeRefresh = Component . prototype . refresh ; this . filterOperators = { contains : 'contains' , endsWith : 'endswith' , equal : 'equal' , greaterThan : 'greaterthan' , greaterThanOrEqual : 'greaterthanorequal' , lessThan : 'lessthan' , lessThanOrEqual : 'lessthanorequal' , notEqual : 'notequal' , startsWith : 'startswith' } ; this . defaultLocale = { EmptyRecord : 'No records to display' , True : 'true' , False : 'false' , InvalidFilterMessage : 'Invalid Filter Data' , GroupDropArea : 'Drag a column header here to group its column' , UnGroup : 'Click here to ungroup' , GroupDisable : 'Grouping is disabled for this column' , FilterbarTitle : '\'s filter bar cell' , EmptyDataSourceError : 'DataSource must not be empty at initial load since columns are generated from dataSource in AutoGenerate Column Grid' , Add : 'Add' , Edit : 'Edit' , Cancel : 'Cancel' , Update : 'Update' , Delete : 'Delete' , Print : 'Print' , Pdfexport : 'PDF Export' , Excelexport : 'Excel Export' , Wordexport : 'Word Export' , Csvexport : 'CSV Export' , Search : 'Search' , Columnchooser : 'Columns' , Save : 'Save' , Item : 'item' , Items : 'items' , EditOperationAlert : 'No records selected for edit operation' , DeleteOperationAlert : 'No records selected for delete operation' , SaveButton : 'Save' , OKButton : 'OK' , CancelButton : 'Cancel' , EditFormTitle : 'Details of ' , AddFormTitle : 'Add New Record' , BatchSaveConfirm : 'Are you sure you want to save changes?' , BatchSaveLostChanges : 'Unsaved changes will be lost. Are you sure you want to continue?' , ConfirmDelete : 'Are you sure you want to Delete Record?' , CancelEdit : 'Are you sure you want to Cancel the changes?' , ChooseColumns : 'Choose Column' , SearchColumns : 'search columns' , Matchs : 'No Matches Found' , FilterButton : 'Filter' , ClearButton : 'Clear' , StartsWith : 'Starts With' , EndsWith : 'Ends With' , Contains : 'Contains' , Equal : 'Equal' , NotEqual : 'Not Equal' , LessThan : 'Less Than' , LessThanOrEqual : 'Less Than Or Equal' , GreaterThan : 'Greater Than' , GreaterThanOrEqual : 'Greater Than Or Equal' , ChooseDate : 'Choose a Date' , EnterValue : 'Enter the value' , Copy : 'Copy' , Group : 'Group by this column' , Ungroup : 'Ungroup by this column' , autoFitAll : 'Auto Fit all columns' , autoFit : 'Auto Fit this column' , Export : 'Export' , FirstPage : 'First Page' , LastPage : 'Last Page' , PreviousPage : 'Previous Page' , NextPage : 'Next Page' , SortAscending : 'Sort Ascending' , SortDescending : 'Sort Descending' , EditRecord : 'Edit Record' , DeleteRecord : 'Delete Record' , FilterMenu : 'Filter' , SelectAll : 'Select All' , Blanks : 'Blanks' , FilterTrue : 'True' , FilterFalse : 'False' , NoResult : 'No Matches Found' , ClearFilter : 'Clear Filter' , NumberFilter : 'Number Filters' , TextFilter : 'Text Filters' , DateFilter : 'Date Filters' , DateTimeFilter : 'DateTime Filters' , MatchCase : 'Match Case' , Between : 'Between' , CustomFilter : 'Custom Filter' , CustomFilterPlaceHolder : 'Enter the value' , CustomFilterDatePlaceHolder : 'Choose a date' , AND : 'AND' , OR : 'OR' , ShowRowsWhere : 'Show rows where:' } ; this . keyConfigs = { downArrow : 'downarrow' , upArrow : 'uparrow' , rightArrow : 'rightarrow' , leftArrow : 'leftarrow' , shiftDown : 'shift+downarrow' , shiftUp : 'shift+uparrow' , shiftRight : 'shift+rightarrow' , shiftLeft : 'shift+leftarrow' , home : 'home' , end : 'end' , escape : 'escape' , ctrlHome : 'ctrl+home' , ctrlEnd : 'ctrl+end' , pageUp : 'pageup' , pageDown : 'pagedown' , ctrlAltPageUp : 'ctrl+alt+pageup' , ctrlAltPageDown : 'ctrl+alt+pagedown' , altPageUp : 'alt+pageup' , altPageDown : 'alt+pagedown' , altDownArrow : 'alt+downarrow' , altUpArrow : 'alt+uparrow' , ctrlDownArrow : 'ctrl+downarrow' , ctrlUpArrow : 'ctrl+uparrow' , ctrlPlusA : 'ctrl+A' , ctrlPlusP : 'ctrl+P' , insert : 'insert' , delete : 'delete' , f2 : 'f2' , enter : 'enter' , ctrlEnter : 'ctrl+enter' , shiftEnter : 'shift+enter' , tab : 'tab' , shiftTab : 'shift+tab' , space : 'space' , ctrlPlusC : 'ctrl+C' , ctrlShiftPlusH : 'ctrl+shift+H' } ; } private protected render ( ) { this . ariaService . setOptions ( this . element , { role : 'grid' } ) ; createSpinner ( { target : this . element } , this . createElement ) ; this . renderModule = new Render ( this , this . serviceLocator ) ; this . getMediaColumns ( ) ; this . searchModule = new Search ( this ) ; this . scrollModule = new Scroll ( this ) ; this . notify ( events . initialLoad , { } ) ; this . trigger ( events . load ) ; prepareColumns ( this . columns as Column [ ] , this . enableColumnVirtualization ) ; this . getColumns ( ) ; this . processModel ( ) ; this . gridRender ( ) ; this . wireEvents ( ) ; this . addListener ( ) ; this . updateDefaultCursor ( ) ; this . updateStackedFilter ( ) ; this . showSpinner ( ) ; this . notify ( events . initialEnd , { } ) ; } /**
     * By default, grid shows the spinner for all its actions. You can use this method to show spinner at your needed time.
     */ public showSpinner ( ) { showSpinner ( this . element ) ; } /**
     * Manually showed spinner needs to hide by `hideSpinnner`.
     */ public hideSpinner ( ) { hideSpinner ( this . element ) ; } private updateStackedFilter ( ) { if ( this . allowFiltering && this . filterSettings . type === 'FilterBar' && this . getHeaderContent ( ) . querySelectorAll ( '.e-stackedheadercell' ) . length ) { this . getHeaderContent ( ) . classList . add ( 'e-stackedfilter' ) ; } else { this . getHeaderContent ( ) . classList . remove ( 'e-stackedfilter' ) ; } } private getMediaColumns ( ) { if ( ! this . enableColumnVirtualization ) { let gcol = this . getColumns ( ) ; this . getShowHideService = this . serviceLocator . getService < ShowHide > ( 'showHideService' ) ; if ( ! isNullOrUndefined ( gcol ) ) { for ( let index = 0 ; index < gcol . length ; index ++ ) { if ( ! isNullOrUndefined ( gcol [ index ] . hideAtMedia ) ) { this . mediaCol . push ( gcol [ index ] ) ; let media = window . matchMedia ( gcol [ index ] . hideAtMedia ) ; this . mediaQueryUpdate ( index , media ) ; media . addListener ( this . mediaQueryUpdate . bind ( this , index ) ) ; } } } } } hidden public mediaQueryUpdate ( columnIndex , e ? ) { let col = this . getColumns ( ) [ columnIndex ] ; col . visible = e . matches ; if ( this . isInitialLoad ) { if ( col . visible ) { this . showHider . show ( col . headerText , 'headerText' ) ; } else { this . showHider . hide ( col . headerText , 'headerText' ) ; } } } private refreshMediaCol ( ) { this . isInitialLoad = true ; if ( this . aggregates . length && this . element . scrollHeight > this . height ) { let footerContent = this . element . querySelector ( '.e-gridfooter' ) ; addClass ( [ footerContent ] , [ 'e-footerpadding' ] ) ; } let checkboxColumn = this . getColumns ( ) . filter ( ( col ) => col . type === 'checkbox' ) ; if ( checkboxColumn . length && this . selectionSettings . checkboxMode === 'ResetOnRowClick' ) { this . isCheckBoxSelection = false ; this . refreshHeader ( ) ; } } private protected eventInitializer ( ) { } method return { void } public destroy ( ) { let gridElement = this . element ; if ( ! gridElement ) { return ; } let hasGridChild = gridElement . querySelector ( '.e-gridheader' ) && gridElement . querySelector ( '.e-gridcontent' ) ? true : false ; if ( hasGridChild ) { this . unwireEvents ( ) ; } this . removeListener ( ) ; this . notify ( events . destroy , { } ) ; this . destroyDependentModules ( ) ; if ( hasGridChild ) { super . destroy ( ) ; } this . toolTipObj . destroy ( ) ; let modules = [ 'renderModule' , 'headerModule' , 'contentModule' , 'valueFormatterService' , 'serviceLocator' , 'ariaService' , 'keyboardModule' , 'widthService' , 'searchModule' , 'showHider' , 'scrollModule' , 'printModule' , 'clipboardModule' , 'focusModule' ] ; for ( let i = 0 ; i < modules . length ; i ++ ) { if ( this [ modules [ i ] ] ) { this [ modules [ i ] ] = null ; } } this . element . innerHTML = '' ; classList ( this . element , [ ] , [ 'e-rtl' , 'e-gridhover' , 'e-responsive' , 'e-default' , 'e-device' , 'e-grid-min-height' ] ) ; } private destroyDependentModules ( ) { let gridElement = this . element ; if ( ! gridElement || ( ! gridElement . querySelector ( '.e-gridheader' ) && ! gridElement . querySelector ( '.e-gridcontent' ) ) ) { return ; } this . scrollModule . destroy ( ) ; this . keyboardModule . destroy ( ) ; this . focusModule . destroy ( ) ; } private protected getModuleName ( ) { return 'grid' ; } hidden public onPropertyChanged ( newProp , oldProp ) { let requireRefresh = false ; let requireGridRefresh = false ; let freezeRefresh = false ; let checkCursor ; let args = { requestType : 'refresh' } ; if ( this . isDestroyed ) { return ; } let properties = Object . keys ( newProp ) ; if ( properties . indexOf ( 'columns' ) > - 1 ) { this . updateColumnObject ( ) ; requireGridRefresh = true ; } for ( let prop of properties ) { switch ( prop ) { case 'allowPaging' : this . notify ( events . uiUpdate , { module : 'pager' , enable : this . allowPaging } ) ; requireRefresh = true ; break ; case 'pageSettings' : this . notify ( events . inBoundModelChanged , { module : 'pager' , properties : newProp . pageSettings } ) ; if ( isNullOrUndefined ( newProp . pageSettings . currentPage ) && isNullOrUndefined ( newProp . pageSettings . totalRecordsCount ) || ! isNullOrUndefined ( oldProp . pageSettings ) && ( ( newProp . pageSettings . currentPage !== oldProp . pageSettings . currentPage ) && ! this . enableColumnVirtualization && ! this . enableVirtualization && this . pageSettings . totalRecordsCount <= this . pageSettings . pageSize ) ) { requireRefresh = true ; } break ; case 'currencyCode' : case 'locale' : super . refresh ( ) ; break ; case 'allowSorting' : this . notify ( events . uiUpdate , { module : 'sort' , enable : this . allowSorting } ) ; requireRefresh = true ; checkCursor = true ; break ; case 'allowFiltering' : this . updateStackedFilter ( ) ; this . notify ( events . uiUpdate , { module : 'filter' , enable : this . allowFiltering } ) ; requireRefresh = true ; if ( this . filterSettings . type !== 'FilterBar' ) { this . refreshHeader ( ) ; } break ; case 'height' : case 'width' : this . notify ( events . uiUpdate , { module : 'scroll' , properties : { width : newProp . width , height : newProp . height } } ) ; break ; case 'allowReordering' : this . headerModule . refreshUI ( ) ; checkCursor = true ; break ; case 'allowRowDragAndDrop' : this . notify ( events . uiUpdate , { module : 'rowDragAndDrop' , enable : this . allowRowDragAndDrop } ) ; break ; case 'allowSelection' : this . notify ( events . uiUpdate , { module : 'selection' , enable : this . allowSelection } ) ; break ; case 'rowTemplate' : this . rowTemplateFn = templateCompiler ( this . rowTemplate ) ; requireRefresh = true ; break ; case 'detailTemplate' : this . detailTemplateFn = templateCompiler ( this . detailTemplate ) ; requireRefresh = true ; break ; case 'allowGrouping' : this . notify ( events . uiUpdate , { module : 'group' , enable : this . allowGrouping } ) ; this . headerModule . refreshUI ( ) ; requireRefresh = true ; checkCursor = true ; break ; case 'childGrid' : requireRefresh = true ; break ; case 'toolbar' : this . notify ( events . uiUpdate , { module : 'toolbar' } ) ; break ; case 'groupSettings' : this . notify ( events . inBoundModelChanged , { module : 'group' , properties : newProp . groupSettings , oldProperties : oldProp . groupSettings } ) ; break ; case 'aggregates' : if ( ! this . aggregates . length && this . allowGrouping && this . groupSettings . columns . length ) { requireRefresh = true ; } this . notify ( events . uiUpdate , { module : 'aggregate' , properties : newProp } ) ; break ; case 'frozenColumns' : case 'frozenRows' : freezeRefresh = true ; requireGridRefresh = true ; break ; case 'enableVirtualization' : super . refresh ( ) ; break ; default : this . extendedPropertyChange ( prop , newProp ) ; } } if ( checkCursor ) { this . updateDefaultCursor ( ) ; } if ( requireGridRefresh ) { if ( freezeRefresh || this . frozenColumns || this . frozenRows ) { this . freezeRefresh ( ) ; } else { this . refresh ( ) ; } } else if ( requireRefresh ) { this . notify ( events . modelChanged , args ) ; requireRefresh = false ; } } private extendedPropertyChange ( prop , newProp ) { switch ( prop ) { case 'enableRtl' : this . updateRTL ( ) ; if ( this . allowPaging ) { ( < EJ2Intance > this . element . querySelector ( '.e-gridpager' ) ) . ej2_instances [ 0 ] . enableRtl = newProp . enableRtl ; ( < EJ2Intance > this . element . querySelector ( '.e-gridpager' ) ) . ej2_instances [ 0 ] . dataBind ( ) ; } if ( this . height !== 'auto' ) { this . scrollModule . removePadding ( ! newProp . enableRtl ) ; this . scrollModule . setPadding ( ) ; } if ( this . toolbar ) { ( < EJ2Intance > this . toolbarModule . getToolbar ( ) ) . ej2_instances [ 0 ] . enableRtl = newProp . enableRtl ; ( < EJ2Intance > this . toolbarModule . getToolbar ( ) ) . ej2_instances [ 0 ] . dataBind ( ) ; } if ( this . contextMenuItems ) { ( < EJ2Intance > this . contextMenuModule . getContextMenu ( ) ) . ej2_instances [ 0 ] . enableRtl = newProp . enableRtl ; ( < EJ2Intance > this . contextMenuModule . getContextMenu ( ) ) . ej2_instances [ 0 ] . dataBind ( ) ; } if ( this . showColumnMenu ) { ( < EJ2Intance > this . columnMenuModule . getColumnMenu ( ) ) . ej2_instances [ 0 ] . enableRtl = newProp . enableRtl ; ( < EJ2Intance > this . columnMenuModule . getColumnMenu ( ) ) . ej2_instances [ 0 ] . dataBind ( ) ; } this . notify ( events . rtlUpdated , { } ) ; break ; case 'enableAltRow' : this . renderModule . refresh ( ) ; break ; case 'allowResizing' : this . headerModule . refreshUI ( ) ; this . updateResizeLines ( ) ; break ; case 'rowHeight' : if ( this . rowHeight ) { addClass ( [ this . element ] , 'e-grid-min-height' ) ; } else { removeClass ( [ this . element ] , 'e-grid-min-height' ) ; } this . renderModule . refresh ( ) ; this . headerModule . refreshUI ( ) ; break ; case 'gridLines' : this . updateGridLines ( ) ; break ; case 'showColumnMenu' : this . headerModule . refreshUI ( ) ; this . notify ( events . uiUpdate , { module : 'columnMenu' , enable : true } ) ; break ; case 'columnMenuItems' : this . notify ( events . uiUpdate , { module : 'columnMenu' , enable : this . columnMenuItems } ) ; break ; case 'contextMenuItems' : this . notify ( events . uiUpdate , { module : 'contextMenu' , enable : this . contextMenuItems } ) ; break ; case 'showColumnChooser' : this . notify ( events . uiUpdate , { module : 'columnChooser' , enable : this . showColumnChooser } ) ; break ; case 'filterSettings' : this . updateStackedFilter ( ) ; this . notify ( events . inBoundModelChanged , { module : 'filter' , properties : newProp . filterSettings } ) ; break ; case 'searchSettings' : this . notify ( events . inBoundModelChanged , { module : 'search' , properties : newProp . searchSettings } ) ; break ; case 'sortSettings' : this . notify ( events . inBoundModelChanged , { module : 'sort' } ) ; break ; case 'selectionSettings' : this . notify ( events . inBoundModelChanged , { module : 'selection' , properties : newProp . selectionSettings } ) ; break ; case 'editSettings' : this . notify ( events . inBoundModelChanged , { module : 'edit' , properties : newProp . editSettings } ) ; break ; case 'allowTextWrap' : case 'textWrapSettings' : if ( this . allowTextWrap ) { this . applyTextWrap ( ) ; } else { this . removeTextWrap ( ) ; } this . notify ( events . freezeRender , { case : 'textwrap' , isModeChg : ( prop === 'textWrapSettings' ) } ) ; break ; case 'dataSource' : let pending = this . getDataModule ( ) . getState ( ) ; if ( pending . isPending ) { let gResult = ! isNullOrUndefined ( this . dataSource ) ? ( < DataResult > this . dataSource ) . result : [ ] ; ( pending . group || [ ] ) . forEach ( ( name ) => { gResult = DataUtil . group ( < Object [ ] > gResult , name , pending . aggregates || [ ] ) ; } ) ; this . dataSource = { result : gResult , count : ( < DataResult > this . dataSource ) . count , aggregates : ( < DataResult > this . dataSource ) . aggregates } ; pending . resolver ( this . dataSource ) ; } else { this . getDataModule ( ) . setState ( { isDataChanged : false } ) ; this . notify ( events . dataSourceModified , { } ) ; this . renderModule . refresh ( ) ; } break ; case 'enableHover' : let action = newProp . enableHover ? addClass : removeClass ; ( < Function > action ) ( [ this . element ] , 'e-gridhover' ) ; break ; } } private public setProperties ( prop , muteOnChange ? ) { super . setProperties ( prop , muteOnChange ) ; if ( this . filterModule && muteOnChange ) { this . filterModule . refreshFilter ( ) ; } } hidden public updateDefaultCursor ( ) { let headerRows = [ ] . slice . call ( this . element . querySelectorAll ( '.e-columnheader' ) ) ; for ( let row of headerRows ) { if ( this . allowSorting || ( this . allowGrouping && this . groupSettings . showDropArea ) || this . allowReordering ) { row . classList . remove ( 'e-defaultcursor' ) ; } else { row . classList . add ( 'e-defaultcursor' ) ; } } } private updateColumnModel ( columns ) { for ( let i = 0 , len = columns . length ; i < len ; i ++ ) { if ( columns [ i ] . columns ) { this . updateColumnModel ( columns [ i ] . columns as Column [ ] ) ; } else { this . columnModel . push ( columns [ i ] as Column ) ; } } this . updateFrozenColumns ( ) ; } private updateFrozenColumns ( ) { let cols = this . columnModel ; let count = 0 ; for ( let i = 0 , len = cols . length ; i < len ; i ++ ) { if ( cols [ i ] . isFrozen ) { cols . splice ( this . frozenColumns + count , 0 , cols . splice ( i , 1 ) [ 0 ] ) ; count ++ ; } } } return { Column [ ] } public getColumns ( isRefresh ? ) { let inview = this . inViewIndexes . map ( ( v ) => v - this . groupSettings . columns . length ) . filter ( ( v ) => v > - 1 ) ; let vLen = inview . length ; if ( ! this . enableColumnVirtualization || isNullOrUndefined ( this . columnModel ) || this . columnModel . length === 0 || isRefresh ) { this . columnModel = [ ] ; this . updateColumnModel ( this . columns as Column [ ] ) ; } let columns = vLen === 0 ? this . columnModel : this . columnModel . slice ( inview [ 0 ] , inview [ vLen - 1 ] + 1 ) ; return columns ; } private public getStackedHeaderColumnByHeaderText ( stackedHeader , col ) { for ( let i = 0 ; i < col . length ; i ++ ) { let individualColumn = col [ i ] ; if ( individualColumn . field === stackedHeader || individualColumn . headerText === stackedHeader ) { this . stackedColumn = individualColumn ; break ; } else if ( individualColumn . columns ) { this . getStackedHeaderColumnByHeaderText ( stackedHeader , < Column [ ] > individualColumn . columns ) ; } } return this . stackedColumn ; } private public getColumnIndexesInView ( ) { return this . inViewIndexes ; } private public getLocaleConstants ( ) { return this . defaultLocale ; } private public setColumnIndexesInView ( indexes ) { this . inViewIndexes = indexes ; } return { Column [ ] } public getVisibleColumns ( ) { let cols = [ ] ; for ( let col of this . columnModel ) { if ( col . visible ) { cols . push ( col ) ; } } return cols ; } return { Element } public getHeaderContent ( ) { return this . headerModule . getPanel ( ) ; } param { Element } element return { void } public setGridHeaderContent ( element ) { this . headerModule . setPanel ( element ) ; } return { Element } public getContentTable ( ) { return this . contentModule . getTable ( ) ; } param { Element } element return { void } public setGridContentTable ( element ) { this . contentModule . setTable ( element ) ; } return { Element } public getContent ( ) { return this . contentModule . getPanel ( ) ; } param { Element } element return { void } public setGridContent ( element ) { this . contentModule . setPanel ( element ) ; } return { Element } public getHeaderTable ( ) { return this . headerModule . getTable ( ) ; } param { Element } element return { void } public setGridHeaderTable ( element ) { this . headerModule . setTable ( element ) ; } return { Element } public getFooterContent ( ) { if ( isNullOrUndefined ( this . footerElement ) ) { this . footerElement = this . element . getElementsByClassName ( 'e-gridfooter' ) [ 0 ] ; } return this . footerElement ; } return { Element } public getFooterContentTable ( ) { if ( isNullOrUndefined ( this . footerElement ) ) { this . footerElement = this . element . getElementsByClassName ( 'e-gridfooter' ) [ 0 ] ; } return < Element > this . footerElement . firstChild . firstChild ; } return { Element } public getPager ( ) { return this . gridPager ; } param { Element } element return { void } public setGridPager ( element ) { this . gridPager = element ; } param { number } index return { Element } public getRowByIndex ( index ) { return this . contentModule . getRowByIndex ( index ) ; } param { number } index return { Element } public getMovableRowByIndex ( index ) { return this . contentModule . getMovableRowByIndex ( index ) ; } return { Element [ ] } public getRows ( ) { return this . contentModule . getRowElements ( ) ; } param { Element } return public getRowInfo ( target ) { let ele = target as Element ; let args = { target : target } ; if ( ! isNullOrUndefined ( target ) && isNullOrUndefined ( parentsUntil ( ele , 'e-detailrowcollapse' ) && isNullOrUndefined ( parentsUntil ( ele , 'e-recordplusexpand' ) ) ) && ! this . isEdit ) { let cell = closest ( ele , '.e-rowcell' ) ; if ( ! cell ) { return args ; } let cellIndex = parseInt ( cell . getAttribute ( 'aria-colindex' ) , 10 ) ; if ( ! isNullOrUndefined ( cell ) && ! isNaN ( cellIndex ) ) { let row = closest ( cell , '.e-row' ) ; let rowIndex = parseInt ( row . getAttribute ( 'aria-rowindex' ) , 10 ) ; let frzCols = this . getFrozenColumns ( ) ; let isMovable = frzCols ? cellIndex >= frzCols : false ; let rows = < Row < { } > [ ] > ( isMovable ? this . contentModule . getMovableRows ( ) : this . contentModule . getRows ( ) ) ; let rowsObject = rows . filter ( ( r ) => r . uid === row . getAttribute ( 'data-uid' ) ) ; let rowData = rowsObject [ 0 ] . data ; let column = rowsObject [ 0 ] . cells [ isMovable ? cellIndex - frzCols : cellIndex ] . column as Column ; args = { cell : cell , cellIndex : cellIndex , row : row , rowIndex : rowIndex , rowData : rowData , column : column , target : target } ; } } return args ; } return { Element [ ] } public getMovableRows ( ) { return this . contentModule . getMovableRowElements ( ) ; } return { Element [ ] } public getDataRows ( ) { let rows = [ ] . slice . call ( this . getContentTable ( ) . querySelector ( 'tbody' ) . children ) ; if ( this . frozenRows ) { let freezeRows = [ ] . slice . call ( this . getHeaderTable ( ) . querySelector ( 'tbody' ) . children ) ; rows = this . addMovableRows ( freezeRows , rows ) ; } let dataRows = this . generateDataRows ( rows ) ; return dataRows ; } hidden public addMovableRows ( fRows , mrows ) { for ( let i = 0 , len = mrows . length ; i < len ; i ++ ) { fRows . push ( mrows [ i ] ) ; } return fRows ; } private generateDataRows ( rows ) { let dRows = [ ] ; for ( let i = 0 , len = rows . length ; i < len ; i ++ ) { if ( rows [ i ] . classList . contains ( 'e-row' ) && ! rows [ i ] . classList . contains ( 'e-hiddenrow' ) ) { dRows . push ( rows [ i ] as Element ) ; } } return dRows ; } return { Element [ ] } public getMovableDataRows ( ) { let rows = [ ] . slice . call ( this . getContent ( ) . querySelector ( '.e-movablecontent' ) . querySelector ( 'tbody' ) . children ) ; if ( this . frozenRows ) { let freezeRows = [ ] . slice . call ( this . getHeaderContent ( ) . querySelector ( '.e-movableheader' ) . querySelector ( 'tbody' ) . children ) ; rows = this . addMovableRows ( freezeRows , rows ) ; } let dataRows = this . generateDataRows ( rows ) ; return dataRows ; } param { string | number } key param { string } field param { string | number | boolean | Date } value public setCellValue ( key , field , value ) { let cells = 'cells' ; let rowData = 'data' ; let rowIdx = 'index' ; let rowuID = 'uid' ; let fieldIdx ; let col ; let tr ; let mTr ; let pkName = this . getPrimaryKeyFieldNames ( ) [ 0 ] ; let cell = new CellRenderer ( this , this . serviceLocator ) ; let selectedRow = { } ; let movableSelectedRow = { } ; let rowObjects = this . contentModule . getRows ( ) ; let movableRowObjects = this . contentModule . getMovableRows ( ) ; fieldIdx = this . getColumnIndexByField ( field ) ; if ( this . groupSettings . columns . length > 0 || this . childGrid || this . detailTemplate ) { fieldIdx = fieldIdx + 1 ; } col = this . getColumnByField ( field ) ; selectedRow = ( < Row < { } > [ ] > rowObjects ) . filter ( ( r ) => getValue ( pkName , r . data ) === key ) [ 0 ] ; movableSelectedRow = ( < Row < { } > [ ] > movableRowObjects ) . filter ( ( r ) => getValue ( pkName , r . data ) === key ) [ 0 ] ; tr = ! isNullOrUndefined ( selectedRow ) ? this . element . querySelector ( '[data-uid=' + selectedRow [ rowuID ] + ']' ) : null ; mTr = ! isNullOrUndefined ( movableSelectedRow ) ? this . element . querySelector ( '[data-uid=' + movableSelectedRow [ rowuID ] + ']' ) : null ; if ( ! isNullOrUndefined ( tr ) ) { setValue ( field , value , selectedRow [ rowData ] ) ; let td = ! isNullOrUndefined ( tr . childNodes [ fieldIdx ] as Element ) ? tr . childNodes [ fieldIdx ] as Element : mTr . childNodes [ fieldIdx - this . frozenColumns ] as Element ; if ( ! isNullOrUndefined ( td ) ) { let sRow = selectedRow [ cells ] [ fieldIdx ] ; let mRow ; if ( this . frozenColumns ) { mRow = movableSelectedRow [ cells ] [ fieldIdx - this . frozenColumns ] ; } cell . refreshTD ( td , ! isNullOrUndefined ( sRow ) ? sRow : mRow , selectedRow [ rowData ] , { index : selectedRow [ rowIdx ] } ) ; if ( this . aggregates . length > 0 ) { this . notify ( events . refreshFooterRenderer , { } ) ; if ( this . groupSettings . columns . length > 0 ) { this . notify ( events . groupAggregates , { } ) ; } } if ( ! isNullOrUndefined ( movableSelectedRow ) && ! isNullOrUndefined ( movableSelectedRow [ 'changes' ] ) ) { movableSelectedRow [ 'changes' ] [ field ] = value ; } this . trigger ( events . queryCellInfo , { cell : td , column : col , data : selectedRow [ rowData ] } ) ; } } else { return ; } } param { string | number } key param { Object } rowData public setRowData ( key , rowData ? ) { let rwdata = 'data' ; let rowuID = 'uid' ; let rowObjects = this . contentModule . getRows ( ) ; let selectedRow ; let pkName = this . getPrimaryKeyFieldNames ( ) [ 0 ] ; let rowRenderer = new RowRenderer < Column > ( this . serviceLocator , null , this ) ; if ( this . groupSettings . columns . length > 0 && this . aggregates . length > 0 ) { rowObjects = ( < Row < { } > [ ] > rowObjects ) . filter ( ( row ) => row . isDataRow ) ; } selectedRow = ( < Row < { } > [ ] > rowObjects ) . filter ( ( r ) => getValue ( pkName , r . data ) === key ) [ 0 ] as Row < Column > ; if ( ! isNullOrUndefined ( selectedRow ) && this . element . querySelectorAll ( '[data-uid=' + selectedRow [ rowuID ] + ']' ) . length ) { selectedRow . changes = rowData ; refreshForeignData ( selectedRow , this . getForeignKeyColumns ( ) , selectedRow . changes ) ; rowRenderer . refresh ( selectedRow , this . getColumns ( ) as Column [ ] , true ) ; if ( this . aggregates . length > 0 ) { this . notify ( events . refreshFooterRenderer , { } ) ; if ( this . groupSettings . columns . length > 0 ) { this . notify ( events . groupAggregates , { } ) ; } } } else { return ; } } param { number } rowIndex param { number } columnIndex return { Element } public getCellFromIndex ( rowIndex , columnIndex ) { return this . getDataRows ( ) [ rowIndex ] . querySelectorAll ( '.e-rowcell' ) [ columnIndex ] ; } param { number } rowIndex param { number } columnIndex return { Element } public getMovableCellFromIndex ( rowIndex , columnIndex ) { return this . getMovableDataRows ( ) [ rowIndex ] . querySelectorAll ( '.e-rowcell' ) [ columnIndex - this . getFrozenColumns ( ) ] ; } param { number } index return { Element } public getColumnHeaderByIndex ( index ) { return this . getHeaderTable ( ) . querySelectorAll ( '.e-headercell' ) [ index ] ; } hidden public getRowObjectFromUID ( uid ) { let rows = this . contentModule . getRows ( ) as Row < Column > [ ] ; let row = this . rowObject ( rows , uid ) ; if ( this . getFrozenColumns ( ) ) { if ( ! row ) { row = this . rowObject ( this . contentModule . getMovableRows ( ) as Row < Column > [ ] , uid ) ; return row ; } } return row ; } private rowObject ( rows , uid ) { for ( let row of rows ) { if ( row . uid === uid ) { return row ; } } return null ; } hidden public getRowsObject ( ) { return this . contentModule . getRows ( ) as Row < Column > [ ] ; } hidden public getMovableRowsObject ( ) { return this . contentModule . getMovableRows ( ) as Row < Column > [ ] ; } param { string } field return { Element } public getColumnHeaderByField ( field ) { return this . getColumnHeaderByUid ( this . getColumnByField ( field ) . uid ) ; } param { string } field return { Element } public getColumnHeaderByUid ( uid ) { return this . getHeaderContent ( ) . querySelector ( '[e-mappinguid=' + uid + ']' ) . parentElement ; } hidden public getColumnByIndex ( index ) { let column ; this . getColumns ( ) . some ( ( col , i ) => { column = col ; return i === index ; } ) ; return column ; } param { string } field return { Column } public getColumnByField ( field ) { return iterateArrayOrObject < Column , Column > ( < Column [ ] > this . getColumns ( ) , ( item , index ) => { if ( item . field === field ) { return item ; } return undefined ; } ) [ 0 ] ; } param { string } field return { number } public getColumnIndexByField ( field ) { let cols = this . getColumns ( ) ; for ( let i = 0 ; i < cols . length ; i ++ ) { if ( cols [ i ] . field === field ) { return i ; } } return - 1 ; } param { string } uid return { Column } public getColumnByUid ( uid ) { return iterateArrayOrObject < Column , Column > ( < Column [ ] > this . getColumns ( ) , ( item , index ) => { if ( item . uid === uid ) { return item ; } return undefined ; } ) [ 0 ] ; } param { string } uid return { number } public getColumnIndexByUid ( uid ) { let index = iterateArrayOrObject < number , Column > ( < Column [ ] > this . getColumns ( ) , ( item , index ) => { if ( item . uid === uid ) { return index ; } return undefined ; } ) [ 0 ] ; return ! isNullOrUndefined ( index ) ? index : - 1 ; } param { string } field return { string } public getUidByColumnField ( field ) { return iterateArrayOrObject < string , Column > ( < Column [ ] > this . getColumns ( ) , ( item , index ) => { if ( item . field === field ) { return item . uid ; } return undefined ; } ) [ 0 ] ; } private param { string } uid return { number } public getNormalizedColumnIndex ( uid ) { let index = this . getColumnIndexByUid ( uid ) ; if ( this . allowGrouping ) { index += this . groupSettings . columns . length ; } if ( this . isDetail ( ) ) { index ++ ; } /**
         * TODO: index normalization based on the stacked header, grouping and detailTemplate
         * and frozen should be handled here
         */ return index ; } return { string [ ] } public getColumnFieldNames ( ) { let columnNames = [ ] ; let column ; for ( let i = 0 , len = this . getColumns ( ) . length ; i < len ; i ++ ) { column = this . getColumns ( ) [ i ] as Column ; if ( column . visible ) { columnNames . push ( column . field ) ; } } return columnNames ; } return { Function } private public getRowTemplate ( ) { return this . rowTemplateFn ; } private return { Function } public getDetailTemplate ( ) { return this . detailTemplateFn ; } private return { Function } public getEditTemplate ( ) { return this . editTemplateFn ; } return { string [ ] } public getPrimaryKeyFieldNames ( ) { let keys = [ ] ; for ( let k = 0 ; k < this . columnModel . length ; k ++ ) { if ( ( this . columnModel [ k ] as Column ) . isPrimaryKey ) { keys . push ( ( this . columnModel [ k ] as Column ) . field ) ; } } return keys ; } /**
     * Refreshes the Grid header and content.
     */ public refresh ( ) { this . headerModule . refreshUI ( ) ; this . updateStackedFilter ( ) ; this . renderModule . refresh ( ) ; } /**
     * Refreshes the Grid header.
     */ public refreshHeader ( ) { this . headerModule . refreshUI ( ) ; } return { Element [ ] } public getSelectedRows ( ) { return this . selectionModule ? this . selectionModule . selectedRecords : [ ] ; } return { number [ ] } public getSelectedRowIndexes ( ) { return this . selectionModule ? this . selectionModule . selectedRowIndexes : [ ] ; } return { number [ ] } public getSelectedRowCellIndexes ( ) { return this . selectionModule . selectedRowCellIndexes ; } return { Object [ ] } public getSelectedRecords ( ) { return this . selectionModule ? this . selectionModule . getSelectedRecords ( ) : [ ] ; } return { Data } public getDataModule ( ) { return this . renderModule . data ; } param { string | string [ ] } keys param { string } showBy return { void } public showColumns ( keys , showBy ? ) { showBy = showBy ? showBy : 'headerText' ; this . showHider . show ( keys , showBy ) ; } param { string | string [ ] } keys param { string } hideBy return { void } public hideColumns ( keys , hideBy ? ) { hideBy = hideBy ? hideBy : 'headerText' ; this . showHider . hide ( keys , hideBy ) ; } hidden public getFrozenColumns ( ) { return this . frozenColumns + this . getFrozenCount ( this . columns as Column [ ] , 0 ) ; } hidden public getVisibleFrozenColumns ( ) { return this . getVisibleFrozenColumnsCount ( ) + this . getVisibleFrozenCount ( this . columns as Column [ ] , 0 ) ; } private getVisibleFrozenColumnsCount ( ) { let visibleFrozenColumns = 0 ; let col = this . columns as Column [ ] ; for ( let i = 0 ; i < this . frozenColumns ; i ++ ) { if ( col [ i ] . visible ) { visibleFrozenColumns ++ ; } } return visibleFrozenColumns ; } private getVisibleFrozenCount ( cols , cnt ) { for ( let i = 0 , len = cols . length ; i < len ; i ++ ) { if ( cols [ i ] . columns ) { cnt = this . getVisibleFrozenCount ( cols [ i ] . columns as Column [ ] , cnt ) ; } else { if ( cols [ i ] . isFrozen && cols [ i ] . visible ) { cnt ++ ; } } } return cnt ; } private getFrozenCount ( cols , cnt ) { for ( let i = 0 , len = cols . length ; i < len ; i ++ ) { if ( cols [ i ] . columns ) { cnt = this . getFrozenCount ( cols [ i ] . columns as Column [ ] , cnt ) ; } else { if ( cols [ i ] . isFrozen ) { cnt ++ ; } } } return cnt ; } param { number } pageNo return { void } public goToPage ( pageNo ) { this . pagerModule . goToPage ( pageNo ) ; } param { string } message return { void } public updateExternalMessage ( message ) { this . pagerModule . updateExternalMessage ( message ) ; } param { string } columnName param { SortDirection } direction param { boolean } isMultiSort return { void } public sortColumn ( columnName , direction , isMultiSort ? ) { this . sortModule . sortColumn ( columnName , direction , isMultiSort ) ; } return { void } public clearSorting ( ) { this . sortModule . clearSorting ( ) ; } param { string } field return { void } hidden public removeSortColumn ( field ) { this . sortModule . removeSortColumn ( field ) ; } param { string } fieldName param { string } filterOperator param { string | number | Date | boolean } filterValue param { string } predicate param { boolean } matchCase param { boolean } ignoreAccent param { string } actualFilterValue param { string } actualOperator return { void } public filterByColumn ( fieldName , filterOperator , filterValue , predicate ? , matchCase ? , ignoreAccent ? , actualFilterValue ? , actualOperator ? ) { this . filterModule . filterByColumn ( fieldName , filterOperator , filterValue , predicate , matchCase , ignoreAccent , actualFilterValue , actualOperator ) ; } return { void } public clearFiltering ( ) { this . filterModule . clearFiltering ( ) ; } param { string } field param { boolean } isClearFilterBar return { void } hidden public removeFilteredColsByField ( field , isClearFilterBar ? ) { this . filterModule . removeFilteredColsByField ( field , isClearFilterBar ) ; } param { number } index param { boolean } isToggle return { void } public selectRow ( index , isToggle ? ) { this . selectionModule . selectRow ( index , isToggle ) ; } param { number [ ] } rowIndexes return { void } public selectRows ( rowIndexes ) { this . selectionModule . selectRows ( rowIndexes ) ; } return { void } public clearSelection ( ) { this . selectionModule . clearSelection ( ) ; } param { IIndex } cellIndex param { boolean } isToggle return { void } public selectCell ( cellIndex , isToggle ? ) { this . selectionModule . selectCell ( cellIndex , isToggle ) ; } param { string } searchString return { void } public search ( searchString ) { this . searchModule . search ( searchString ) ; } return { void } public print ( ) { this . printModule . print ( ) ; } param { string } fieldname param { Object } data public deleteRecord ( fieldname ? , data ? ) { this . editModule . deleteRecord ( fieldname , data ) ; } param { HTMLTableRowElement } tr public startEdit ( ) { this . editModule . startEdit ( ) ; } /**
     * If Grid is in editable state, you can save a record by invoking endEdit.
     */ public endEdit ( ) { this . editModule . endEdit ( ) ; } /**
     * Cancels edited state.
     */ public closeEdit ( ) { this . editModule . closeEdit ( ) ; } param { Object } data param { number } index public addRecord ( data ? , index ? ) { this . editModule . addRecord ( data , index ) ; } param { HTMLTableRowElement } tr public deleteRow ( tr ) { this . editModule . deleteRow ( tr ) ; } param { boolean } withHeader public copy ( withHeader ? ) { this . clipboardModule . copy ( withHeader ) ; } hidden public recalcIndentWidth ( ) { if ( ! this . getHeaderTable ( ) . querySelector ( '.e-emptycell' ) ) { return ; } if ( ( ! this . groupSettings . columns . length && ! this . isDetail ( ) ) || this . getHeaderTable ( ) . querySelector ( '.e-emptycell' ) . getAttribute ( 'indentRefreshed' ) || ! this . getContentTable ( ) ) { return ; } let indentWidth = ( this . getHeaderTable ( ) . querySelector ( '.e-emptycell' ) . parentElement as HTMLElement ) . offsetWidth ; let headerCol = [ ] . slice . call ( this . getHeaderTable ( ) . querySelector ( 'colgroup' ) . childNodes ) ; let contentCol = [ ] . slice . call ( this . getContentTable ( ) . querySelector ( 'colgroup' ) . childNodes ) ; let perPixel = indentWidth / 30 ; let i = 0 ; if ( perPixel >= 1 ) { indentWidth = ( 30 / perPixel ) ; } if ( this . enableColumnVirtualization ) { indentWidth = 30 ; } while ( i < this . groupSettings . columns . length ) { headerCol [ i ] . style . width = indentWidth + 'px' ; contentCol [ i ] . style . width = indentWidth + 'px' ; this . notify ( events . columnWidthChanged , { index : i , width : indentWidth } ) ; i ++ ; } if ( this . isDetail ( ) ) { headerCol [ i ] . style . width = indentWidth + 'px' ; contentCol [ i ] . style . width = indentWidth + 'px' ; this . notify ( events . columnWidthChanged , { index : i , width : indentWidth } ) ; } this . getHeaderTable ( ) . querySelector ( '.e-emptycell' ) . setAttribute ( 'indentRefreshed' , 'true' ) ; } param { string } fromFName param { string } toFName return { void } public reorderColumns ( fromFName , toFName ) { this . reorderModule . reorderColumns ( fromFName , toFName ) ; } param { string | string [ ] } fieldNames return { void } public autoFitColumns ( fieldNames ? ) { this . resizeModule . autoFitColumns ( fieldNames ) ; } hidden public createColumnchooser ( x , y , target ) { this . columnChooserModule . renderColumnChooser ( x , y , target ) ; } private initializeServices ( ) { this . serviceLocator . register ( 'widthService' , this . widthService = new ColumnWidthService ( this ) ) ; this . serviceLocator . register ( 'cellRendererFactory' , new CellRendererFactory ) ; this . serviceLocator . register ( 'rendererFactory' , new RendererFactory ) ; this . serviceLocator . register ( 'localization' , this . localeObj = new L10n ( this . getModuleName ( ) , this . defaultLocale , this . locale ) ) ; this . serviceLocator . register ( 'valueFormatter' , this . valueFormatterService = new ValueFormatter ( this . locale ) ) ; this . serviceLocator . register ( 'showHideService' , this . showHider = new ShowHide ( this ) ) ; this . serviceLocator . register ( 'ariaService' , this . ariaService = new AriaService ( ) ) ; this . serviceLocator . register ( 'focus' , this . focusModule = new FocusStrategy ( this ) ) ; } private processModel ( ) { let gCols = this . groupSettings . columns ; let sCols = this . sortSettings . columns ; let flag ; let j ; if ( this . allowGrouping ) { for ( let i = 0 , len = gCols . length ; i < len ; i ++ ) { j = 0 ; for ( let sLen = sCols . length ; j < sLen ; j ++ ) { if ( sCols [ j ] . field === gCols [ i ] ) { flag = true ; break ; } } if ( ! flag ) { sCols . push ( { field : gCols [ i ] , direction : 'Ascending' } ) ; } else { if ( this . allowSorting ) { this . sortedColumns . push ( sCols [ j ] . field ) ; } else { sCols [ j ] . direction = 'Ascending' ; } } if ( ! this . groupSettings . showGroupedColumn ) { let column = this . enableColumnVirtualization ? ( < Column [ ] > this . columns ) . filter ( ( c ) => c . field === gCols [ i ] ) [ 0 ] : this . getColumnByField ( gCols [ i ] ) ; column . visible = false ; } } } if ( ! gCols . length ) { sCols . forEach ( ( col ) => { this . sortedColumns . push ( col . field ) ; } ) ; } this . rowTemplateFn = templateCompiler ( this . rowTemplate ) ; this . detailTemplateFn = templateCompiler ( this . detailTemplate ) ; this . editTemplateFn = templateCompiler ( this . editSettings . template ) ; if ( ! isNullOrUndefined ( this . parentDetails ) ) { let value = isNullOrUndefined ( this . parentDetails . parentKeyFieldValue ) ? 'undefined' : this . parentDetails . parentKeyFieldValue ; this . query . where ( this . queryString , 'equal' , value , true ) ; } this . initForeignColumn ( ) ; } private initForeignColumn ( ) { if ( this . isForeignKeyEnabled ( this . getColumns ( ) ) ) { this . notify ( events . initForeignKeyColumn , this . getForeignKeyColumns ( ) ) ; } } private gridRender ( ) { this . updateRTL ( ) ; if ( this . enableHover ) { this . element . classList . add ( 'e-gridhover' ) ; } if ( Browser . isDevice ) { this . element . classList . add ( 'e-device' ) ; } if ( this . rowHeight ) { this . element . classList . add ( 'e-grid-min-height' ) ; } classList ( this . element , [ 'e-responsive' , 'e-default' ] , [ ] ) ; let rendererFactory = this . serviceLocator . getService < RendererFactory > ( 'rendererFactory' ) ; this . headerModule = rendererFactory . getRenderer ( RenderType . Header ) ; this . contentModule = rendererFactory . getRenderer ( RenderType . Content ) ; this . printModule = new Print ( this , this . scrollModule ) ; this . clipboardModule = new Clipboard ( this ) ; this . renderModule . render ( ) ; this . eventInitializer ( ) ; this . createGridPopUpElement ( ) ; this . widthService . setWidthToColumns ( ) ; this . updateGridLines ( ) ; this . applyTextWrap ( ) ; this . createTooltip ( ) ; } private dataReady ( ) { this . scrollModule . setWidth ( ) ; this . scrollModule . setHeight ( ) ; if ( this . height !== 'auto' ) { this . scrollModule . setPadding ( ) ; } } private updateRTL ( ) { if ( this . enableRtl ) { this . element . classList . add ( 'e-rtl' ) ; } else { this . element . classList . remove ( 'e-rtl' ) ; } } private createGridPopUpElement ( ) { let popup = this . createElement ( 'div' , { className : 'e-gridpopup' , styles : 'display:none;' } ) ; let content = this . createElement ( 'div' , { className : 'e-content' , attrs : { tabIndex : '-1' } } ) ; append ( [ content , this . createElement ( 'div' , { className : 'e-uptail e-tail' } ) ] , popup ) ; content . appendChild ( this . createElement ( 'span' ) ) ; append ( [ content , this . createElement ( 'div' , { className : 'e-downtail e-tail' } ) ] , popup ) ; this . element . appendChild ( popup ) ; } private updateGridLines ( ) { classList ( this . element , [ ] , [ 'e-verticallines' , 'e-horizontallines' , 'e-hidelines' , 'e-bothlines' ] ) ; switch ( this . gridLines ) { case 'Horizontal' : this . element . classList . add ( 'e-horizontallines' ) ; break ; case 'Vertical' : this . element . classList . add ( 'e-verticallines' ) ; break ; case 'None' : this . element . classList . add ( 'e-hidelines' ) ; break ; case 'Both' : this . element . classList . add ( 'e-bothlines' ) ; break ; } this . updateResizeLines ( ) ; } private updateResizeLines ( ) { if ( this . allowResizing && ! ( this . gridLines === 'Vertical' || this . gridLines === 'Both' ) ) { this . element . classList . add ( 'e-resize-lines' ) ; } else { this . element . classList . remove ( 'e-resize-lines' ) ; } } return { void } hidden public applyTextWrap ( ) { if ( this . allowTextWrap ) { let headerRows = [ ] . slice . call ( this . element . querySelectorAll ( '.e-columnheader' ) ) ; switch ( this . textWrapSettings . wrapMode ) { case 'Header' : wrap ( this . element , false ) ; wrap ( this . getContent ( ) , false ) ; wrap ( headerRows , true ) ; break ; case 'Content' : wrap ( this . getContent ( ) , true ) ; wrap ( this . element , false ) ; wrap ( headerRows , false ) ; break ; default : wrap ( this . element , true ) ; wrap ( this . getContent ( ) , false ) ; wrap ( headerRows , false ) ; } } } return { void } hidden public removeTextWrap ( ) { wrap ( this . element , false ) ; let headerRows = [ ] . slice . call ( this . element . querySelectorAll ( '.e-columnheader' ) ) ; wrap ( headerRows , false ) ; wrap ( this . getContent ( ) , false ) ; } return { void } hidden public createTooltip ( ) { this . toolTipObj = new Tooltip ( { opensOn : 'custom' , content : '' } , this . element ) ; } private getTooltipStatus ( element ) { let width ; let headerTable = this . getHeaderTable ( ) ; let contentTable = this . getContentTable ( ) ; let headerDivTag = 'e-gridheader' ; let contentDivTag = 'e-gridcontent' ; let htable = this . createTable ( headerTable , headerDivTag , 'header' ) ; let ctable = this . createTable ( headerTable , headerDivTag , 'content' ) ; let td = element ; let table = headerTable . contains ( element ) ? htable : ctable ; let ele = headerTable . contains ( element ) ? 'th' : 'tr' ; table . querySelector ( ele ) . className = element . className ; table . querySelector ( ele ) . innerHTML = element . innerHTML ; width = table . querySelector ( ele ) . getBoundingClientRect ( ) . width ; document . body . removeChild ( htable ) ; document . body . removeChild ( ctable ) ; if ( width > element . getBoundingClientRect ( ) . width ) { return true ; } return false ; } private mouseMoveHandler ( e ) { if ( this . isEllipsisTooltip ( ) ) { let element = parentsUntil ( ( e . target as Element ) , 'e-ellipsistooltip' ) as HTMLElement ; if ( element ) { if ( element . getAttribute ( 'aria-describedby' ) ) { return ; } if ( this . getTooltipStatus ( element ) ) { if ( element . getElementsByClassName ( 'e-headertext' ) . length ) { this . toolTipObj . content = ( element . getElementsByClassName ( 'e-headertext' ) [ 0 ] as HTMLElement ) . innerText ; } else { this . toolTipObj . content = element . innerText ; } this . toolTipObj . open ( element ) ; } else { this . toolTipObj . close ( ) ; } } else { this . toolTipObj . close ( ) ; } } } private isEllipsisTooltip ( ) { let cols = this . getColumns ( ) ; for ( let i = 0 ; i < cols . length ; i ++ ) { if ( cols [ i ] . clipMode === 'EllipsisWithTooltip' ) { return true ; } } return false ; } private scrollHandler ( ) { if ( this . isEllipsisTooltip ( ) ) { this . toolTipObj . close ( ) ; } } hidden protected createTable ( table , tag , type ) { let myTableDiv = this . createElement ( 'div' ) as HTMLDivElement ; myTableDiv . className = this . element . className ; myTableDiv . style . cssText = 'display: inline-block;visibility:hidden;position:absolute' ; let mySubDiv = this . createElement ( 'div' ) as HTMLDivElement ; mySubDiv . className = tag ; let myTable = this . createElement ( 'table' ) as HTMLTableElement ; myTable . className = table . className ; myTable . style . cssText = 'table-layout: auto;width: auto' ; let ele = ( type === 'header' ) ? 'th' : 'td' ; let myTr = this . createElement ( 'tr' ) as HTMLTableRowElement ; let mytd = this . createElement ( ele ) as HTMLElement ; myTr . appendChild ( mytd ) ; myTable . appendChild ( myTr ) ; mySubDiv . appendChild ( myTable ) ; myTableDiv . appendChild ( mySubDiv ) ; document . body . appendChild ( myTableDiv ) ; return myTableDiv ; } private keyPressed ( e ) { if ( e . action === 'tab' || e . action === 'shiftTab' ) { this . toolTipObj . close ( ) ; } } hidden public wireEvents ( ) { EventHandler . add ( this . element , 'click' , this . mouseClickHandler , this ) ; EventHandler . add ( this . element , 'touchend' , this . mouseClickHandler , this ) ; EventHandler . add ( this . element , 'focusout' , this . focusOutHandler , this ) ; EventHandler . add ( this . getContent ( ) , 'dblclick' , this . dblClickHandler , this ) ; if ( this . allowKeyboard ) { this . element . tabIndex = this . element . tabIndex === - 1 ? 0 : this . element . tabIndex ; } this . keyboardModule = new KeyboardEvents ( this . element , { keyAction : this . keyActionHandler . bind ( this ) , keyConfigs : this . keyConfigs , eventName : 'keydown' } ) ; EventHandler . add ( this . getContent ( ) . firstElementChild , 'scroll' , this . scrollHandler , this ) ; EventHandler . add ( this . element , 'mousemove' , this . mouseMoveHandler , this ) ; } hidden public unwireEvents ( ) { EventHandler . remove ( this . element , 'click' , this . mouseClickHandler ) ; EventHandler . remove ( this . element , 'touchend' , this . mouseClickHandler ) ; EventHandler . remove ( this . element , 'focusout' , this . focusOutHandler ) ; EventHandler . remove ( this . getContent ( ) . firstElementChild , 'scroll' , this . scrollHandler ) ; EventHandler . remove ( this . element , 'mousemove' , this . mouseMoveHandler ) ; } hidden public addListener ( ) { if ( this . isDestroyed ) { return ; } this . on ( events . dataReady , this . dataReady , this ) ; this . on ( events . contentReady , this . recalcIndentWidth , this ) ; this . on ( events . headerRefreshed , this . recalcIndentWidth , this ) ; this . dataBoundFunction = this . refreshMediaCol . bind ( this ) ; this . addEventListener ( events . dataBound , this . dataBoundFunction ) ; this . on ( events . keyPressed , this . keyPressed , this ) ; } hidden public removeListener ( ) { if ( this . isDestroyed ) { return ; } this . off ( events . dataReady , this . dataReady ) ; this . off ( events . contentReady , this . recalcIndentWidth ) ; this . off ( events . headerRefreshed , this . recalcIndentWidth ) ; this . removeEventListener ( events . dataBound , this . dataBoundFunction ) ; this . off ( events . keyPressed , this . keyPressed ) ; } return { Object [ ] } hidden public getCurrentViewRecords ( ) { return ( this . allowGrouping && this . groupSettings . columns . length && this . currentViewData . length ) ? ( this . currentViewData as Object [ ] & { records : Object [ ] ; } ) . records : this . currentViewData ; } private mouseClickHandler ( e ) { if ( this . isChildGrid ( e ) || ( parentsUntil ( e . target as Element , 'e-gridpopup' ) && e . touches ) || this . element . querySelectorAll ( '.e-cloneproperties' ) . length || this . checkEdit ( e ) ) { return ; } if ( ( ( ! this . allowRowDragAndDrop && ( parentsUntil ( e . target as Element , 'e-gridcontent' ) || ( e . target as Element ) . tagName === 'TD' ) ) || ( ! ( this . allowGrouping || this . allowReordering ) && parentsUntil ( e . target as Element , 'e-gridheader' ) ) ) && e . touches ) { return ; } if ( parentsUntil ( e . target as Element , 'e-gridheader' ) && this . allowRowDragAndDrop ) { e . preventDefault ( ) ; } this . notify ( events . click , e ) ; } private checkEdit ( e ) { let tr = parentsUntil ( e . target as Element , 'e-row' ) ; let isEdit = this . editSettings . mode !== 'Batch' && this . isEdit && tr && ( tr . classList . contains ( 'e-editedrow' ) || tr . classList . contains ( 'e-addedrow' ) ) ; return ! parentsUntil ( e . target as Element , 'e-unboundcelldiv' ) && ( isEdit || ( parentsUntil ( e . target as Element , 'e-rowcell' ) && parentsUntil ( e . target as Element , 'e-rowcell' ) . classList . contains ( 'e-editedbatchcell' ) ) ) ; } private dblClickHandler ( e ) { let grid = parentsUntil ( e . target as Element , 'e-grid' ) ; if ( isNullOrUndefined ( grid ) || grid . id !== this . element . id || closest ( < Node > e . target , '.e-unboundcelldiv' ) ) { return ; } let args = this . getRowInfo ( e . target as Element ) as RecordDoubleClickEventArgs ; args . target = e . target as Element ; this . trigger ( events . recordDoubleClick , args ) ; this . notify ( events . dblclick , e ) ; } private focusOutHandler ( e ) { if ( this . isChildGrid ( e ) ) { return ; } if ( ! parentsUntil ( e . target as Element , 'e-grid' ) ) { ( this . element . querySelector ( '.e-gridpopup' ) as HTMLElement ) . style . display = 'None' ; } let filterClear = this . element . querySelector ( '.e-cancel:not(.e-hide)' ) ; if ( filterClear ) { filterClear . classList . add ( 'e-hide' ) ; } if ( ( ! e . relatedTarget || ! parentsUntil ( e . relatedTarget as Element , 'e-grid' ) ) && ! this . keyPress && this . editSettings . mode === 'Batch' && this . isEdit && ! Browser . isDevice ) { this . editModule . saveCell ( ) ; this . notify ( events . editNextValCell , { } ) ; } this . keyPress = false ; } private isChildGrid ( e ) { let gridElement = parentsUntil ( ( e . target as HTMLElement ) , 'e-grid' ) ; if ( gridElement && gridElement . id !== this . element . id ) { return true ; } return false ; } private mergePersistGridData ( ) { let data = window . localStorage . getItem ( this . getModuleName ( ) + this . element . id ) ; if ( ! ( isNullOrUndefined ( data ) || ( data === '' ) ) ) { let dataObj = JSON . parse ( data ) ; let keys = Object . keys ( dataObj ) ; this . isProtectedOnChange = true ; for ( let key of keys ) { if ( ( typeof this [ key ] === 'object' ) && ! isNullOrUndefined ( this [ key ] ) ) { if ( Array . isArray ( this [ key ] ) && key === 'columns' ) { this . mergeColumns ( < Column [ ] > dataObj [ key ] , < Column [ ] > this [ key ] ) ; this [ key ] = dataObj [ key ] ; } else { extend ( this [ key ] , dataObj [ key ] ) ; } } else { this [ key ] = dataObj [ key ] ; } } this . isProtectedOnChange = false ; } } private mergeColumns ( storedColumn , columns ) { ( < Column [ ] > storedColumn ) . forEach ( ( col , index , arr ) => { let ind ; let localCol = this . getColumnByField ( col . field ) || columns . some ( ( element , i ) => { ind = i ; return element . headerText === col . headerText ; } ) && columns [ ind ] ; if ( ! isNullOrUndefined ( localCol ) ) { if ( localCol . columns && localCol . columns . length ) { this . mergeColumns ( < Column [ ] > col . columns , < Column [ ] > localCol . columns ) ; } else { arr [ index ] = < Column > extend ( { } , localCol , col , true ) ; } } } ) ; } private isDetail ( ) { return ! isNullOrUndefined ( this . detailTemplate ) || ! isNullOrUndefined ( this . childGrid ) ; } private isCommandColumn ( columns ) { return columns . some ( ( col ) => { if ( col . columns ) { return this . isCommandColumn ( col . columns as Column [ ] ) ; } return ! ! ( col . commands || col . commandsTemplate ) ; } ) ; } private isForeignKeyEnabled ( columns ) { return columns . some ( ( col ) => { if ( col . columns ) { return this . isForeignKeyEnabled ( col . columns as Column [ ] ) ; } return ! ! ( col . dataSource && col . foreignKeyValue ) ; } ) ; } private keyActionHandler ( e ) { this . keyPress = e . action !== 'space' ; if ( this . isChildGrid ( e ) || ( this . isEdit && e . action !== 'escape' && e . action !== 'enter' && e . action !== 'shiftEnter' && e . action !== 'tab' && e . action !== 'shiftTab' ) ) { return ; } if ( this . allowKeyboard ) { if ( e . action === 'ctrlPlusP' ) { e . preventDefault ( ) ; this . print ( ) ; } this . notify ( events . keyPressed , e ) ; } } hidden public setInjectedModules ( modules ) { this . injectedModules = modules ; } private updateColumnObject ( ) { prepareColumns ( this . columns , this . enableColumnVirtualization ) ; this . initForeignColumn ( ) ; this . notify ( events . autoCol , { } ) ; } return { Column [ ] } public getForeignKeyColumns ( ) { return this . getColumns ( ) . filter ( ( col ) => { return col . isForeignColumn ( ) ; } ) ; } hidden public getRowHeight ( ) { return this . rowHeight ? this . rowHeight : getRowHeight ( this . element ) ; } /**
     * Refreshes the Grid column changes.
     */ public refreshColumns ( ) { this . isPreventScrollEvent = true ; this . updateColumnObject ( ) ; this . refresh ( ) ; } param { ExcelExportProperties } excelExportProperties param { boolean } isMultipleExport param { workbook } workbook param { boolean } isBlob return { Promise < any > } public excelExport ( excelExportProperties ? , isMultipleExport ? , workbook ? , isBlob ? ) { return this . excelExportModule . Map ( this , excelExportProperties , isMultipleExport , workbook , false , isBlob ) ; } param { ExcelExportProperties } excelExportProperties param { boolean } isMultipleExport param { workbook } workbook param { boolean } isBlob return { Promise < any > } public csvExport ( excelExportProperties ? , isMultipleExport ? , workbook ? , isBlob ? ) { return this . excelExportModule . Map ( this , excelExportProperties , isMultipleExport , workbook , true , isBlob ) ; } param { pdfExportProperties } PdfExportProperties param { isMultipleExport } isMultipleExport param { pdfDoc } pdfDoc param { boolean } isBlob return { Promise < any > } public pdfExport ( pdfExportProperties ? , isMultipleExport ? , pdfDoc ? , isBlob ? ) { return this . pdfExportModule . Map ( this , pdfExportProperties , isMultipleExport , pdfDoc , isBlob ) ; } param { string } columnName return { void } public groupColumn ( columnName ) { this . groupModule . groupColumn ( columnName ) ; } param { string } columnName return { void } public ungroupColumn ( columnName ) { this . groupModule . ungroupColumn ( columnName ) ; } hidden public isContextMenuOpen ( ) { return this . contextMenuModule && this . contextMenuModule . isOpen ; } hidden public ensureModuleInjected ( module ) { return this . getInjectedModules ( ) . indexOf ( module ) >= 0 ; } param { string [ ] } propertyNames public destroyTemplate ( propertyNames ? ) { this . clearTemplate ( propertyNames ) ; } } Grid . Inject ( Selection ) ;