import { ChildProperty , compile as baseTemplateComplier , setValue , Internationalization } from '@syncfusion/ej2-base' ; import { extend as baseExtend , isNullOrUndefined , getValue , classList , NumberFormatOptions } from '@syncfusion/ej2-base' ; import { setStyleAttribute , addClass , attributes , remove , createElement , DateFormatOptions , removeClass } from '@syncfusion/ej2-base' ; import { IPosition , IGrid , IValueFormatter , IRow , ICell } from './interface' ; import { ServiceLocator } from '../services/service-locator' ; import { DataUtil , Query , DataManager , Predicate } from '@syncfusion/ej2-data' ; import { Column } from '../models/column' ; import { ColumnModel , AggregateColumnModel } from '../models/models' ; import { AggregateType } from './enum' ; import { Dialog , calculateRelativeBasedPosition , Popup , calculatePosition } from '@syncfusion/ej2-popups' ; import { PredicateModel } from './grid-model' ; param { Object } target param { string } checkFor returns hidden export function doesImplementInterface ( target , checkFor ) { return ( < any > target ) . prototype && checkFor in ( < any > target ) . prototype ; } param { string } field param { Object } data param { IColumn } column hidden export function valueAccessor ( field , data , column ) { field = isNullOrUndefined ( field ) ? '' : field ; return DataUtil . getObject ( field , data ) ; } param { Function } fn return { Promise < T > } hidden export function getUpdateUsingRaf < T > ( updateFunction , callBack ) { requestAnimationFrame ( ( ) => { try { callBack ( null , updateFunction ( ) ) ; } catch ( e ) { callBack ( e ) ; } } ) ; } hidden export function iterateArrayOrObject < T , U > ( collection , predicate ) { let result = [ ] ; for ( let i = 0 , len = collection . length ; i < len ; i ++ ) { let pred = predicate ( collection [ i ] , i ) ; if ( ! isNullOrUndefined ( pred ) ) { result . push ( < T > pred ) ; } } return result ; } hidden export function iterateExtend ( array ) { let obj = [ ] ; for ( let i = 0 ; i < array . length ; i ++ ) { obj . push ( baseExtend ( { } , getActualProperties ( array [ i ] ) , { } , true ) ) ; } return obj ; } hidden export function templateCompiler ( template ) { if ( template ) { let e ; try { if ( document . querySelectorAll ( template ) . length ) { return baseTemplateComplier ( document . querySelector ( template ) . innerHTML . trim ( ) ) ; } } catch ( e ) { return baseTemplateComplier ( template ) ; } } return undefined ; } hidden export function setStyleAndAttributes ( node , customAttributes ) { let copyAttr = { } ; let literals = [ 'style' , 'class' ] ; baseExtend ( copyAttr , customAttributes , { } ) ; if ( 'style' in copyAttr ) { setStyleAttribute ( node as HTMLElement , copyAttr [ literals [ 0 ] ] as { [ x ] : Object ; } ) ; delete copyAttr [ literals [ 0 ] ] ; } if ( 'class' in copyAttr ) { addClass ( [ node ] , copyAttr [ literals [ 1 ] ] as string | string [ ] ) ; delete copyAttr [ literals [ 1 ] ] ; } attributes ( node , copyAttr as { [ x ] : string ; } ) ; } hidden export function extend ( copied , first , second ? , exclude ? ) { let moved = baseExtend ( copied , first , second ) ; Object . keys ( moved ) . forEach ( ( value , index ) => { if ( exclude . indexOf ( value ) !== - 1 ) { delete moved [ value ] ; } } ) ; return moved ; } hidden export function prepareColumns ( columns , autoWidth ? ) { for ( let c = 0 , len = columns . length ; c < len ; c ++ ) { let column ; if ( typeof columns [ c ] === 'string' ) { column = new Column ( { field : < string > columns [ c ] } ) ; } else if ( ! ( columns [ c ] instanceof Column ) ) { if ( ! ( columns [ c ] as Column ) . columns ) { column = new Column ( columns [ c ] as Column ) ; } else { column = new Column ( columns [ c ] as Column ) ; ( columns [ c ] as Column ) . columns = prepareColumns ( ( columns [ c ] as Column ) . columns ) ; } } else { column = < Column > columns [ c ] ; } column . headerText = isNullOrUndefined ( column . headerText ) ? column . foreignKeyValue || column . field || '' : column . headerText ; column . foreignKeyField = column . foreignKeyField || column . field ; column . valueAccessor = ( typeof column . valueAccessor === 'string' ? getValue ( < string > column . valueAccessor , window ) : column . valueAccessor ) || valueAccessor ; column . width = autoWidth && isNullOrUndefined ( column . width ) ? 200 : column . width ; if ( isNullOrUndefined ( column . visible ) ) { column . visible = true ; } columns [ c ] = column ; } return columns as Column [ ] ; } hidden export function setCssInGridPopUp ( popUp , e , className ) { let popUpSpan = popUp . querySelector ( 'span' ) ; let position = popUp . parentElement . getBoundingClientRect ( ) ; let targetPosition = ( e . target as HTMLElement ) . getBoundingClientRect ( ) ; let isBottomTail ; popUpSpan . className = className ; popUp . style . display = '' ; isBottomTail = ( isNullOrUndefined ( ( e as MouseEvent ) . clientY ) ? ( e as TouchEvent ) . changedTouches [ 0 ] . clientY : ( e as MouseEvent ) . clientY ) > popUp . offsetHeight + 10 ; popUp . style . top = targetPosition . top - position . top + ( isBottomTail ? - ( popUp . offsetHeight + 10 ) : popUp . offsetHeight + 10 ) + 'px' ; popUp . style . left = getPopupLeftPosition ( popUp , e , targetPosition , position . left ) + 'px' ; if ( isBottomTail ) { ( popUp . querySelector ( '.e-downtail' ) as HTMLElement ) . style . display = '' ; ( popUp . querySelector ( '.e-uptail' ) as HTMLElement ) . style . display = 'none' ; } else { ( popUp . querySelector ( '.e-downtail' ) as HTMLElement ) . style . display = 'none' ; ( popUp . querySelector ( '.e-uptail' ) as HTMLElement ) . style . display = '' ; } } hidden function getPopupLeftPosition ( popup , e , targetPosition , left ) { let width = popup . offsetWidth / 2 ; let x = getPosition ( e ) . x ; if ( x - targetPosition . left < width ) { return targetPosition . left - left ; } else if ( targetPosition . right - x < width ) { return targetPosition . right - left - width * 2 ; } else { return x - left - width ; } } hidden export function getActualProperties < T > ( obj ) { if ( obj instanceof ChildProperty ) { return < T > getValue ( 'properties' , obj ) ; } else { return obj ; } } hidden export function parentsUntil ( elem , selector , isID ? ) { let parent = elem ; while ( parent ) { if ( isID ? parent . id === selector : parent . classList . contains ( selector ) ) { break ; } parent = parent . parentElement ; } return parent ; } hidden export function getElementIndex ( element , elements ) { let index = - 1 ; for ( let i = 0 , len = elements . length ; i < len ; i ++ ) { if ( elements [ i ] . isEqualNode ( element ) ) { index = i ; break ; } } return index ; } hidden export function inArray ( value , collection ) { for ( let i = 0 , len = collection . length ; i < len ; i ++ ) { if ( collection [ i ] === value ) { return i ; } } return - 1 ; } hidden export function getActualPropFromColl ( collection ) { let coll = [ ] ; for ( let i = 0 , len = collection . length ; i < len ; i ++ ) { if ( collection [ i ] . hasOwnProperty ( 'properties' ) ) { coll . push ( ( collection [ i ] as { properties : Object ; } ) . properties ) ; } else { coll . push ( collection [ i ] ) ; } } return coll ; } hidden export function removeElement ( target , selector ) { let elements = [ ] . slice . call ( target . querySelectorAll ( selector ) ) ; for ( let i = 0 ; i < elements . length ; i ++ ) { remove ( elements [ i ] ) ; } } hidden export function getPosition ( e ) { let position = { } as IPosition ; position . x = ( isNullOrUndefined ( ( e as MouseEvent ) . clientX ) ? ( e as TouchEvent ) . changedTouches [ 0 ] . clientX : ( e as MouseEvent ) . clientX ) ; position . y = ( isNullOrUndefined ( ( e as MouseEvent ) . clientY ) ? ( e as TouchEvent ) . changedTouches [ 0 ] . clientY : ( e as MouseEvent ) . clientY ) ; return position ; } let uid = 0 ; hidden export function getUid ( prefix ) { return prefix + uid ++ ; } hidden export function appendChildren ( elem , children ) { for ( let i = 0 , len = children . length ; i < len ; i ++ ) { if ( len === children . length ) { elem . appendChild ( children [ i ] ) ; } else { elem . appendChild ( children [ 0 ] ) ; } } return elem as Element ; } hidden export function parents ( elem , selector , isID ? ) { let parent = elem ; let parents = [ ] ; while ( parent ) { if ( isID ? parent . id === selector : parent . classList . contains ( selector ) ) { parents . push ( parent ) ; } parent = parent . parentElement ; } return parents ; } hidden export function calculateAggregate ( type , data , column ? , context ? ) { if ( type === 'Custom' ) { let temp = column . customAggregate as Function ; if ( typeof temp === 'string' ) { temp = getValue ( temp , window ) ; } return temp ? temp . call ( context , data , column ) : '' ; } return ( column . field in data || data instanceof Array ) ? DataUtil . aggregates [ type . toLowerCase ( ) ] ( data , column . field ) : null ; } hidden let scrollWidth = null ; hidden export function getScrollBarWidth ( ) { if ( scrollWidth !== null ) { return scrollWidth ; } let divNode = document . createElement ( 'div' ) ; let value = 0 ; divNode . style . cssText = 'width:100px;height: 100px;overflow: scroll;position: absolute;top: -9999px;' ; document . body . appendChild ( divNode ) ; value = ( divNode . offsetWidth - divNode . clientWidth ) | 0 ; document . body . removeChild ( divNode ) ; return scrollWidth = value ; } hidden let rowHeight ; hidden export function getRowHeight ( element ? ) { if ( rowHeight !== undefined ) { return rowHeight ; } let table = < HTMLTableElement > createElement ( 'table' , { className : 'e-table' , styles : 'visibility: hidden' } ) ; table . innerHTML = '<tr><td class="e-rowcell">A<td></tr>' ; element . appendChild ( table ) ; let rect = table . querySelector ( 'td' ) . getBoundingClientRect ( ) ; element . removeChild ( table ) ; rowHeight = Math . ceil ( rect . height ) ; return rowHeight ; } hidden export function isComplexField ( field ) { return field . split ( '.' ) . length > 1 ; } hidden export function getComplexFieldID ( field = '' ) { return field . replace ( /\./g , '_' ) ; } hidden export function setComplexFieldID ( field = '' ) { return field . replace ( /_/g , '.' ) ; } hidden export function isEditable ( col , type , elem ) { let row = parentsUntil ( elem , 'e-row' ) ; let isOldRow = ! row ? true : row && ! row . classList . contains ( 'e-insertedrow' ) ; if ( type === 'beginEdit' && isOldRow ) { if ( col . isIdentity || col . isPrimaryKey || ! col . allowEditing ) { return false ; } return true ; } else if ( type === 'add' && col . isIdentity && col . isPrimaryKey ) { return false ; } else { if ( isOldRow && ! col . allowEditing && ! col . isIdentity && ! col . isPrimaryKey ) { return false ; } return true ; } } hidden export function isActionPrevent ( inst ) { let dlg = inst . element . querySelector ( '#' + inst . element . id + 'EditConfirm' ) as HTMLElement ; return inst . editSettings . mode === 'Batch' && ( inst . element . querySelectorAll ( '.e-updatedtd' ) . length ) && inst . editSettings . showConfirmDialog && ( dlg ? dlg . classList . contains ( 'e-popup-close' ) : true ) ; } hidden export function wrap ( elem , action ) { let clName = 'e-wrap' ; elem = elem instanceof Array ? elem : [ elem ] ; for ( let i = 0 ; i < elem . length ; i ++ ) { action ? elem [ i ] . classList . add ( clName ) : elem [ i ] . classList . remove ( clName ) ; } } hidden export function setFormatter ( serviceLocator ? , column ? ) { let fmtr = serviceLocator . getService < IValueFormatter > ( 'valueFormatter' ) ; switch ( column . type ) { case 'date' : column . setFormatter ( fmtr . getFormatFunction ( { type : 'date' , skeleton : column . format } as DateFormatOptions ) ) ; column . setParser ( fmtr . getParserFunction ( { type : 'date' , skeleton : column . format } as DateFormatOptions ) ) ; break ; case 'datetime' : column . setFormatter ( fmtr . getFormatFunction ( { type : 'dateTime' , skeleton : column . format } as DateFormatOptions ) ) ; column . setParser ( fmtr . getParserFunction ( { type : 'dateTime' , skeleton : column . format } as DateFormatOptions ) ) ; break ; case 'number' : column . setFormatter ( fmtr . getFormatFunction ( { format : column . format } as NumberFormatOptions ) ) ; column . setParser ( fmtr . getParserFunction ( { format : column . format } as NumberFormatOptions ) ) ; break ; } } hidden export function addRemoveActiveClasses ( cells , add , ... args ) { for ( let i = 0 , len = cells . length ; i < len ; i ++ ) { if ( add ) { classList ( cells [ i ] , [ ... args ] , [ ] ) ; cells [ i ] . setAttribute ( 'aria-selected' , 'true' ) ; } else { classList ( cells [ i ] , [ ] , [ ... args ] ) ; cells [ i ] . removeAttribute ( 'aria-selected' ) ; } } } hidden export function distinctStringValues ( result ) { let temp = { } ; let res = [ ] ; for ( let i = 0 ; i < result . length ; i ++ ) { if ( ! ( result [ i ] in temp ) ) { res . push ( result [ i ] . toString ( ) ) ; temp [ result [ i ] ] = 1 ; } } return res ; } hidden export function getFilterMenuPostion ( target , dialogObj , grid ) { let elementVisible = dialogObj . element . style . display ; dialogObj . element . style . display = 'block' ; let dlgWidth = dialogObj . width as number ; let newpos ; if ( ! grid . enableRtl ) { newpos = calculateRelativeBasedPosition ( ( < HTMLElement > target ) , dialogObj . element ) ; dialogObj . element . style . display = elementVisible ; dialogObj . element . style . top = ( newpos . top + target . getBoundingClientRect ( ) . height ) - 5 + 'px' ; let leftPos = ( ( newpos . left - dlgWidth ) + target . clientWidth ) ; if ( leftPos < 1 ) { dialogObj . element . style . left = ( dlgWidth + leftPos ) - 16 + 'px' ; } else { dialogObj . element . style . left = leftPos + - 4 + 'px' ; } } else { newpos = calculatePosition ( ( < HTMLElement > target ) , 'left' , 'bottom' ) ; dialogObj . element . style . top = ( newpos . top + target . getBoundingClientRect ( ) . height ) - 35 + 'px' ; dialogObj . element . style . display = elementVisible ; let leftPos = ( ( newpos . left - dlgWidth ) + target . clientWidth ) ; if ( leftPos < 1 ) { dialogObj . element . style . left = ( dlgWidth + leftPos ) + - 16 + 'px' ; } else { dialogObj . element . style . left = leftPos - 16 + 'px' ; } } } hidden export function getZIndexCalcualtion ( args , dialogObj ) { args . popup . element . style . zIndex = ( dialogObj . zIndex + 1 ) . toString ( ) ; } hidden export function toogleCheckbox ( elem ) { let span = elem . querySelector ( '.e-frame' ) ; span . classList . contains ( 'e-check' ) ? classList ( span , [ 'e-uncheck' ] , [ 'e-check' ] ) : classList ( span , [ 'e-check' ] , [ 'e-uncheck' ] ) ; } hidden export function createCboxWithWrap ( uid , elem , className ? ) { let div = createElement ( 'div' , { className : className } ) ; div . appendChild ( elem ) ; div . setAttribute ( 'uid' , uid ) ; return div ; } hidden export function removeAddCboxClasses ( elem , checked ) { removeClass ( [ elem ] , [ 'e-check' , 'e-stop' , 'e-uncheck' ] ) ; if ( checked ) { elem . classList . add ( 'e-check' ) ; } else { elem . classList . add ( 'e-uncheck' ) ; } } param row param columns param data hidden export function refreshForeignData ( row , columns , data ) { columns . forEach ( ( col ) => { setValue ( col . field , getForeignData ( col , data ) , row . foreignKeyData ) ; } ) ; row . cells . forEach ( ( cell ) => { if ( cell . isForeignKey ) { setValue ( 'foreignKeyData' , getValue ( cell . column . field , row . foreignKeyData ) , cell ) ; } } ) ; } param column param data param lValue param foreignData hidden export function getForeignData ( column , data ? , lValue ? , foreignKeyData ? ) { let fField = column . foreignKeyField ; let key = < string | Date > ( lValue || valueAccessor ( column . field , data , column ) ) ; key = isNullOrUndefined ( key ) ? '' : key ; let query = new Query ( ) ; let fdata = foreignKeyData || ( ( column . dataSource instanceof DataManager ) && column . dataSource . dataSource . json . length ? ( < DataManager > column . dataSource ) . dataSource . json : column . columnData ) ; if ( ( < Date > key ) . getDay ) { query . where ( getDatePredicate ( { field : fField , operator : 'equal' , value : key , matchCase : false } ) ) ; } else { query . where ( fField , '==' , key , false ) ; } return new DataManager ( fdata ) . executeLocal ( query ) ; } param foreignKeyValue param columns hidden export function getColumnByForeignKeyValue ( foreignKeyValue , columns ) { let column ; return columns . some ( ( col ) => { column = col ; return col . foreignKeyValue === foreignKeyValue ; } ) && column ; } hidden param filterObject export function getDatePredicate ( filterObject , type ? ) { let datePredicate ; let prevDate ; let nextDate ; let prevObj = baseExtend ( { } , getActualProperties ( filterObject ) ) as PredicateModel ; let nextObj = baseExtend ( { } , getActualProperties ( filterObject ) ) as PredicateModel ; let value = new Date ( filterObject . value as string ) ; if ( filterObject . operator === 'equal' || filterObject . operator === 'notequal' ) { if ( type === 'datetime' ) { prevDate = new Date ( value . setSeconds ( value . getSeconds ( ) - 1 ) ) ; nextDate = new Date ( value . setSeconds ( value . getSeconds ( ) + 2 ) ) ; filterObject . value = new Date ( value . setSeconds ( nextDate . getSeconds ( ) - 1 ) ) ; } else { prevDate = new Date ( value . setHours ( 0 ) - 1 ) ; nextDate = new Date ( value . setHours ( 24 ) ) ; } prevObj . value = prevDate ; nextObj . value = nextDate ; if ( filterObject . operator === 'equal' ) { prevObj . operator = 'greaterthan' ; nextObj . operator = 'lessthan' ; } else if ( filterObject . operator === 'notequal' ) { prevObj . operator = 'lessthanorequal' ; nextObj . operator = 'greaterthanorequal' ; } let predicateSt = new Predicate ( prevObj . field , prevObj . operator , prevObj . value , false ) ; let predicateEnd = new Predicate ( nextObj . field , nextObj . operator , nextObj . value , false ) ; datePredicate = filterObject . operator === 'equal' ? predicateSt . and ( predicateEnd ) : predicateSt . or ( predicateEnd ) ; } else { if ( typeof ( prevObj . value ) === 'string' ) { prevObj . value = new Date ( prevObj . value ) ; } let predicates = new Predicate ( prevObj . field , prevObj . operator , prevObj . value , false ) ; datePredicate = predicates ; } if ( ( < { setProperties : Function ; } > filterObject ) . setProperties ) { ( < { setProperties : Function ; } > filterObject ) . setProperties ( { ejpredicate : datePredicate } , true ) ; } else { filterObject . ejpredicate = datePredicate ; } return datePredicate ; } hidden export function renderMovable ( ele , frzCols ) { let mEle = ele . cloneNode ( true ) as Element ; for ( let i = 0 ; i < frzCols ; i ++ ) { mEle . removeChild ( mEle . children [ 0 ] ) ; } for ( let i = frzCols , len = ele . childElementCount ; i < len ; i ++ ) { ele . removeChild ( ele . children [ ele . childElementCount - 1 ] ) ; } return mEle ; } export function getObject ( field = '' , object ? ) { if ( field ) { let value = object ; let splits = field . split ( '.' ) ; for ( let i = 0 ; i < splits . length && ! isNullOrUndefined ( value ) ; i ++ ) { value = value [ splits [ i ] ] ; } return value as string ; } } export function getCustomDateFormat ( format , colType ) { let intl = new Internationalization ( ) ; let formatvalue ; let formatter = 'format' ; let type = 'type' ; if ( colType === 'date' ) { formatvalue = typeof ( format ) === 'object' ? intl . getDatePattern ( { type : format [ type ] ? format [ type ] : 'date' , format : format [ formatter ] } , false ) : intl . getDatePattern ( { type : 'date' , skeleton : format } , false ) ; } else { formatvalue = typeof ( format ) === 'object' ? intl . getDatePattern ( { type : format [ type ] ? format [ type ] : 'dateTime' , format : format [ formatter ] } , false ) : intl . getDatePattern ( { type : 'dateTime' , skeleton : format } , false ) ; } return formatvalue ; }