How to customize Drag and Drop operation of Tree Grid
We can customize row DragandDrop operation using Events such as rowDrop ,rowDragStartHelper, rowDragStart of Tree Grid.
Here is the list of customizations that we have used in Drag and Drop operation.
- Hide Drag Icon of particular row using rowDataBound event and prevent Drag using rowDragStartHelper
- Dragged rows can only be dropped in specific locations using rowDrop event.
- Customize the clone element using rowDragStart event.
- Hide Drag Icon of particular row using rowDataBound event and prevent Drag using rowDragStartHelper
This is demonstrated in the below sample code in which we have used rowDataBound event to hide the Drag Icon by empty the corresponding td in TreeGrid row. Also we have cancel the drag operation of this corresponding row by giving args.cancel as true.
JS
let treegrid: TreeGrid = new TreeGrid( { dataSource: dragData, allowRowDragAndDrop: true, allowPaging:true, pageSettings: { pageSize: 10, pageCount: 2, pageSizes: true }, childMapping: 'subtasks', height: '400', allowSelection: true, treeColumnIndex: 1, selectionSettings: { type: 'Multiple' }, columns: [ { field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, textAlign: 'Right', width: 100 }, { field: 'taskName', headerText: 'Task Name', width: 250 }, { field: 'startDate', headerText: 'Start Date', textAlign: 'Right', width: 135, format: { skeleton: 'yMd', type: 'date' }}, { field: 'endDate', headerText: 'End Date', textAlign: 'Right', width: 135, format: { skeleton: 'yMd', type: 'date' }}, { field: 'duration', headerText: 'Duration', textAlign: 'Right', width: 120 }, { field: 'progress', headerText: 'Progress', textAlign: 'Right', width: 120 }, { field: 'priority', headerText: 'Priority', textAlign: 'Left', width: 135 }, ], }); treegrid.appendTo('#TreeGrid'); treegrid.rowDataBound = function (args) { if (args.data.taskID == 1) { args.row.querySelector('td').innerHTML = " "; //hide the DragIcon(td element) } }; treegrid.rowDragStartHelper = function (args) { if (args.data[0].taskID == 1) { args.cancel = 'true'; //prevent Drag operations by setting args.cancel as true } };
Output
Fig 1: DragIcon hides for first row
- Dragged rows can only be dropped in specific locations using rowDrop event and show indicator using rowDrag.
This is demonstrated in the below sample code in which we have prevented the drop action for the specific location(for ex:- parent records) using rowDrop event of the TreeGrid. In this event, we have cancel the drop action for the parent row by giving args.cancel as true and displayed an alert message ‘Dropping disabled for parent row” when we drop the dragged rows on the parent row. Also we have shown Indicator(no-drop)icon for the cloned element dynamically to indicate which records has been prevented from drop action using rowDrag event.
JS
let treegrid: TreeGrid = new TreeGrid( { dataSource: dragData, allowRowDragAndDrop: true, allowPaging:true, pageSettings: { pageSize: 10, pageCount: 2, pageSizes: true }, childMapping: 'subtasks', height: '400', allowSelection: true, treeColumnIndex: 1, selectionSettings: { type: 'Multiple' }, columns: [ { field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, textAlign: 'Right', width: 100 }, { field: 'taskName', headerText: 'Task Name', width: 250 }, { field: 'startDate', headerText: 'Start Date', textAlign: 'Right', width: 135, format: { skeleton: 'yMd', type: 'date' }}, { field: 'endDate', headerText: 'End Date', textAlign: 'Right', width: 135, format: { skeleton: 'yMd', type: 'date' }}, { field: 'duration', headerText: 'Duration', textAlign: 'Right', width: 120 }, { field: 'progress', headerText: 'Progress', textAlign: 'Right', width: 120 }, { field: 'priority', headerText: 'Priority', textAlign: 'Left', width: 135 }, ], }); treegrid.appendTo('#TreeGrid'); treegrid.rowDrop: function(args) { var treeGridobj = document.getElementsByClassName("e-treegrid")[0].ej2_instances; var data = treeGridobj[0].getCurrentViewRecords()[args.dropIndex]; if (data.hasChildRecords) { //apply your own customized condition args.cancel = 'true' alert("dropping disabled for parent row") //alert message while dropping on parent row } }; treegrid.rowDrag: function(args) { let rowEle: Element = args.target ? args.target.closest('tr') : null; let rowIdx: number = rowEle ? (rowEle as HTMLTableRowElement).rowIndex : -1; let currentData: ITreeData = this.getCurrentViewRecords()[rowIdx]; if (rowIdx !== -1) { if (currentData.hasChildRecords) this.rowDragAndDropModule.addErrorElem(); //shown (no drop) icon for the parent records } }
Output
Fig 2: Drop operation prevented for parent record
3. Customize the clone element using rowDragStart event.
This is demonstrated in the below sample code in which we can customize the clone element using rowDragStart event of TreeGrid. In this event, we have modified the font family of the dragged or cloned element.
JS
let treegrid: TreeGrid = new TreeGrid( { dataSource: dragData, allowRowDragAndDrop: true, allowPaging:true, pageSettings: { pageSize: 10, pageCount: 2, pageSizes: true }, childMapping: 'subtasks', height: '400', allowSelection: true, treeColumnIndex: 1, selectionSettings: { type: 'Multiple' }, columns: [ { field: 'taskID', headerText: 'Task ID', isPrimaryKey: true, textAlign: 'Right', width: 100 }, { field: 'taskName', headerText: 'Task Name', width: 250 }, { field: 'startDate', headerText: 'Start Date', textAlign: 'Right', width: 135, format: { skeleton: 'yMd', type: 'date' }}, { field: 'endDate', headerText: 'End Date', textAlign: 'Right', width: 135, format: { skeleton: 'yMd', type: 'date' }}, { field: 'duration', headerText: 'Duration', textAlign: 'Right', width: 120 }, { field: 'progress', headerText: 'Progress', textAlign: 'Right', width: 120 }, { field: 'priority', headerText: 'Priority', textAlign: 'Left', width: 135 }, ], }); treegrid.appendTo('#TreeGrid'); treegrid.rowDragStart: function(args) { args.rows[0].classList.add('e-dragclonerow'); //customize the dragged row here }
<style> .e-dragclonerow { font-family: fantasy; } </style>
Output
Fig 3: Customization shown for dragged row
Sample Links: -
JavaScript Platform: - JavaScriptDemo
React Platform: - ReactDemo
Angular Platform:- AngularDemo
Vue Platform:- Vue Demo