Background:
The default behavior of a data grid is moving rows or cells within itself. Sometimes users need the functionality to move rows from one grid to another. Wijmo’s FlexGrid, with the help of HTML 5’s drag and drop API supports this and it is straightforward to implement.
Steps to Complete:
- Add event listeners to your grids
- Create a drag function to connect to your listener
- Create a drop function to connect to your listener
Getting Started:
You use the HTML5 drag/drop API to drag and drop rows between the grids. You can find additional information and a demo showcasing this functionality here.
Add event listeners to your grids
In vanilla JavaScript, you create your grids and then wire up the listeners:
<!-- index.html -->
<link rel="stylesheet" href="https://cdn.mescius.com/wijmo/5.latest/styles/wijmo.min.css" />
<div class="container">
<div id="grid1"></div>
<div id="grid2"></div>
</div>
<script src="https://cdn.mescius.com/wijmo/5.latest/controls/wijmo.min.js"></script>
<script src="https://cdn.mescius.com/wijmo/5.latest/controls/wijmo.grid.min.js"></script>
<script>
// Example data sources (replace with your own)
const data1 = [
{ id: 1, country: 'US', sales: 1000 },
{ id: 2, country: 'Germany', sales: 2000 },
];
const data2 = [
{ id: 3, country: 'Japan', sales: 1500 },
{ id: 4, country: 'UK', sales: 1200 },
];
const grid1 = new wijmo.grid.FlexGrid('#grid1', { itemsSource: data1 });
const grid2 = new wijmo.grid.FlexGrid('#grid2', { itemsSource: data2 });
const dnd = {
sGrid: null,
dataTransferRow: null,
targetRowIndex: null,
initializedGrid1(grid1) {
grid1.hostElement.addEventListener('dragstart', this.dragStart(grid1).bind(this));
grid1.hostElement.addEventListener('dragover', this.dragOver(grid1).bind(this));
grid1.hostElement.addEventListener('drop', this.dropRow(grid1).bind(this));
},
initializedGrid2(grid2) {
grid2.hostElement.addEventListener('dragstart', this.dragStart(grid2).bind(this));
grid2.hostElement.addEventListener('dragover', this.dragOver(grid2).bind(this));
grid2.hostElement.addEventListener('drop', this.dropRow(grid2).bind(this));
},
// ...dragStart/marker helper methods live alongside the methods below...
// dragStart(grid) { ... }
// _moveMarker(grid, htinfo) { ... }
// _delMarker(grid) { ... }
// See next sections for dragOver and dropRow.
};
dnd.initializedGrid1(grid1);
dnd.initializedGrid2(grid2);
</script>
Create a drag function to connect to your listener
dragOver(grid) {
var dragOverHandler = function (e) {
if (grid == this.sGrid || !this.dataTransferRow) {
return;
}
e.dataTransfer.dropEffect = 'copy';
let htinfo = grid.hitTest(e);
this._moveMarker(grid, htinfo);
this.targetRowIndex = htinfo.row;
e.preventDefault();
};
return dragOverHandler;
}
Create a drop function to connect to your listener
dropRow(grid) {
var droppedRow = function (e) {
if (grid == this.sGrid || !this.dataTransferRow) {
return;
}
this.dataTransferRow.forEach((row) => {
let dataItem = Object.assign({}, row.dataItem);
grid.collectionView.refresh();
//row dropped copy it
console.log('drop', this.targetRowIndex);
if (this.targetRowIndex === null) {
grid.collectionView.sourceCollection.push(dataItem);
} else {
grid.collectionView.sourceCollection.splice(this.targetRowIndex + 1, 0, dataItem);
this._delMarker(grid);
}
grid.collectionView.refresh();
});
this.dataTransferRow.forEach((row) => {
row.collectionView.remove(row.dataItem);
});
};
return droppedRow;
}
And that’s how you add the functionality to drag a row by the rowHeader from one grid to any column of another grid. If you want to start the dragging from any cell instead of only from the rowHeader, then you handle the formatItem event of FlexGrid. Make each cell draggable and then change the dragStart method condition to only allow dragging from RowHeader type cells.
Happy coding!
Andrew Peterson
