How to disable row sorting, once enabled, on Flexgrid

Posted by: dharric on 9 January 2019, 9:37 am EST

    • Post Options:
    • Link

    Posted 9 January 2019, 9:37 am EST

    I am using the code below to enable sorting on my flexgrid. The sorting works well, but even after disabling sorting and having the drag related events disabled–the sorting does not turn off.

    
    <FlexGrid
                            autoGenerateColumns={false}
                            columns={colDefs}
                            itemsSource={collView}
                            style={{ maxHeight: '300px', width: '1300px' }}
                            initialized={this.initializedGrid}
                            selectionMode={SelectionMode.cell}
                            isReadOnly={Boolean(true)}
                            selectionChanged={this.gridSelectionChanged}
                            formatItem={this.formatItem}
                            itemFormatter={this.itemFormatter}
                        />
    
    export const SelectionMode = {
        none: 0,
        cell: 1, 
        cellRange: 2,
        row: 3,
        rowRange: 4,
        listBox: 5
    }
    
    // !!! NOTE YOU MUST IMPLEMENT FUNCTION ItemFormatter on the grid and create enableSort state property !!!
    export const AllowRowDragAndDrop = (self, CellType, isGrouped = true) => {
        let dragRow = null;
        let dragColumn = null;
        let dropRow = null;
        function mousedown(e) {
            if (self.grid.hitTest(e).cellType === CellType.Cell) {
                e.stopPropagation();
            };
        }
        function dragstart(e) {
            //if (e.panel.rows[e.row] instanceof GroupRow) {
            //    return;
            //}
            dragRow = null;
            var ht = self.grid.hitTest(e);
            if (ht.cellType === CellType.Cell) {
                dragRow = ht.row;
                e.dataTransfer.effectAllowed = 'copy';
                e.dataTransfer.setData('text', '');
            };
        }
        function dragover(e) {
            if (dragRow != null) {
                var ht = self.grid.hitTest(e);
                if (ht.cellType === CellType.Cell) {
                    dropRow = ht.row;
                }
                e.dataTransfer.dropEffect = 'copy';
                e.preventDefault();
            }
        }
        function drop(e) {
            if (dragRow != null) {
                const ddata = {};
                const dragParentGroupings = [];
                const dropParentGroupings = [];
                if (isGrouped) {
                    // dragRow and dropRow is based on a grouped grid, which includes additional rows for groupings
                    // must remove these additional rows to get correct index
                    const items = self.grid.itemsSource.items;
                    const uniqueParentGroups = [...new Set(items.map((grp, index) => {
                        return grp.entity;
                    }))];
                    const actualRowsInGrid = []; // as opposed to rows in data set
                    for (let g = 0; g < uniqueParentGroups.length; g++) {
                        const currentGroup = uniqueParentGroups[g];
                        actualRowsInGrid.push({ isParent: true, entity: currentGroup });
                        const currentGroupRows = items.filter(item => {
                            item.isParent = false;
                            return item.entity === currentGroup;
                        });
                        for (let r = 0; r < currentGroupRows.length; r++) {
                            actualRowsInGrid.push(currentGroupRows[r]);
                        }
                    }
                    // use actual rows in grid to determine the grouping offset
                    const endDragRange = dragRow;                
                    const dragRowItems = actualRowsInGrid.slice(0, endDragRange);                
                    dragRowItems.forEach((item) => { 
                        if (!dragParentGroupings.includes(item.entity)) {
                            dragParentGroupings.push(item.entity);
                        }
                    });
    
                    const endDropRange = dropRow;
                    const dropRowItems = actualRowsInGrid.slice(0, endDropRange);
                    dropRowItems.forEach((item) => {
                        if (!dropParentGroupings.includes(item.entity)) {
                            dropParentGroupings.push(item.entity);
                        }
                    });
    
                    if (dropParentGroupings.length !== dragParentGroupings.length) {
                        dragRow = null;
                        return;
                    }
                }
    
                // grouped grids cells are offset by number of parent groupings above the cell, non-grouped are offset by 1
                const dragGroupingOffset = -1 * dragParentGroupings.length; 
                const dropGroupingOffset = -1 * dropParentGroupings.length;
                dropRow += dropGroupingOffset;
                dragRow += dragGroupingOffset;
    
                const dropRowKeys = Object.keys(self.grid.itemsSource.items[dropRow]);
                for (let dropKey of dropRowKeys) {
                    ddata[dropKey] = self.grid.itemsSource.items[dropRow][dropKey];
                }
    
                const dragRowKeys = Object.keys(self.grid.itemsSource.items[dragRow]);
                for (let dragKey of dragRowKeys) {
                    self.grid.itemsSource.items[dropRow][dragKey] = self.grid.itemsSource.items[dragRow][dragKey];
                }
    
                for (let dropKey of dropRowKeys) {
                    self.grid.itemsSource.items[dragRow][dropKey] = ddata[dropKey];
                }
    
                self.grid.refresh();
    
                dragRow = null;
            }
        }
    
        if (!self.state.enableSort) {
            // self.grid.hostElement.removeEventListener('mousedown', mousedown);
            self.grid.hostElement.removeEventListener('dragstart', dragstart);
            self.grid.hostElement.removeEventListener('dragover', dragover);
            self.grid.hostElement.removeEventListener('drop', drop);
        } else {
            // self.grid.hostElement.addEventListener('mousedown', mousedown, true);
            self.grid.hostElement.addEventListener('dragstart', dragstart);
            self.grid.hostElement.addEventListener('dragover', dragover);
            self.grid.hostElement.addEventListener('drop', drop);
        }
    }
    
    
    // WEBPACK FOOTER //
    // src/common/services/GridHelper.js
    
  • Posted 9 January 2019, 10:14 am EST

    Sorry I meant drag and drop not sort.

  • Posted 10 January 2019, 1:59 am EST

    Hi,

    The issue here is that the eventListeners are not actually removed from the grid’s host. Since, drop, dragstart, etc. functions are defined locally inside the ‘AllowRowDragAndDrop’ function, a new object is created for functions each time ‘AllowRowDragAndDrop’ is called and due to which removeEventListener() method identifies them as the completely different functions than the previous ones so they are not removed.

    What we could do is save the instances of the event handlers attached and then remove them whenever required.

    Please refer to the following code snippet:

    
    if (!self.state.enableSort) {
            // self.grid.hostElement.removeEventListener('mousedown', mousedown);
            //self.grid.hostElement.removeEventListener('dragstart', dragstart);
            //self.grid.hostElement.removeEventListener('dragover', dragover);
            //self.grid.hostElement.removeEventListener('drop', drop);
    
    	// remove listeners
    	let listeners = self.grid.hostElement['_handlersToBeRemoved'];
    	if(listeners){
    		listeners.forEach(listener => {
    			self.grid.hostElement.removeEventListener(listener.eventName, listener.functionInstance);
    		});
    		// listeners removed, clear list
    		self.grid.hostElement['_handlersToBeRemoved'] = [];
    	}
        } else {
            // self.grid.hostElement.addEventListener('mousedown', mousedown, true);
            self.grid.hostElement.addEventListener('dragstart', dragstart);
            self.grid.hostElement.addEventListener('dragover', dragover);
            self.grid.hostElement.addEventListener('drop', drop);
    	// save instances to be removed later
    	if(!self.grid.hostElement['_handlersToBeRemoved']){
    		self.grid.hostElement['_handlersToBeRemoved'] = [];
    	}
    	self.grid.hostElement['_handlersToBeRemoved'].push({
    		eventName: 'dragstart',
    		functionInstance: dragstart
    	});
    	self.grid.hostElement['_handlersToBeRemoved'].push({
    		eventName: 'dragover',
    		functionInstance: dragover
    	});
    	self.grid.hostElement['_handlersToBeRemoved'].push({
    		eventName: 'drop',
    		functionInstance: drop
    	});
        }
    

    Also please make sure that remove listener part is executed at the right time.

    ~Sharad

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels