Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ Change log
* fix: [#2628](https://github.com/gridstack/gridstack.js/issues/2628) `removeAll()` does not trigger Angular's ngOnDestroy
* fix: [#2503](https://github.com/gridstack/gridstack.js/issues/2503) Drag and drop a widget on top of a locked widget - Thank you [JakubEleniuk](https://github.com/JakubEleniuk)
* fix: [#2584](https://github.com/gridstack/gridstack.js/issues/2584) wrong sort order during 1 column resize - Thank you [JakubEleniuk](https://github.com/JakubEleniuk) again.
* fix: [#2639](https://github.com/gridstack/gridstack.js/issues/2639) load() with mix of new item without coordinates

## 10.1.1 (2024-03-03)
* fix: [#2620](https://github.com/gridstack/gridstack.js/pull/2620) allow resizing with sizeToContent:NUMBER is uses
Expand Down
74 changes: 74 additions & 0 deletions spec/e2e/html/2639_load_missing_coord.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>#2639 load() fix</title>
<link rel="stylesheet" href="../../../demo/demo.css" />
<script src="../../../dist/gridstack-all.js"></script>
</head>
<body>
<div class="container-fluid">
<h1>#2639 load() fix with mix of missing coordinates.</h1>
<div>
<button onClick="addNewWidget()">Add widget using .addWidget()</button>
<button onClick="loadNewWidget()">Add widget using .load()</button>
</div>
<br><br>
<div class="grid-stack"></div>
<textarea readonly rows="20" id="text" style="width: 100%;"></textarea>
</div>
<script src="events.js"></script>
<script type="text/javascript">
saveGrid = function() {
items = grid.save();
document.querySelector('#text').innerHTML = JSON.stringify(items, ' ', 2)
}

var count = 0;
var items = [
{x: 0, y: 0, w: 2, h: 2},
{x: 2, y: 0, w: 8, h: 2},
{x: 0, y: 2, w: 6, h: 2},
{x: 6, y: 2, w: 3, h: 2},
{x: 9, y: 2, w: 3, h: 2},
{x: 0, y: 4, w: 5, h: 3},
].map(w => ({
...w,
id: String(count),
content: String(count++)
}));

var options = { // put in gridstack options here
float: false,
cellHeight: 70,
};
var grid = GridStack.init(options).load(items);
grid.on('change added', saveGrid);
saveGrid();

createNode = function (str) {
return {
id: String(count),
w: 3,
h: 3,
content: `${count++} ${str}`,
};
}

// Gets placed in the next hortizontal open slot
addNewWidget = function () {
grid.addWidget(createNode('added'));
return false;
};

// Gets placed at the bottom of a grid
loadNewWidget = function () {
items.push(createNode('loaded'));
grid.load(items);
return false;
}
</script>
</body>
</html>
11 changes: 11 additions & 0 deletions src/gridstack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,12 @@ export class GridStack {
items = Utils.cloneDeep(items); // so we can mod
const column = this.getColumn();

// if we have a mix of new items without coordinates and existing items, separate them out so they can be added after #2639
let addAfter = items.filter(n => (n.x === undefined || n.y === undefined) && !Utils.find(this.engine.nodes, n.id));
if (addAfter.length && addAfter.length !== items.length) {
items = items.filter(n => !Utils.find(addAfter, n.id));
} else addAfter = [];

// if passed list has coordinates, use them (insert from end to beginning for conflict resolution) else keep widget order
const haveCoord = items.some(w => w.x !== undefined || w.y !== undefined);
if (haveCoord) items = Utils.sort(items, -1);
Expand Down Expand Up @@ -776,6 +782,11 @@ export class GridStack {
}
});

// finally append any separate ones that didn't have explicit coordinates last so they can find next empty spot
if (addRemove) {
addAfter.forEach(w => this.addWidget(w))
}

this.engine.removedNodes = removed;
this.batchUpdate(false);

Expand Down