Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3bb9f0b

Browse files
authored
Merge pull request gridstack#2720 from adumesny/master
load() now creates in order
2 parents 2643116 + ec3c7e4 commit 3bb9f0b

File tree

4 files changed

+31
-41
lines changed

4 files changed

+31
-41
lines changed

demo/two.html

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,13 @@ <h1>Two grids demo</h1>
7373

7474
let items = [
7575
{x: 0, y: 0, w: 2, h: 2},
76-
{x: 3, y: 1, h: 2},
77-
{x: 4, y: 1},
78-
{x: 2, y: 3, w: 3, maxW: 3, id: 'special', content: 'has maxW=3'},
76+
{x: 1, y: 1, h: 2}, // intentional overlap to test collision on load
77+
{x: 1, y: 1}, // intentional overlap to test collision on load
78+
{x: 3, y: 1},
79+
{x: 2, y: 3, w: 3, maxW: 3, content: 'has maxW=3'},
7980
{x: 2, y: 5}
8081
];
82+
items.forEach((item, i) => item.content = item.content || String(i));
8183

8284
grids.forEach(function (grid, i) {
8385
addEvents(grid, i);

doc/CHANGES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Change log
55
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
66
**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*
77

8+
- [10.2.1-dev (TBD)](#1021-dev-tbd)
89
- [10.2.1 (2024-06-23)](#1021-2024-06-23)
910
- [10.2.0 (2024-06-02)](#1020-2024-06-02)
1011
- [10.1.2 (2024-03-30)](#1012-2024-03-30)
@@ -111,6 +112,9 @@ Change log
111112

112113
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
113114

115+
## 10.2.1-dev (TBD)
116+
* fix: [#2717](https://github.com/gridstack/gridstack.js/pull/2717) load() now creates in order
117+
114118
## 10.2.1 (2024-06-23)
115119
* fix: [#2683](https://github.com/gridstack/gridstack.js/issues/2683) check for fixed grid maxRow during resize
116120
* fix: [#2694](https://github.com/gridstack/gridstack.js/issues/2694) prevent 'r' rotation to items that can't resize (locked, noResize, fixed sizes)

src/gridstack-engine.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ export class GridStackEngine {
3939
protected _prevFloat: boolean;
4040
/** @internal cached layouts of difference column count so we can restore back (eg 12 -> 1 -> 12) */
4141
protected _layouts?: GridStackNode[][]; // maps column # to array of values nodes
42+
/** @internal set during loading (which is sorted) so item gets added AFTER collision nodes */
43+
public _loading?: boolean
4244
/** @internal true while we are resizing widgets during column resize to skip certain parts */
4345
protected _inColumnResize?: boolean;
4446
/** @internal true if we have some items locked */
@@ -91,7 +93,7 @@ export class GridStackEngine {
9193

9294
// during while() collisions MAKE SURE to check entire row so larger items don't leap frog small ones (push them all down starting last in grid)
9395
let area = nn;
94-
if (this._useEntireRowArea(node, nn)) {
96+
if (!this._loading && this._useEntireRowArea(node, nn)) {
9597
area = {x: 0, w: this.column, y: nn.y, h: nn.h};
9698
collide = this.collide(node, area, opt.skip); // force new hit
9799
}
@@ -100,14 +102,14 @@ export class GridStackEngine {
100102
let newOpt: GridStackMoveOpts = {nested: true, pack: false};
101103
while (collide = collide || this.collide(node, area, opt.skip)) { // could collide with more than 1 item... so repeat for each
102104
let moved: boolean;
103-
// if colliding with a locked item OR moving down with top gravity (and collide could move up) -> skip past the collide,
105+
// if colliding with a locked item OR loading (move after) OR moving down with top gravity (and collide could move up) -> skip past the collide,
104106
// but remember that skip down so we only do this once (and push others otherwise).
105-
if (collide.locked || node._moving && !node._skipDown && nn.y > node.y && !this.float &&
107+
if (collide.locked || this._loading || node._moving && !node._skipDown && nn.y > node.y && !this.float &&
106108
// can take space we had, or before where we're going
107109
(!this.collide(collide, {...collide, y: node.y}, node) || !this.collide(collide, {...collide, y: nn.y - collide.h}, node))) {
108110
node._skipDown = (node._skipDown || nn.y > node.y);
109111
moved = this.moveNode(node, {...nn, y: collide.y + collide.h, ...newOpt});
110-
if (collide.locked && moved) {
112+
if ((collide.locked || this._loading) && moved) {
111113
Utils.copyPos(nn, node); // moving after lock become our new desired location
112114
} else if (!collide.locked && moved && opt.pack) {
113115
// we moved after and will pack: do it now and keep the original drop location, but past the old collide to see what else we might push way

src/gridstack.ts

Lines changed: 16 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,6 @@ export class GridStack {
252252
protected _sizeThrottle: () => void;
253253
/** @internal limit auto cell resizing method */
254254
protected prevWidth: number;
255-
/** @internal true when loading items to insert first rather than append */
256-
protected _insertNotAppend: boolean;
257255
/** @internal extra row added when dragging at the bottom of the grid */
258256
protected _extraDragRow = 0;
259257
/** @internal true if nested grid should get column count from our width */
@@ -421,7 +419,7 @@ export class GridStack {
421419

422420
// load any passed in children as well, which overrides any DOM layout done above
423421
if (opts.children) {
424-
let children = opts.children;
422+
const children = opts.children;
425423
delete opts.children;
426424
if (children.length) this.load(children); // don't load empty
427425
}
@@ -495,11 +493,7 @@ export class GridStack {
495493
node = this.engine.prepareNode(options);
496494
this._writeAttr(el, options);
497495

498-
if (this._insertNotAppend) {
499-
this.el.prepend(el);
500-
} else {
501-
this.el.appendChild(el);
502-
}
496+
this.el.appendChild(el);
503497

504498
this.makeWidget(el, options);
505499

@@ -703,22 +697,16 @@ export class GridStack {
703697
// make sure size 1x1 (default) is present as it may need to override current sizes
704698
items.forEach(n => { n.w = n.w || 1; n.h = n.h || 1 });
705699

706-
// if we have a mix of new items without coordinates and existing items, separate them out so they can be added after #2639
707-
let addAfter = items.filter(n => (n.x === undefined || n.y === undefined) && !Utils.find(this.engine.nodes, n.id));
708-
if (addAfter.length && addAfter.length !== items.length) {
709-
items = items.filter(n => !Utils.find(addAfter, n.id));
710-
} else addAfter = [];
711-
712-
// if passed list has coordinates, use them (insert from end to beginning for conflict resolution) else keep widget order
713-
const haveCoord = items.some(w => w.x !== undefined || w.y !== undefined);
714-
if (haveCoord) items = Utils.sort(items, -1);
715-
this._insertNotAppend = haveCoord; // if we create in reverse order...
700+
// sort items. those without coord will be appended last
701+
items = Utils.sort(items);
716702

717703
// if we're loading a layout into for example 1 column and items don't fit, make sure to save
718704
// the original wanted layout so we can scale back up correctly #1471
719-
if (items.some(n => ((n.x || 0) + (n.w || 1)) > column)) {
705+
let maxColumn = 0;
706+
items.forEach(n => { maxColumn = Math.max(maxColumn, (n.x || 0) + n.w) });
707+
if (maxColumn > column) {
720708
this._ignoreLayoutsNodeChange = true; // skip layout update
721-
this.engine.cacheLayout(items, 12, true); // TODO: 12 is arbitrary. use max value in layout ?
709+
this.engine.cacheLayout(items, maxColumn, true);
722710
}
723711

724712
// if given a different callback, temporally set it as global option so creating will use it
@@ -728,19 +716,18 @@ export class GridStack {
728716
let removed: GridStackNode[] = [];
729717
this.batchUpdate();
730718

731-
// if we are blank (loading into empty like startup) temp remove animation
732-
const noAnim = !this.engine.nodes.length;
733-
if (noAnim) this.setAnimation(false);
719+
// if we are loading from empty temporarily remove animation
720+
const blank = !this.engine.nodes.length;
721+
if (blank) this.setAnimation(false);
734722

735723
// see if any items are missing from new layout and need to be removed first
736-
if (addRemove) {
724+
if (!blank && addRemove) {
737725
let copyNodes = [...this.engine.nodes]; // don't loop through array you modify
738726
copyNodes.forEach(n => {
739727
if (!n.id) return;
740728
let item = Utils.find(items, n.id);
741729
if (!item) {
742-
if (GridStack.addRemoveCB)
743-
GridStack.addRemoveCB(this.el, n, false, false);
730+
if (GridStack.addRemoveCB) GridStack.addRemoveCB(this.el, n, false, false);
744731
removed.push(n); // batch keep track
745732
this.removeWidget(n.el, true, false);
746733
}
@@ -749,6 +736,7 @@ export class GridStack {
749736

750737
// now add/update the widgets - starting with removing items in the new layout we will reposition
751738
// to reduce collision and add no-coord ones at next available spot
739+
this.engine._loading = true; // help with collision
752740
let updateNodes: GridStackWidget[] = [];
753741
this.engine.nodes = this.engine.nodes.filter(n => {
754742
if (Utils.find(items, n.id)) { updateNodes.push(n); return false; } // remove if found from list
@@ -778,28 +766,22 @@ export class GridStack {
778766
let sub = item.el.querySelector('.grid-stack') as GridHTMLElement;
779767
if (sub && sub.gridstack) {
780768
sub.gridstack.load(w.subGridOpts.children); // TODO: support updating grid options ?
781-
this._insertNotAppend = true; // got reset by above call
782769
}
783770
}
784771
} else if (addRemove) {
785772
this.addWidget(w);
786773
}
787774
});
788775

789-
// finally append any separate ones that didn't have explicit coordinates last so they can find next empty spot
790-
if (addRemove) {
791-
addAfter.forEach(w => this.addWidget(w))
792-
}
793-
776+
delete this.engine._loading; // done loading
794777
this.engine.removedNodes = removed;
795778
this.batchUpdate(false);
796779

797780
// after commit, clear that flag
798781
delete this._ignoreLayoutsNodeChange;
799-
delete this._insertNotAppend;
800782
prevCB ? GridStack.addRemoveCB = prevCB : delete GridStack.addRemoveCB;
801783
// delay adding animation back
802-
if (noAnim && this.opts?.animate) this.setAnimation(this.opts.animate, true);
784+
if (blank && this.opts?.animate) this.setAnimation(this.opts.animate, true);
803785
return this;
804786
}
805787

0 commit comments

Comments
 (0)