Arrastar linha em Web Components grade de árvore

    The Ignite UI for Web Components Row Dragging feature in Web Components Tree Grid is easily configurable and is used for rearranging rows within the grid by dragging and dropping them to a new position using the mouse. It is initialized on the root IgcTreeGridComponent component and is configurable via the RowDraggable input.

    Web Components Tree Grid Row Drag Example

    Configuração

    In order to enable row-dragging for your IgcTreeGridComponent, all you need to do is set the grid's RowDraggable to true. Once this is enabled, a row-drag handle will be displayed on each row. This handle can be used to initiate row dragging. Clicking on the drag-handle and moving the cursor while holding down the button will cause the grid's RowDragStart event to fire. Releasing the click at any time will cause RowDragEnd event to fire.

    <igc-tree-grid row-draggable="true">
    </igc-tree-grid>
    

    Templating the Drag Icon

    The drag handle icon can be templated using the grid's DragIndicatorIconTemplate. In the example we're building, let's change the icon from the default one (drag_indicator) to drag_handle.

    <igc-tree-grid row-draggable="true" id="grid">
    </igc-tree-grid>
    
    constructor() {
        var grid = this.grid = document.getElementById('grid') as IgcHierarchicalGridComponent;
        grid.dragIndicatorIconTemplate = this.dragIndicatorIconTemplate;
    }
    
    public dragIndicatorIconTemplate = (ctx: IgcGridEmptyTemplateContext) => {
        return html`<igc-icon name="drag_handle" collection="material"></igc-icon>`;
    }
    

    Application Demo

    Row Reordering Demo

    Com a ajuda dos eventos de arrastar linha da grade, você pode criar uma grade que permite reordenar as linhas arrastando-as.

    <igc-tree-grid id="tGrid" row-draggable="true" primary-key="ID">
    </igc-tree-grid>
    
    constructor() {
        var tGrid = this.tGrid = document.getElementById('tGrid') as IgcTreeGridComponent;
        tGrid.addEventListener("rowDragStart", this.webTreeGridReorderRowStartHandler);
        tGrid.addEventListener("rowDragEnd", this.webTreeGridReorderRowHandler);
    }
    

    [!Note] Make sure that there is a PrimaryKey specified for the grid! The logic needs an unique identifier for the rows so they can be properly reordered.

    Depois queRowDraggable está ativado e uma zona de queda está definida, você precisa implementar um manipulador simples para o evento de drop. Quando uma linha é arrastada, verifique o seguinte:

    • A linha é expandida? Em caso afirmativo, recolha-o.
    • A linha foi lançada dentro da grade?
    • Se sim, em qual outra fileira a fileira arrastada foi largada?
    • Depois de encontrar a linha de destino, troque os registros nodata array
    • A linha foi inicialmente selecionada? Em caso afirmativo, marque-o como selecionado.

    Abaixo, você pode ver isso implementado:

    public webTreeGridReorderRowStartHandler(args: CustomEvent<IgcRowDragStartEventArgs){
            const draggedRow = args.detail.dragElement;
            const grid = this.treeGrid;
            const row = grid.getRowByIndex(draggedRow.getAttribute('data-rowindex'));
            if(row.expanded){
                row.expanded = false;
            }
        }
    
        public webTreeGridReorderRowHandler(args: CustomEvent<IgcRowDragEndEventArgs>): void {
            const ghostElement = args.detail.dragDirective.ghostElement;
            const dragElementPos = ghostElement.getBoundingClientRect();
            const grid = this.treeGrid;
            const rows = Array.prototype.slice.call(document.getElementsByTagName("igx-tree-grid-row"));
            const currRowIndex = this.getCurrentRowIndex(rows,
            { x: dragElementPos.x, y: dragElementPos.y });
            if (currRowIndex === -1) { return; }
            const draggedRow = args.detail.dragData.data;
            const childRows = this.findChildRows(grid.data, draggedRow);
            //remove the row that was dragged and place it onto its new location
            grid.deleteRow(args.detail.dragData.key);
            grid.data.splice(currRowIndex, 0, args.detail.dragData.data);
            // reinsert the child rows
            childRows.reverse().forEach(childRow => {
                grid.data.splice(currRowIndex + 1, 0, childRow);
            });
        }
    
        private findChildRows(rows: any[], parent: any): any[] {
            const childRows: any[] = [];
            rows.forEach(row => {
                if (row.ParentID === parent.ID) {
                    childRows.push(row);
                    // Recursively find children of current row
                    const grandchildren = this.findChildRows(rows, row);
                    childRows.push(...grandchildren);
                }
            });
            return childRows;
        }
    
        public getCurrentRowIndex(rowList: any[], cursorPosition: any) {
            for (const row of rowList) {
                const rowRect = row.getBoundingClientRect();
                if (cursorPosition.y > rowRect.top + window.scrollY && cursorPosition.y < rowRect.bottom + window.scrollY &&
                    cursorPosition.x > rowRect.left + window.scrollX && cursorPosition.x < rowRect.right + window.scrollX) {
                    // return the index of the targeted row
                    return parseInt(row.attributes["data-rowindex"].value);
                }
            }
            return -1;
        }
    

    Com essas etapas fáceis, você configurou uma grade que permite reordenar linhas por meio de arrastar/soltar! Você pode ver o código acima em ação na demonstração a seguir.

    Observe que também temos a seleção de linha habilitada e preservamos a seleção ao soltar a linha arrastada.

    Limitations

    Currently, there are no known limitations for the RowDraggable.

    API References

    Additional Resources

    Nossa comunidade é ativa e sempre acolhedora para novas ideias.