Skip to content

Commit ebdc1a2

Browse files
authored
Merge pull request #1720 from adumesny/master
`addWidget()` while in 1 column fix
2 parents 637490a + fc918a4 commit ebdc1a2

File tree

4 files changed

+37
-11
lines changed

4 files changed

+37
-11
lines changed

demo/responsive.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ <h1>Responsive grid demo</h1>
2424
<option value="scale">scale</option>
2525
<option value="none">none</option>
2626
</select>
27+
<a onClick="grid.removeAll()" class="btn btn-primary" href="#">Clear</a>
28+
<a onClick="addWidget()" class="btn btn-primary" href="#">Add Widget</a>
2729
</div>
2830
<br/>
2931
<div class="grid-stack">
@@ -58,6 +60,10 @@ <h1>Responsive grid demo</h1>
5860
text.innerHTML = 12;
5961
}
6062
};
63+
64+
function addWidget() {
65+
grid.addWidget({x:0, y:0, w:4, content: '4x1'});
66+
};
6167

6268
let items = [ // our initial 12 column layout loaded first so we can compare
6369
{x: 0, y: 0, w: 2, content: '0'},

doc/CHANGES.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ Change log
5656
## 4.1.0-dev
5757

5858
- fix [#1704](https://github.com/gridstack/gridstack.js/issues/1704) scrollbar fix broken in 4.x
59-
- add [#1682](https://github.com/gridstack/gridstack.js/issues/1682) `addWidget()` now supports recursive grids like init/addGrid() does.
59+
- fix [#1655](https://github.com/gridstack/gridstack.js/issues/1655) `addWidget()` while in 1 column now remembers original wanted width
60+
- add [#1682](https://github.com/gridstack/gridstack.js/issues/1682) `addWidget()` now supports nested grids like init/addGrid() does.
6061

6162
## 4.1.0 (2021-4-7)
6263

src/gridstack-engine.ts

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,12 @@ export class GridStackEngine {
349349
if (node.minH) { node.h = Math.max(node.h, node.minH); }
350350

351351
if (node.w > this.column) {
352+
// if user loaded a larger than allowed widget for current # of columns,
353+
// remember it's full width so we can restore back (1 -> 12 column) #1655
354+
if (this.column < 12) {
355+
node.w = Math.min(12, node.w);
356+
this.cacheOneLayout(node, 12);
357+
}
352358
node.w = this.column;
353359
} else if (node.w < 1) {
354360
node.w = 1;
@@ -484,7 +490,7 @@ export class GridStackEngine {
484490
// don't use 'faster' .splice(findIndex(),1) in case node isn't in our list, or in multiple times.
485491
this.nodes = this.nodes.filter(n => n !== node);
486492
return this._packNodes()
487-
._notify(node, removeDOM);
493+
._notify(node);
488494
}
489495

490496
public removeAll(removeDOM = true): GridStackEngine {
@@ -493,7 +499,7 @@ export class GridStackEngine {
493499
removeDOM && this.nodes.forEach(n => n._removeDOM = true); // let CB remove actual HTML (used to set _id to null, but then we loose layout info)
494500
this.removedNodes = this.nodes;
495501
this.nodes = [];
496-
return this._notify(this.removedNodes, removeDOM);
502+
return this._notify(this.removedNodes);
497503
}
498504

499505
/** checks if item can be moved (layout constrain) vs moveNode(), returning true if was able to move.
@@ -691,8 +697,9 @@ export class GridStackEngine {
691697
// we save the original x,y,w (h isn't cached) to see what actually changed to propagate better.
692698
// Note: we don't need to check against out of bound scaling/moving as that will be done when using those cache values.
693699
nodes.forEach(node => {
700+
if (!node._orig) return; // didn't change (newly added ?)
694701
let n = layout.find(l => l._id === node._id);
695-
if (!n) return this; // no cache for new nodes. Will use those values.
702+
if (!n) return; // no cache for new nodes. Will use those values.
696703
let ratio = column / this.column;
697704
// Y changed, push down same amount
698705
// TODO: detect doing item 'swaps' will help instead of move (especially in 1 column mode)
@@ -828,6 +835,21 @@ export class GridStackEngine {
828835
return this;
829836
}
830837

838+
/**
839+
* call to cache the given node layout internally to the given location so we can restore back when column changes size
840+
* @param node single node to cache
841+
* @param column corresponding column index to save it under
842+
*/
843+
public cacheOneLayout(n: GridStackNode, column: number): GridStackEngine {
844+
n._id = n._id || GridStackEngine._idSeq++;
845+
let layout: Layout = {x: n.x, y: n.y, w: n.w, _id: n._id}
846+
this._layouts = this._layouts || [];
847+
this._layouts[column] = this._layouts[column] || [];
848+
let index = this._layouts[column].findIndex(l => l._id === n._id);
849+
index === -1 ? this._layouts[column].push(layout) : this._layouts[column][index] = layout;
850+
return this;
851+
}
852+
831853

832854
/** called to remove all internal values but the _id */
833855
public cleanupNode(node: GridStackNode): GridStackEngine {

src/gridstack.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,6 @@ export class GridStack {
211211
/** @internal */
212212
private _placeholder: HTMLElement;
213213
/** @internal */
214-
private _oneColumnMode: boolean;
215-
/** @internal */
216214
private _prevColumn: number;
217215
/** @internal */
218216
private _ignoreLayoutsNodeChange: boolean;
@@ -314,12 +312,12 @@ export class GridStack {
314312
column: this.opts.column,
315313
float: this.opts.float,
316314
maxRow: this.opts.maxRow,
317-
onChange: (cbNodes, removeDOM = true) => {
315+
onChange: (cbNodes) => {
318316
let maxH = 0;
319317
this.engine.nodes.forEach(n => { maxH = Math.max(maxH, n.y + n.h) });
320318
cbNodes.forEach(n => {
321319
let el = n.el;
322-
if (removeDOM && n._removeDOM) { // TODO: do we need to pass 'removeDOM' ?
320+
if (n._removeDOM) {
323321
if (el) el.remove();
324322
delete n._removeDOM;
325323
} else {
@@ -498,7 +496,7 @@ export class GridStack {
498496
* see http://gridstackjs.com/demo/serialization.html
499497
**/
500498
public load(layout: GridStackWidget[], addAndRemove: boolean | ((g: GridStack, w: GridStackWidget, add: boolean) => GridItemHTMLElement) = true): GridStack {
501-
let items = GridStack.Utils.sort(layout, -1, this._prevColumn || this.opts.column);
499+
let items = GridStack.Utils.sort([...layout], -1, this._prevColumn || this.opts.column); // make copy before we mod/sort
502500
this._insertNotAppend = true; // since create in reverse order...
503501

504502
// if we're loading a layout into 1 column (_prevColumn is set only when going to 1) and items don't fit, make sure to save
@@ -1334,8 +1332,7 @@ export class GridStack {
13341332
let oneColumn = !this.opts.disableOneColumnMode && this.el.clientWidth <= this.opts.minWidth;
13351333
let changedOneColumn = false;
13361334

1337-
if (!this._oneColumnMode !== !oneColumn) { // use ! (negate) so we can check undefined == false vs true
1338-
this._oneColumnMode = oneColumn;
1335+
if ((this.opts.column === 1) !== oneColumn) {
13391336
changedOneColumn = true;
13401337
if (this.opts.animate) { this.setAnimation(false); } // 1 <-> 12 is too radical, turn off animation
13411338
this.column(oneColumn ? 1 : this._prevColumn);

0 commit comments

Comments
 (0)