import { isNullOrUndefined , extend , addClass } from '@syncfusion/ej2-base' ; import { attributes as addAttributes } from '@syncfusion/ej2-base' ; import { Column } from '../models/column' ; import { Row } from '../models/row' ; import { Cell } from '../models/cell' ; import { rowDataBound , queryCellInfo } from '../base/constant' ; import { setStyleAndAttributes , getObject } from '../base/util' ; import { ICellRenderer , IRowRenderer , IRow , QueryCellInfoEventArgs , RowDataBoundEventArgs , IGrid } from '../base/interface' ; import { CellType } from '../base/enum' ; import { CellRendererFactory } from '../services/cell-render-factory' ; import { ServiceLocator } from '../services/service-locator' ; import { CellMergeRender } from './cell-merge-renderer' ; hidden export class RowRenderer < T > implements IRowRenderer < T > { public element : Element ; private cellRenderer : ICellRenderer < T > ; private serviceLocator : ServiceLocator ; private cellType : CellType ; protected parent : IGrid ; constructor ( serviceLocator ? , cellType ? , parent ? ) { this . cellType = cellType ; this . serviceLocator = serviceLocator ; this . parent = parent ; this . element = this . parent . createElement ( 'tr' , { attrs : { role : 'row' } } ) ; } param { Column [ ] } columns param { Object } data param { { [ x : string ] : Object } } attributes param { string } rowTemplate public render ( row , columns , attributes ? , rowTemplate ? , cloneNode ? ) { return this . refreshRow ( row , columns , attributes , rowTemplate , cloneNode ) ; } param { Column [ ] } columns param { Object } data param { { [ x : string ] : Object } } attributes param { string } rowTemplate public refresh ( row , columns , isChanged , attributes ? , rowTemplate ? ) { if ( isChanged ) { row . data = extend ( { } , row . changes ) ; this . refreshMergeCells ( row ) ; } let node = this . parent . element . querySelector ( '[data-uid=' + row . uid + ']' ) ; let tr = this . refreshRow ( row , columns , attributes , rowTemplate ) ; let cells = [ ] . slice . call ( ( tr as HTMLTableRowElement ) . cells ) ; node . innerHTML = '' ; for ( let cell of cells ) { node . appendChild ( cell ) ; } } private refreshRow ( row , columns , attributes ? , rowTemplate ? , cloneNode ? ) { let tr = ! isNullOrUndefined ( cloneNode ) ? cloneNode : this . element . cloneNode ( ) as Element ; let rowArgs = { data : row . data } ; let cellArgs = { data : row . data } ; let attrCopy = extend ( { } , attributes , { } ) ; let chekBoxEnable = this . parent . getColumns ( ) . filter ( ( col ) => col . type === 'checkbox' && col . field ) [ 0 ] ; let value = false ; if ( chekBoxEnable ) { value = getObject ( chekBoxEnable . field , rowArgs . data ) ; } if ( row . isDataRow ) { row . isSelected = this . parent . getSelectedRowIndexes ( ) . indexOf ( row . index ) > - 1 || value ; } if ( row . isDataRow && this . parent . isCheckBoxSelection && this . parent . checkAllRows === 'Check' && this . parent . enableVirtualization ) { row . isSelected = true ; if ( this . parent . getSelectedRowIndexes ( ) . indexOf ( row . index ) === - 1 ) { this . parent . getSelectedRowIndexes ( ) . push ( row . index ) ; } } this . buildAttributeFromRow ( tr , row ) ; addAttributes ( tr , attrCopy as { [ x ] : string ; } ) ; setStyleAndAttributes ( tr , row . attributes ) ; let cellRendererFact = this . serviceLocator . getService < CellRendererFactory > ( 'cellRendererFactory' ) ; for ( let i = 0 , len = row . cells . length ; i < len ; i ++ ) { let cell = row . cells [ i ] ; cell . isSelected = row . isSelected ; let cellRenderer = cellRendererFact . getCellRenderer ( row . cells [ i ] . cellType || CellType . Data ) ; let attrs = { 'index' : ! isNullOrUndefined ( row . index ) ? row . index . toString ( ) : '' } ; if ( row . isExpand && row . cells [ i ] . cellType === CellType . DetailExpand ) { attrs [ 'class' ] = 'e-detailrowexpand' ; } let td = cellRenderer . render ( row . cells [ i ] , row . data , attrs ) ; if ( row . cells [ i ] . cellType !== CellType . Filter ) { if ( row . cells [ i ] . cellType === CellType . Data || row . cells [ i ] . cellType === CellType . CommandColumn ) { this . parent . trigger ( queryCellInfo , extend ( cellArgs , < QueryCellInfoEventArgs > { cell : td , column : < { } > cell . column , colSpan : 1 , foreignKeyData : row . cells [ i ] . foreignKeyData } ) ) ; if ( cellArgs . colSpan > 1 || row . cells [ i ] . cellSpan > 1 ) { let cellMerge = new CellMergeRender ( this . serviceLocator , this . parent ) ; td = cellMerge . render ( cellArgs , row , i , td ) ; } } if ( ! row . cells [ i ] . isSpanned ) { tr . appendChild ( td ) ; } } } let args = { row : tr , rowHeight : this . parent . rowHeight } ; if ( row . isDataRow ) { this . parent . trigger ( rowDataBound , extend ( rowArgs , args ) ) ; } if ( this . parent . enableVirtualization ) { rowArgs . rowHeight = this . parent . rowHeight ; } if ( rowArgs . rowHeight ) { ( tr as HTMLElement ) . style . height = rowArgs . rowHeight + 'px' ; } else if ( this . parent . rowHeight && ( tr . querySelector ( '.e-headercell' ) || tr . querySelector ( '.e-groupcaption' ) ) ) { ( tr as HTMLElement ) . style . height = this . parent . rowHeight + 'px' ; } if ( row . cssClass ) { tr . classList . add ( row . cssClass ) ; } if ( this . parent . element . scrollHeight > this . parent . height && this . parent . aggregates . length ) { for ( let i = 0 ; i < this . parent . aggregates . length ; i ++ ) { let property = 'properties' ; let column = 'columns' ; if ( this . parent . aggregates [ i ] [ property ] [ column ] [ 0 ] . footerTemplate ) { let summarycell = tr . querySelectorAll ( '.e-summarycell' ) ; if ( summarycell . length ) { let lastSummaryCell = ( summarycell [ summarycell . length - 1 ] ) as Element ; addClass ( [ lastSummaryCell ] , [ 'e-lastsummarycell' ] ) ; } } } } return tr ; } private refreshMergeCells ( row ) { for ( let cell of row . cells ) { cell . isSpanned = false ; } return row ; } param { Element } tr param { { [ x : string ] : Object } } attr public buildAttributeFromRow ( tr , row ) { let attr = { } ; let prop = { 'rowindex' : 'aria-rowindex' , 'dataUID' : 'data-uid' , 'ariaSelected' : 'aria-selected' } ; let classes = [ ] ; if ( row . isDataRow ) { classes . push ( 'e-row' ) ; } if ( row . isAltRow ) { classes . push ( 'e-altrow' ) ; } if ( ! isNullOrUndefined ( row . index ) ) { attr [ prop . rowindex ] = row . index ; } if ( row . rowSpan ) { attr . rowSpan = row . rowSpan ; } if ( row . uid ) { attr [ prop . dataUID ] = row . uid ; } if ( row . isSelected ) { attr [ prop . ariaSelected ] = true ; } if ( row . visible === false ) { classes . push ( 'e-hide' ) ; } attr . class = classes ; setStyleAndAttributes ( tr , attr ) ; } }