-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Description
Hello !
I am encountering a problem with RGL and I don't know if it's a bug or me doing things badly.
Demo here
What I'm trying to do
I'd like to create a dashboard using react-grid-layout. I'm trying to implement the container pattern so I have a DashboardContainer component controlling the layout via his state and passing this layout down to a Dashboard component in the props.
The problem I encounter
Elements are placed correctly for the initial state but when I add items, the x, y, w and h of the added element aren't correct.
It should be (5,0,2,2) for the first addition, and it ends up being placed on (0,4,1,1)
I saw that elements can be redimensionned to 1 of width and height if they don't have the correct key, but I think my keys are correct.
Example: this layout is passed to Dasboard
But this is the displayed layout (the element "new0" isn't corresponding)
My code
Dashboard Container :
import React from "react";
import ReactDOM from "react-dom";
import Dashboard from "./Dashboard";
class DashboardContainer extends React.Component {
static defaultProps = {
maxRows: 8,
cols: 12
};
state = {
layout: [
{ i: "key0", x: 0, y: 0, w: 2, h: 2 },
{ i: "key1", x: 2, y: 0, w: 3, h: 2 },
{ i: "key2", x: 2, y: 2, w: 2, h: 2 },
{ i: "key3", x: 8, y: 0, w: 3, h: 2 }
],
newElementsCount: 0
};
onLayoutChange = l => {
this.setState({ layout: l });
};
add = () => {
// all this is just to calculate where the new element should be placed
var x = 0,
y = 0,
w = 2,
h = 2,
arr = [],
trouve = false;
for (let i = 0; i < 12; i++) {
arr.push([]);
for (let j = 0; j < 8; j++) {
arr[i].push(1);
}
}
this.state.layout.forEach(function(e) {
for (let i = 0; i < e.w; i++) {
for (let j = 0; j < e.h; j++) {
arr[e.x + i][e.y + j] = 0;
}
}
});
var checkOk = (arr, w, h, x, y) => {
var res = true;
for (let i = x; i < x + w; i++) {
for (let j = y; j < y + h; j++) {
if (!arr[i][j]) res = false;
}
}
return res;
};
if (checkOk(arr, w, h, x, y)) trouve = true;
while (!trouve && y + h <= 8) {
if (x + w === 12) {
x = 0;
y++;
} else {
x++;
}
if (checkOk(arr, w, h, x, y)) trouve = true;
}
if (trouve) {
var newLayout = this.state.layout;
newLayout.push({
i: "new" + this.state.newElementsCount,
x: x,
y: y,
w: w,
h: h
});
this.setState({
newElementsCount: this.state.newElementsCount + 1,
layout: newLayout
});
} else {
console.log("Can't add");
}
};
render() {
return (
<div>
<Dashboard
layout={this.state.layout}
add={this.add}
cols={this.props.cols}
maxRows={this.props.maxRows}
onLayoutChange={this.onLayoutChange}
preventCollision={true}
/>
</div>
);
}
}
const contentDiv = document.getElementById("root");
ReactDOM.render(React.createElement(DashboardContainer), contentDiv);
Dashboard :
import React from "react";
import RGL, { WidthProvider } from "react-grid-layout";
const ReactGridLayout = WidthProvider(RGL);
class Dashboard extends React.Component {
generateDOM() {
return this.props.layout.map(function(item) {
return <div key={item.i}>{item.i}</div>;
});
}
render() {
return (
<div>
<button onClick={this.props.add}>Add</button>
<ReactGridLayout
rowHeight={30}
maxRows={this.props.maxRows}
cols={this.props.cols}
layout={this.props.layout}
compactType={null}
onLayoutChange={this.props.onLayoutChange}
>
{this.generateDOM()}
</ReactGridLayout>
</div>
);
}
}
module.exports = Dashboard;
You can find a codesandbox with this exact code here
I'm still very new to React and RGL so any suggestions are welcome !
Thank you

