I want to have a grid which will always have for example 3 rows and 3 columns. Now suppose these are my grid items
<div className="myClass" key="1">1</div>
<div className="myClass" key="2">2</div>
<div className="myClass" key="3">3</div>
<div className="myClass" key="4">4</div>
<div className="myClass" key="5">5</div>
<div className="myClass" key="6">6</div>
<div className="myClass" key="7">7</div>
<div className="myClass" key="8">8</div>
<div className="myClass" key="9">9</div>
suppose all items have same width and height and are not resizable.
If I drag 9 over to 6 aka vertically the items will just swap their places. However if I drag 9 over to 8 aka horizontally the 8 item will go down to a new row and 9 will be in place of 8 while the previous place of 9 will be empty. Is it possible to make items just swap places during horizontal drag as well, instead of creating a new row?
So I added the onLayoutChange
to the ReactGridLayout
Read code comments for more details.
private onLayoutChange = (layout: any) => {
const fixedLayout = this.fixLayout(layout)
this.setState({
layout: fixedLayout
})
}
/**
* The `react-grid-layout` lib is not swapping items during horizontal dragover
* Rather it moves the items into a new row
* Since we need a static 3x3 row, let's fix that
*/
private fixLayout = (layout: any) => {
// `y` is calculated by `h` in the layout object, since `h` is 20
// first row will be 0, second 20, third 40
const maxY = 40
// when an item goes to a new row, there is an empty column in the maxY row
// so here we find which columns exist
// tslint:disable-next-line:max-line-length
const maxRowXs = layout.map((item: any) => item.y === maxY ? item.x : null).filter((value: any) => value !== null)
// xs or cols, we only have 3 cols
const xs = [0,1,2]
// find the missing col
// tslint:disable-next-line:max-line-length
const missingX = xs.find((value: any) => maxRowXs.every((maxRowX: number) => maxRowX !== value))
// bring the item from the new row into maxY row
// and place it in the missing column
const fixedLayout = layout.map((item: any) => {
if (item.y > maxY) {
return {
...item,
y: maxY,
x: missingX
}
}
return item
})
return fixedLayout
}