Skip to content

Commit 2876398

Browse files
author
Alain Dumesny
authored
1 column edit propagation fixes (#1127)
* more fix #37 and part2 of #1120 * editing in 1 column (or few columns) does a better job updating higher layout * track before and after and move items accordingly. Tracking item swap would be even better still * column.html demo has been updated to support item delete. * karma test updated
1 parent c543b08 commit 2876398

File tree

4 files changed

+60
-26
lines changed

4 files changed

+60
-26
lines changed

demo/column.html

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ <h1>setColumn() grid demo</h1>
5353
}
5454

5555
var items = [
56+
/* match karma testing
57+
{x: 0, y: 0, width: 4, height: 2},
58+
{x: 4, y: 0, width: 4, height: 4},
59+
{text: ' auto'},
60+
*/
5661
{x: 0, y: 0, width: 2, height: 2},
5762
{x: 2, y: 0, width: 2, height: 1},
5863
{x: 5, y: 1, width: 1, height: 1},
@@ -63,22 +68,21 @@ <h1>setColumn() grid demo</h1>
6368
];
6469
var count = 0;
6570
grid.batchUpdate();
66-
for (count=0; count<4;) {
67-
var n = items[count];
68-
grid.addWidget($('<div><div class="grid-stack-item-content">' + count++ + (n.text ? n.text : '') + '</div></div>'), n);
69-
};
71+
addWidget(); addWidget(); addWidget(); addWidget();
7072
grid.commit();
7173

72-
$('#add-widget').click(function() {
74+
function addWidget() {
7375
var n = items[count] || {
7476
x: Math.round(12 * Math.random()),
7577
y: Math.round(5 * Math.random()),
7678
width: Math.round(1 + 3 * Math.random()),
7779
height: Math.round(1 + 3 * Math.random())
7880
};
79-
grid.addWidget($('<div><div class="grid-stack-item-content">' + count++ + (n.text ? n.text : '') + '</div></div>'), n);
80-
});
81+
grid.addWidget($('<div><div class="grid-stack-item-content"><button onclick="grid.removeWidget(this.parentNode.parentNode)">X</button><br>'
82+
+ count++ + (n.text ? n.text : '') + '</div></div>'), n);
83+
};
8184

85+
$('#add-widget').click(function() { addWidget() });
8286
$('#1column').click(function() { delete grid.opts.oneColumnModeDomSort; grid.setColumn(1); $text.text(1);});
8387
$('#1columnDOM').click(function() { grid.opts.oneColumnModeDomSort = true; grid.setColumn(1); $text.text('1 DOM');});
8488
$('#2column').click(function() { grid.setColumn(2); $text.text(2);});

doc/CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ Change log
3131

3232
- add `oneColumnModeDomSort` true|false to let you specify a custom layout (use dom order instead of x,y) for oneColumnMode `setColumn(1)` [#713](https://github.com/gridstack/gridstack.js/issues/713)
3333
- fix oneColumnMode to only restore if we auto went to it as window sizes up [#1125](https://github.com/gridstack/gridstack.js/pull/1125)
34+
- editing in 1 column (or few columns) does a better job updating higher layout (track before and after and move items accordingly).
35+
Tracking item swap would be even better still. [#1127](https://github.com/gridstack/gridstack.js/pull/1127)
3436

3537
## v0.6.1 (2020-02-02)
3638

spec/gridstack-spec.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ describe('gridstack', function() {
383383
expect(parseInt(el2.attr('data-gs-height'))).toBe(4);
384384

385385
expect(parseInt(el3.attr('data-gs-x'))).toBe(0);
386-
expect(parseInt(el3.attr('data-gs-y'))).toBe(6);
386+
expect(parseInt(el3.attr('data-gs-y'))).toBe(6); // ??? keep same row, but might more intuitive higher
387387
expect(parseInt(el3.attr('data-gs-width'))).toBe(1); // ??? could take entire width if it did above
388388
expect(parseInt(el3.attr('data-gs-height'))).toBe(1);
389389

@@ -397,6 +397,7 @@ describe('gridstack', function() {
397397
expect(parseInt(el3.attr('data-gs-width'))).toBe(1);
398398
expect(parseInt(el3.attr('data-gs-height'))).toBe(1);
399399

400+
expect(parseInt(el1.attr('data-gs-x'))).toBe(0);
400401
expect(parseInt(el1.attr('data-gs-y'))).toBe(1);
401402
expect(parseInt(el1.attr('data-gs-width'))).toBe(1);
402403
expect(parseInt(el1.attr('data-gs-height'))).toBe(2);
@@ -420,8 +421,8 @@ describe('gridstack', function() {
420421
expect(parseInt(el1.attr('data-gs-width'))).toBe(4);
421422
expect(parseInt(el1.attr('data-gs-height'))).toBe(2);
422423

423-
expect(parseInt(el2.attr('data-gs-x'))).toBe(0);
424-
expect(parseInt(el2.attr('data-gs-y'))).toBe(3);
424+
expect(parseInt(el2.attr('data-gs-x'))).toBe(4);
425+
expect(parseInt(el2.attr('data-gs-y'))).toBe(1);
425426
expect(parseInt(el2.attr('data-gs-width'))).toBe(4);
426427
expect(parseInt(el2.attr('data-gs-height'))).toBe(4);
427428

@@ -440,8 +441,8 @@ describe('gridstack', function() {
440441
expect(parseInt(el1.attr('data-gs-width'))).toBe(1);
441442
expect(parseInt(el1.attr('data-gs-height'))).toBe(2);
442443

443-
expect(parseInt(el2.attr('data-gs-x'))).toBe(0);
444-
expect(parseInt(el2.attr('data-gs-y'))).toBe(3);
444+
expect(parseInt(el2.attr('data-gs-x'))).toBe(1);
445+
expect(parseInt(el2.attr('data-gs-y'))).toBe(1);
445446
expect(parseInt(el2.attr('data-gs-width'))).toBe(1);
446447
expect(parseInt(el2.attr('data-gs-height'))).toBe(4);
447448
});

src/gridstack.js

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -355,12 +355,12 @@
355355

356356
if (this.float) {
357357
this.nodes.forEach(function(n, i) {
358-
if (n._updating || n._origY === undefined || n.y === n._origY) {
358+
if (n._updating || n._packY === undefined || n.y === n._packY) {
359359
return;
360360
}
361361

362362
var newY = n.y;
363-
while (newY >= n._origY) {
363+
while (newY >= n._packY) {
364364
var collisionNode = this.nodes
365365
.slice(0, i)
366366
.find(Utils._didCollide, {n: n, newY: newY});
@@ -653,14 +653,14 @@
653653
GridStackEngine.prototype.beginUpdate = function(node) {
654654
if (node._updating) return;
655655
node._updating = true;
656-
this.nodes.forEach(function(n) { n._origY = n.y; });
656+
this.nodes.forEach(function(n) { n._packY = n.y; });
657657
};
658658

659659
GridStackEngine.prototype.endUpdate = function() {
660660
var n = this.nodes.find(function(n) { return n._updating; });
661661
if (n) {
662662
n._updating = false;
663-
this.nodes.forEach(function(n) { delete n._origY; });
663+
this.nodes.forEach(function(n) { delete n._packY; });
664664
}
665665
};
666666

@@ -1801,23 +1801,37 @@
18011801
GridStackEngine.prototype._layoutsNodesChange = function(nodes) {
18021802
if (!this._layouts || this._ignoreLayoutsNodeChange) return;
18031803
// remove smaller layouts - we will re-generate those on the fly... larger ones need to update
1804-
this._layouts.forEach(function(layout, i) {
1805-
if (!layout || i === this.column) return;
1806-
if (i < this.column) {
1807-
this._layouts[i] = undefined;
1804+
this._layouts.forEach(function(layout, column) {
1805+
if (!layout || column === this.column) return;
1806+
if (column < this.column) {
1807+
this._layouts[column] = undefined;
18081808
}
18091809
else {
1810-
// TODO: save the original x,y,w (h isn't cached) and see what actually changed to propagate correctly ?
1810+
// we save the original x,y,w (h isn't cached) to see what actually changed to propagate better.
1811+
// Note: we don't need to check against out of bound scaling/moving as that will be done when using those cache values.
18111812
nodes.forEach(function(node) {
18121813
var n = layout.find(function(l) { return l._id === node._id });
1813-
if (!n) return;
1814-
var ratio = i / this.column;
1815-
n.y = node.y;
1816-
n.x = Math.round(node.x * ratio);
1817-
// width ???
1814+
if (!n) return; // no cache for new nodes. Will use those values.
1815+
var ratio = column / this.column;
1816+
// Y changed, push down same amount
1817+
// TODO: detect doing item 'swaps' will help instead of move (especially in 1 column mode)
1818+
if (node.y !== node._origY) {
1819+
n.y += (node.y - node._origY);
1820+
}
1821+
// X changed, scale from new position
1822+
if (node.x !== node._origX) {
1823+
n.x = Math.round(node.x * ratio);
1824+
}
1825+
// width changed, scale from new width
1826+
if (node.width !== node._origW) {
1827+
n.width = Math.round(node.width * ratio);
1828+
}
1829+
// ...height always carries over from cache
18181830
}, this);
18191831
}
18201832
}, this);
1833+
1834+
this._saveInitial(); // reset current value now that we diffed.
18211835
}
18221836

18231837
/**
@@ -1906,6 +1920,19 @@
19061920
}, this);
19071921
this.commit();
19081922
delete this._ignoreLayoutsNodeChange;
1923+
1924+
// save this initial layout so we can see what changed and apply changes to other layouts better (diff)
1925+
this._saveInitial();
1926+
}
1927+
1928+
/** called to save initial position/size */
1929+
GridStackEngine.prototype._saveInitial = function() {
1930+
this.nodes.forEach(function(n) {
1931+
n._origX = n.x;
1932+
n._origY = n.y;
1933+
n._origW = n.width;
1934+
n._origH = n.height;
1935+
});
19091936
}
19101937

19111938
/**

0 commit comments

Comments
 (0)