import { MouseEventArgs , Draggable } from '@syncfusion/ej2-base' ; import { extend } from '@syncfusion/ej2-base' ; import { remove , closest as closestElement , classList } from '@syncfusion/ej2-base' ; import { IGrid , IAction , NotifyArgs , EJ2Intance , IPosition } from '../base/interface' ; import { parentsUntil , removeElement , getPosition } from '../base/util' ; import * as events from '../base/constant' ; import { Column } from '../models/column' ; import { RowDropEventArgs } from '../base/interface' ; hidden export class RowDD implements IAction { private selectedRows : number [ ] = [ ] ; private isDragStop : boolean ; private helper : Function = ( e ) => { let gObj = this . parent ; if ( document . getElementsByClassName ( 'e-griddragarea' ) . length || ( ! ( e . sender . target as Element ) . classList . contains ( 'e-selectionbackground' ) && gObj . selectionSettings . type !== 'Single' ) ) { return false ; } let visualElement = this . parent . createElement ( 'div' , { className : 'e-cloneproperties e-draganddrop e-grid e-dragclone' , styles : 'height:"auto", z-index:2, width:' + gObj . element . offsetWidth } ) ; let table = this . parent . createElement ( 'table' , { styles : 'width:' + gObj . element . offsetWidth } ) ; let tbody = this . parent . createElement ( 'tbody' ) ; if ( gObj . selectionSettings . mode === 'Row' && gObj . selectionSettings . type === 'Single' ) { let index = parseInt ( ( e . sender . target as Element ) . parentElement . getAttribute ( 'aria-rowindex' ) , 10 ) ; gObj . selectRow ( index ) ; } let selectedRows = gObj . getSelectedRows ( ) ; for ( let i = 0 , len = selectedRows . length ; i < len ; i ++ ) { let selectedRow = selectedRows [ i ] . cloneNode ( true ) as Element ; removeElement ( selectedRow , '.e-indentcell' ) ; removeElement ( selectedRow , '.e-detailrowcollapse' ) ; removeElement ( selectedRow , '.e-detailrowexpand' ) ; tbody . appendChild ( selectedRow ) ; } table . appendChild ( tbody ) ; visualElement . appendChild ( table ) ; gObj . element . appendChild ( visualElement ) ; return visualElement ; } ; private dragStart : Function = ( e ) => { let gObj = this . parent ; if ( document . getElementsByClassName ( 'e-griddragarea' ) . length ) { return ; } gObj . trigger ( events . rowDragStart , { rows : gObj . getSelectedRows ( ) , target : e . target , draggableType : 'rows' , data : gObj . getSelectedRecords ( ) } ) ; let dropElem = document . getElementById ( gObj . rowDropSettings . targetID ) as EJ2Intance ; if ( gObj . rowDropSettings . targetID && dropElem && dropElem . ej2_instances ) { dropElem . ej2_instances [ 0 ] . getContent ( ) . classList . add ( 'e-allowRowDrop' ) ; } this . isDragStop = false ; } ; private drag : Function = ( e ) => { let gObj = this . parent ; let cloneElement = this . parent . element . querySelector ( '.e-cloneproperties' ) as HTMLElement ; let target = this . getElementFromPosition ( cloneElement , e . event ) ; classList ( cloneElement , [ 'e-defaultcur' ] , [ 'e-notallowedcur' ] ) ; gObj . trigger ( events . rowDrag , { rows : gObj . getSelectedRows ( ) , target : target , draggableType : 'rows' , data : gObj . getSelectedRecords ( ) } ) ; gObj . element . classList . add ( 'e-rowdrag' ) ; if ( ! parentsUntil ( target , 'e-gridcontent' ) || parentsUntil ( cloneElement . parentElement , 'e-grid' ) . id === parentsUntil ( target , 'e-grid' ) . id ) { classList ( cloneElement , [ 'e-notallowedcur' ] , [ 'e-defaultcur' ] ) ; } } ; private dragStop : Function = ( e ) => { let gObj = this . parent ; if ( this . parent . isDestroyed ) { return ; } let target = this . getElementFromPosition ( e . helper as HTMLElement , e . event ) ; gObj . element . classList . remove ( 'e-rowdrag' ) ; let dropElem = document . getElementById ( gObj . rowDropSettings . targetID ) as EJ2Intance ; if ( gObj . rowDropSettings . targetID && dropElem && dropElem . ej2_instances ) { dropElem . ej2_instances [ 0 ] . getContent ( ) . classList . remove ( 'e-allowRowDrop' ) ; } let args = { target : target , draggableType : 'rows' , cancel : false , rows : gObj . getSelectedRows ( ) , data : gObj . getSelectedRecords ( ) } ; gObj . trigger ( events . rowDrop , args ) ; if ( ! parentsUntil ( target , 'e-gridcontent' ) || args . cancel ) { remove ( e . helper ) ; return ; } } ; private parent : IGrid ; hidden constructor ( parent ? ) { this . parent = parent ; if ( this . parent . isDestroyed ) { return ; } this . parent . on ( events . initialEnd , this . initializeDrag , this ) ; this . parent . on ( events . columnDrop , this . columnDrop , this ) ; this . parent . on ( events . rowDragAndDropComplete , this . onActionComplete , this ) ; this . parent . on ( events . uiUpdate , this . enableAfterRender , this ) ; } private initializeDrag ( ) { let gObj = this . parent ; let column ; let drag ; drag = new Draggable ( gObj . getContent ( ) as HTMLElement , { dragTarget : '.e-rowcell' , distance : 5 , helper : this . helper , dragStart : this . dragStart , drag : this . drag , dragStop : this . dragStop } ) ; } private getElementFromPosition ( element , event ) { let target ; let position = getPosition ( event ) ; element . style . display = 'none' ; target = document . elementFromPoint ( position . x , position . y ) ; element . style . display = '' ; return target ; } return { void } hidden public onActionComplete ( e ) { this . parent . trigger ( events . actionComplete , extend ( e , { type : events . actionComplete } ) ) ; } private getTargetIdx ( targetRow ) { return targetRow ? parseInt ( targetRow . getAttribute ( 'aria-rowindex' ) , 10 ) : 0 ; } private columnDrop ( e ) { let gObj = this . parent ; if ( e . droppedElement . getAttribute ( 'action' ) !== 'grouping' ) { let targetRow = closestElement ( e . target , 'tr' ) ; let srcControl ; let currentIndex ; if ( e . droppedElement . parentElement . id !== gObj . element . id ) { srcControl = ( < EJ2Intance > e . droppedElement . parentElement ) . ej2_instances [ 0 ] ; } else { return ; } if ( srcControl . element . id !== gObj . element . id && srcControl . rowDropSettings . targetID !== gObj . element . id ) { return ; } let records = srcControl . getSelectedRecords ( ) ; let targetIndex = currentIndex = this . getTargetIdx ( targetRow ) ; let count = 0 ; if ( isNaN ( targetIndex ) ) { targetIndex = currentIndex = 0 ; } if ( gObj . allowPaging ) { targetIndex = targetIndex + ( gObj . pageSettings . currentPage * gObj . pageSettings . pageSize ) - gObj . pageSettings . pageSize ; } gObj . notify ( events . rowsAdded , { toIndex : targetIndex , records : records } ) ; gObj . notify ( events . modelChanged , { type : events . actionBegin , requestType : 'rowdraganddrop' } ) ; let selectedRows = srcControl . getSelectedRowIndexes ( ) ; let skip = srcControl . allowPaging ? ( srcControl . pageSettings . currentPage * srcControl . pageSettings . pageSize ) - srcControl . pageSettings . pageSize : 0 ; this . selectedRows = [ ] ; for ( let i = 0 , len = records . length ; i < len ; i ++ ) { this . selectedRows . push ( skip + selectedRows [ i ] ) ; } srcControl . notify ( events . rowsRemoved , { indexes : this . selectedRows , records : records } ) ; srcControl . notify ( events . modelChanged , { type : events . actionBegin , requestType : 'rowdraganddrop' } ) ; } } private enableAfterRender ( e ) { if ( e . module === this . getModuleName ( ) && e . enable ) { this . initializeDrag ( ) ; } } return { void } hidden public destroy ( ) { let gridElement = this . parent . element ; if ( this . parent . isDestroyed || ! gridElement || ( ! gridElement . querySelector ( '.e-gridheader' ) && ! gridElement . querySelector ( '.e-gridcontent' ) ) ) { return ; } this . parent . off ( events . initialEnd , this . initializeDrag ) ; this . parent . off ( events . columnDrop , this . columnDrop ) ; this . parent . off ( events . rowDragAndDropComplete , this . onActionComplete ) ; this . parent . off ( events . uiUpdate , this . enableAfterRender ) ; } private protected getModuleName ( ) { return 'rowDragAndDrop' ; } }