Web Components Tree Grid の行ドラッグ
Web Components Tree Grid の Ignite UI for Web Components 行ドラッグ機能は簡単に構成でき、マウスを使用して行を新しい位置にドラッグ アンド ドロップすることで、グリッド内の行を再配置するために使用されます。これはルートの IgcTreeGrid コンポーネントで初期化され、IgcTreeGrid.rowDraggable 入力を介して構成できます。
Web Components Tree Grid 行ドラッグの例
構成
IgcTreeGrid の行ドラッグを有効にするには、グリッドの IgcTreeGrid.rowDraggable を true に設定するだけです。これが有効になると、行ドラッグ ハンドルが各行に表示されます。このハンドルを使用して行ドラッグを開始できます。ドラッグ ハンドルをクリックし、マウスボタンを押したままカーソルを移動すると、グリッドの IgcIgcTreeGrid.rowDragStart イベントが発生します。ドラッグ中にマウスボタンを離すと IgcIgcTreeGrid.rowDragEnd イベントが発生します。
<igc-tree-grid row-draggable="true">
</igc-tree-grid>
ドロップ エリア
はじめに、DragDropModule を登録する必要があります。
import { IgcDragDropModule } from 'igniteui-webcomponents';
// ...
ModuleManager.register(
IgcDragDropModule
);
constructor() {
var grid = this.grid = document.getElementById('grid') as IgcGridComponent;
this._bind = () => {
grid.rowDragGhost = this.rowDragGhostTemplate;
}
this._bind();
}
public rowDragGhostTemplate = (ctx: IgcGridRowDragGhostContext) => {
return html`<igc-icon fontSet="material">arrow_right_alt</igc-icon>`;
}
ドラッグ アイコンのテンプレート化
ドラッグ ハンドル アイコンは、グリッドの DragIndicatorIconTemplate を使用してテンプレート化できます。作成中の例では、デフォルトのアイコン (drag_indicator) を drag_handle に変更してみましょう。
デモ
アプリケーション デモ
行の並べ替えデモ
グリッドの行ドラッグ イベントを使用すると、行をドラッグして並べ替えられるグリッドを作成できます。
<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);
}
グリッドに IgcTreeGrid.primaryKey が指定されていることを確認してください。行を正しく並べ替えるには、一意の識別子が必要です。
IgcTreeGrid.rowDraggable が有効になり、ドロップ エリアが定義されたら、ドロップ イベント用の簡単なハンドラーを実装する必要があります。行がドラッグされたときは、次を確認します。
- 行は展開されているか。展開されている場合は折りたたむ
- 行はグリッド内にドロップされたか
- ドロップされた場合、ドラッグされた行が別のどの行にドロップされたか
- ターゲット行が見つかったら、
Data配列内でレコードの位置を入れ替える - 行は元々選択されていたか。選択されていた場合は、選択済みとしてマークする
以下は、その実装例です。
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;
}
これらの簡単な手順で、ドラッグ アンド ドロップによる行の並べ替えが可能なグリッドを設定できました。上記のコードの動作は、以下のデモで確認できます。
行選択も有効になっており、ドラッグされた行をドロップしたときに選択状態が保持されることに注目してください。
制限
現在、IgcTreeGrid.rowDraggable に関する既知の制限事項はありません。
API リファレンス
IgcTreeGrid
その他のリソース
コミュニティは常に新しいアイデアを歓迎しています。