Arrastre de filas en Web Components cuadrícula de árbol
La función de arrastre de filas Ignite UI for Web Components en Web Components cuadrícula de árbol es fácilmente configurable y se utiliza para reorganizar filas dentro de la cuadrícula arrastrándolas y soltándolas a una nueva posición con el mouse. Se inicializa en el componente raíz IgcTreeGridComponent y se puede configurar a través de la rowDraggable entrada.
Web Components Ejemplo de arrastre de fila de cuadrícula de árbol
import { IgcPropertyEditorPanelModule } from'igniteui-webcomponents-layouts';
import'igniteui-webcomponents-grids/grids/combined';
import { ComponentRenderer, PropertyEditorPanelDescriptionModule, WebTreeGridDescriptionModule, WebPaginatorDescriptionModule } from'igniteui-webcomponents-core';
import { IgcTreeGridComponent, IgcGridToolbarTitleComponent } from'igniteui-webcomponents-grids/grids';
import { EmployeesNestedDataItem, EmployeesNestedDataItem_EmployeesItem, EmployeesNestedData } from'./EmployeesNestedData';
import"igniteui-webcomponents-grids/grids/themes/light/bootstrap.css";
import { ModuleManager } from'igniteui-webcomponents-core';
import"./index.css";
ModuleManager.register(
IgcPropertyEditorPanelModule
);
exportclassSample{
private treeGrid: IgcTreeGridComponent
private treeGrid2: IgcTreeGridComponent
private employees: IgcGridToolbarTitleComponent
private employeesData:EmployeesNestedData;
private _bind: () =>void;
constructor() {
var treeGrid = this.treeGrid = document.getElementById('treeGrid') as IgcTreeGridComponent;
var treeGrid2 = this.treeGrid2 = document.getElementById('treeGrid2') as IgcTreeGridComponent;
var employees = this.employees = document.getElementById('Employees') as IgcGridToolbarTitleComponent;
var employeesData = new EmployeesNestedData();
this._bind = () => {
treeGrid.data = this.employeesNestedData;
treeGrid2.data = [];
treeGrid2.emptyGridMessage = "Drag and Drop a row from the left grid to this grid";
treeGrid.addEventListener("rowDragEnd", this.onGridRowDragEnd.bind(this));
}
this._bind();
}
publicaddRowAndChildren(row:EmployeesNestedDataItem, newData:any[]) {
if(newData.includes(row)){
return;
}
elseif(newData.length>0 && row.Employees){
for(let i= row.Employees.length;i>=0;i--){
if(newData.includes(row.Employees[i])){
let index = newData.findIndex(element => element.ID === row.Employees[i].ID);
if (index > -1) {
newData.splice(index, 1);
}
}
}
}
for (let record of newData) {
if (record.Employees && record.Employees.includes(row)) {
return;
}
}
newData.push(row);
}
public onGridRowDragEnd(args: any): void {
const ghostElement = args.detail.dragDirective.ghostElement;
if (ghostElement != null) {
const dragElementPos = ghostElement.getBoundingClientRect();
const gridPosition = this.treeGrid2.getBoundingClientRect();
const withinXBounds = dragElementPos.x >= gridPosition.x && dragElementPos.x <= gridPosition.x + gridPosition.width;
const withinYBounds = dragElementPos.y >= gridPosition.y && dragElementPos.y <= gridPosition.y + gridPosition.height;
if (withinXBounds && withinYBounds) {
const newData = [...this.treeGrid2.data];
const draggedRowData = args.detail.dragData.data;
this.addRowAndChildren(draggedRowData, newData);
this.treeGrid2.data = newData;
}
}
}
private _employeesNestedData: EmployeesNestedData = null;
publicgetemployeesNestedData(): EmployeesNestedData {
if (this._employeesNestedData == null)
{
this._employeesNestedData = new EmployeesNestedData();
}
returnthis._employeesNestedData;
}
private _componentRenderer: ComponentRenderer = null;
publicgetrenderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
PropertyEditorPanelDescriptionModule.register(context);
WebTreeGridDescriptionModule.register(context);
WebPaginatorDescriptionModule.register(context);
}
returnthis._componentRenderer;
}
}
new Sample();
ts
<!DOCTYPE html><html><head><title>Sample | Ignite UI | Web Components | infragistics</title><metacharset="UTF-8" /><linkrel="shortcut icon"href="https://static.infragistics.com/xplatform/images/browsers/wc.png" ><linkrel="stylesheet"href="https://fonts.googleapis.com/icon?family=Material+Icons" /><linkrel="stylesheet"href="https://fonts.googleapis.com/css?family=Kanit&display=swap" /><linkrel="stylesheet"href="https://fonts.googleapis.com/css?family=Titillium Web" /><linkrel="stylesheet"href="https://static.infragistics.com/xplatform/css/samples/shared.v8.css" /><linkrel="stylesheet"href="/src/index.css"type="text/css" /></head><body><divid="root"><divclass="container sample ig-typography"><divclass="container horizontal"><divclass="container vertical"style="padding: 0.5rem;"><igc-tree-gridauto-generate="false"name="treeGrid"id="treeGrid"child-data-key="Employees"row-draggable="true"
><igc-columnfield="Name"header="Name"data-type="string"sortable="true"editable="true"resizable="true"
></igc-column><igc-columnfield="HireDate"header="Hire Date"data-type="date"sortable="true"editable="true"resizable="true"></igc-column><igc-columnfield="Age"header="Age"data-type="number"sortable="true"editable="true"resizable="true"></igc-column></igc-tree-grid></div><divclass="container vertical"style="padding: 0.5rem;"><igc-tree-gridauto-generate="false"name="treeGrid2"id="treeGrid2"child-data-key="Employees"
><igc-columnfield="Name"header="Name"data-type="string"sortable="true"editable="true"resizable="true"
></igc-column><igc-columnfield="HireDate"header="Hire Date"data-type="date"sortable="true"editable="true"resizable="true"></igc-column><igc-columnfield="Age"header="Age"data-type="number"sortable="true"editable="true"resizable="true"></igc-column></igc-tree-grid></div></div></div></div><!-- This script is needed only for parcel and it will be excluded for webpack -->
<% if (false) { %><scriptsrc="src/index.ts"></script><% } %>
</body></html>html
/* shared styles are loaded from: *//* https://static.infragistics.com/xplatform/css/samples */css
¿Te gusta esta muestra? Obtenga acceso a nuestro kit de herramientas de Ignite UI for Web Components completo y comience a crear sus propias aplicaciones en minutos. Descárgalo gratis.
Configuración
Para habilitar el arrastre de filas para su IgcTreeGridComponent, todo lo que necesita hacer es establecer la cuadrícula en rowDraggable true. Una vez que esté habilitado, se mostrará un controlador de arrastre de fila en cada fila. Este controlador se puede utilizar para iniciar el arrastre de filas. Al hacer clic en el controlador de arrastre y mover el cursor mientras se mantiene presionado el botón, se activará el evento de RowDragStart la cuadrícula. Si suelta el clic en cualquier momento, se RowDragEnd activará el evento.
El icono del controlador de arrastre se puede crear como plantilla usando dragIndicatorIconTemplate de la cuadrícula. En el ejemplo que estamos creando, cambiemos el ícono predeterminado (drag_indicator) a drag_handle.
Para hacerlo, podemos usar el DragIndicatorIcon para pasar una plantilla dentro del cuerpo de la igc-tree-grid:
constructor() {
var tGrid = this.tGrid = document.getElementById('tGrid') as IgcTreeGridComponent;
tGrid.addEventListener("rowDragStart", this.webTreeGridReorderRowStartHandler);
tGrid.addEventListener("rowDragEnd", this.webTreeGridReorderRowHandler);
}
ts
¡Asegúrese de que haya una clave principal especificada para la cuadrícula! La lógica necesita un identificador único para las filas para que puedan reordenarse correctamente.
Una vez que rowDraggable esté habilitado y se haya definido una zona de colocación, debe implementar un controlador simple para el evento de colocación. Cuando se arrastra una fila, verifique lo siguiente:
¿Se amplía la fila? Si es así, colapsarlo.
¿Se dejó caer la fila dentro de la cuadrícula?
Si es así, ¿en qué otra fila se soltó la fila arrastrada?
Una vez que haya encontrado la fila de destino, intercambie las ubicaciones de los registros en la matriz data.
¿Se seleccionó inicialmente la fila? Si es así, márquelo como seleccionado.
A continuación, puedes ver esto implementado:
publicwebTreeGridReorderRowStartHandler(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 rowconst grandchildren = this.findChildRows(rows, row);
childRows.push(...grandchildren);
}
});
return childRows;
}
publicgetCurrentRowIndex(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 rowreturnparseInt(row.attributes["data-rowindex"].value);
}
}
return -1;
}
ts
¡Con estos sencillos pasos, ha configurado una cuadrícula que permite reordenar filas mediante arrastrar y soltar! Puede ver el código anterior en acción en la siguiente demostración.
Observe que también tenemos habilitada la selección de filas y conservamos la selección al soltar la fila arrastrada.
import'igniteui-webcomponents-grids/grids/combined';
import { ComponentRenderer, WebTreeGridDescriptionModule } from'igniteui-webcomponents-core';
import { IgcTreeGridComponent } from'igniteui-webcomponents-grids/grids';
import { EmployeesNestedTreeDataItem, EmployeesNestedTreeData } from'./EmployeesNestedTreeData';
import { IgcRowDragStartEventArgs, IgcRowDragEndEventArgs } from'igniteui-webcomponents-grids/grids';
import"igniteui-webcomponents-grids/grids/themes/light/bootstrap.css";
import"./index.css";
exportclassSample{
private treeGrid: IgcTreeGridComponent
private _bind: () =>void;
constructor() {
var treeGrid = this.treeGrid = document.getElementById('treeGrid') as IgcTreeGridComponent;
this.webTreeGridReorderRowStartHandler = this.webTreeGridReorderRowStartHandler.bind(this);
this.webTreeGridReorderRowHandler = this.webTreeGridReorderRowHandler.bind(this);
this._bind = () => {
treeGrid.data = this.employeesNestedTreeData;
treeGrid.addEventListener("rowDragStart", this.webTreeGridReorderRowStartHandler);
treeGrid.addEventListener("rowDragEnd", this.webTreeGridReorderRowHandler);
}
this._bind();
}
private _employeesNestedTreeData: EmployeesNestedTreeData = null;
publicgetemployeesNestedTreeData(): EmployeesNestedTreeData {
if (this._employeesNestedTreeData == null)
{
this._employeesNestedTreeData = new EmployeesNestedTreeData();
}
returnthis._employeesNestedTreeData;
}
private _componentRenderer: ComponentRenderer = null;
publicgetrenderer(): ComponentRenderer {
if (this._componentRenderer == null) {
this._componentRenderer = new ComponentRenderer();
var context = this._componentRenderer.context;
WebTreeGridDescriptionModule.register(context);
}
returnthis._componentRenderer;
}
publicwebTreeGridReorderRowStartHandler(args: CustomEvent<IgcRowDragStartEventArgs>){
const draggedRow = args.detail.dragData;
if(draggedRow.expanded){
draggedRow.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 rowconst grandchildren = this.findChildRows(rows, row);
childRows.push(...grandchildren);
}
});
return childRows;
}
publicgetCurrentRowIndex(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 rowreturnparseInt(row.attributes["data-rowindex"].value);
}
}
return -1;
}
}
new Sample();
ts
<!DOCTYPE html><html><head><title>Sample | Ignite UI | Web Components | infragistics</title><metacharset="UTF-8" /><linkrel="shortcut icon"href="https://static.infragistics.com/xplatform/images/browsers/wc.png" ><linkrel="stylesheet"href="https://fonts.googleapis.com/icon?family=Material+Icons" /><linkrel="stylesheet"href="https://fonts.googleapis.com/css?family=Kanit&display=swap" /><linkrel="stylesheet"href="https://fonts.googleapis.com/css?family=Titillium Web" /><linkrel="stylesheet"href="https://static.infragistics.com/xplatform/css/samples/shared.v8.css" /><linkrel="stylesheet"href="/src/index.css"type="text/css" /></head><body><divid="root"><divclass="container sample ig-typography"><divclass="container fill"><igc-tree-gridauto-generate="false"name="treeGrid"id="treeGrid"id="treeGrid"primary-key="ID"foreign-key="ParentID"row-draggable="true"><igc-columnfield="Name"header="Full Name"data-type="string"resizable="true"sortable="true"filterable="true"editable="true"></igc-column><igc-columnfield="Age"data-type="number"resizable="false"sortable="false"filterable="false"editable="true"></igc-column><igc-columnfield="Title"data-type="string"resizable="true"sortable="true"filterable="true"editable="true"></igc-column><igc-columnfield="HireDate"header="Hire Date"data-type="date"resizable="true"sortable="true"filterable="true"editable="true"></igc-column></igc-tree-grid></div></div></div><!-- This script is needed only for parcel and it will be excluded for webpack -->
<% if (false) { %><scriptsrc="src/index.ts"></script><% } %>
</body></html>html
/* shared styles are loaded from: *//* https://static.infragistics.com/xplatform/css/samples */css
Limitaciones
Actualmente, no existen limitaciones conocidas para rowDraggable.