Blazor Tree Grid の行ドラッグ

    Blazor Tree Grid の Ignite UI for Blazor 行ドラッグ機能は簡単に構成でき、マウスを使用して行を新しい位置にドラッグ アンド ドロップすることで、グリッド内の行を再配置するために使用されます。これはルートの IgbTreeGrid コンポーネントで初期化され、RowDraggable 入力を介して構成できます。

    Blazor Tree Grid 行ドラッグの例

    構成

    IgbTreeGrid の行ドラッグを有効にするには、グリッドの RowDraggabletrue に設定します。これが有効になると、行ドラッグ ハンドルが各行に表示されます。このハンドルは行ドラッグを開始するために使用できます。ドラッグ ハンドルをクリックしてボタンを押しながらカーソルを動かすと、グリッドの RowDragStart イベントが発生します。クリックをリリースすると、RowDragEnd イベントが発生します。

    <IgbTreeGrid RowDraggable="true">
    </IgbTreeGrid>
    

    ドラッグ アイコンのテンプレート化

    ドラッグ ハンドル アイコンは、グリッドの DragIndicatorIconTemplate を使用してテンプレート化できます。作成している例で、アイコンをデフォルトのもの (drag_indicator) から drag_handle に変更します。

    そのためには、DragIndicatorIcon を使用して IgbTreeGrid の本体内にテンプレートを渡すことができます。

    <IgbTreeGrid Data="CustomersData" PrimaryKey="ID" RowDraggable="true" DragIndicatorIconTemplate="dragIndicatorIconTemplate" @ref="grid">
    </IgbTreeGrid>
    
    private RenderFragment<IgbGridEmptyTemplateContext> dragIndicatorIconTemplate = (context) =>
    {
        return @<div>
            <IgbIcon IconName="drag_handle" Collection="material"></IgbIcon>
        </div>;
    };
    

    アプリケーション デモ

    行の並べ替えデモ

    グリッドの行ドラッグ イベントを使用して、ドラッグよる行の並べ替えるが可能なグリッドを作成できます。

    <IgbTreeGrid Data="CustomersData" PrimaryKey="ID" RowDraggable="true" RowDragStartScript="WebTreeGridReorderRowStartHandler" RowDragEndScript="WebTreeGridReorderRowHandler"></IgbTreeGrid>
    

    [!Note] グリッドに PrimaryKey が指定されていることを確認してください。ロジックが行を適切に並べ替えられるように、行には一意の識別子が必要です。

    RowDraggable が有効になり、ドロップ エリアが定義されたら、ドロップ イベントの単純なハンドラーを実装する必要があります。行をドラッグするときは、以下を確認してください:

    • 行が展開されていますか? そうであれば、行を縮小します。
    • 行はグリッド内にドロップされましたか?
    • そうであれば、ドラッグされた行が他のどの行にドロップされましたか?
    • ターゲット行が見つかれば、Data 配列内のレコードの位置を入れ替えます。
    • 行は最初に選択されてましたか? そうであれば、選択済みとしてマークします。

    以下では、上記の実装を示します。

    //in JavaScript
    igRegisterScript("WebTreeGridReorderRowStartHandler", (args) => {
        const draggedRow = args.detail.dragElement;
        const row = this.treeGrid.getRowByIndex(draggedRow.getAttribute('data-rowindex'));
        if (row.expanded) {
            row.expanded = false;
        }
    }, false);
    
    igRegisterScript("WebTreeGridReorderRowHandler", (args) => {
        const ghostElement = args.detail.dragDirective.ghostElement;
        const dragElementPos = ghostElement.getBoundingClientRect();
        const grid = document.getElementsByTagName("igc-tree-grid")[0];
        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; }
        // remove the row that was dragged and place it onto its new location
        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);
        });
    }, false);
    
    function findChildRows(rows, parent) {
        const childRows = [];
        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;
    }
    
    function getCurrentRowIndex(rowList, cursorPosition) {
        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;
    }
    

    これらの簡単な手順で、ドラッグ/ドロップで行を並べ替えることができるグリッドを構成しました! 次のデモで、上記コードの動作を確認できます。

    行の選択も有効で、ドラッグした行をドロップしても選択が保持されます。

    制限

    現在、RowDraggable に既知の制限はありません。

    API リファレンス

    その他のリソース

    コミュニティに参加して新しいアイデアをご提案ください。