Skip to content

Commit 5035a18

Browse files
author
Alain Dumesny
authored
Merge pull request #1097 from adumesny/develop
much faster removeAll(), single event trigger
2 parents bf28a78 + f7e46c5 commit 5035a18

File tree

6 files changed

+90
-23
lines changed

6 files changed

+90
-23
lines changed

demo/responsive.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,9 @@ <h1>Responsive grid demo</h1>
8585
this.grid = $('.grid-stack').data('gridstack');
8686

8787
this.loadGrid = function () {
88-
this.grid.batchUpdate();
8988
this.grid.removeAll();
9089
var items = GridStackUI.Utils.sort(this.serializedData);
90+
this.grid.batchUpdate();
9191
items.forEach(function (node, i) {
9292
this.grid.addWidget($('<div><div class="grid-stack-item-content">' + i + '</div></div>'), node);
9393
}.bind(this));

demo/serialization.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ <h1>Serialization demo</h1>
5656
this.grid = $('.grid-stack').data('gridstack');
5757

5858
this.loadGrid = function () {
59-
this.grid.batchUpdate();
6059
this.grid.removeAll();
6160
var items = GridStackUI.Utils.sort(this.serializedData);
61+
this.grid.batchUpdate();
6262
items.forEach(function (node) {
6363
this.grid.addWidget($('<div><div class="grid-stack-item-content"></div></div>'), node);
6464
}, this);

doc/CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Change log
3232
- fixed callbacks to get either `added, removed, change` or combination if adding a node require also to change its (x,y) for example.
3333
Also you can now call `batchUpdate()` before calling a bunch of `addWidget()` and get a single event callback (more efficient).
3434
[#1096](https://github.com/gridstack/gridstack.js/pull/1096)
35+
- `removeAll()` is now much faster (no relayout) and calls `removed` event just once with a list
3536

3637
## v0.5.5 (2019-11-27)
3738

spec/e2e/html/gridstack-with-height.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ <h1>gridstack.js tests</h1>
3535
];
3636

3737
this.grid = $('.grid-stack').data('gridstack');
38-
this.grid.batchUpdate();
3938
this.grid.removeAll();
4039
items = GridStackUI.Utils.sort(items);
4140
var id = 0;
41+
this.grid.batchUpdate();
4242
items.forEach(function(node) {
4343
var w = $('<div><div class="grid-stack-item-content"></div></div>');
4444
w.attr('id', 'item-' + (++id));

spec/gridstack-spec.js

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@ describe('gridstack', function() {
77
var gridstackHTML =
88
'<div style="width: 992px; height: 800px" id="gs-cont">' +
99
' <div class="grid-stack">' +
10-
' <div class="grid-stack-item" data-gs-x="0" data-gs-y="0" data-gs-width="4" data-gs-height="2">' +
10+
' <div class="grid-stack-item" data-gs-x="0" data-gs-y="0" data-gs-width="4" data-gs-height="2" id="item1">' +
1111
' <div class="grid-stack-item-content"></div>' +
1212
' </div>' +
13-
' <div class="grid-stack-item" data-gs-x="4" data-gs-y="0" data-gs-width="4" data-gs-height="4">' +
13+
' <div class="grid-stack-item" data-gs-x="4" data-gs-y="0" data-gs-width="4" data-gs-height="4" id="item2">' +
1414
' <div class="grid-stack-item-content"></div>' +
1515
' </div>' +
1616
' </div>' +
1717
'</div>';
1818
// generic widget with no param
19-
var widgetHTML = '<div class="grid-stack-item"><div class="grid-stack-item-content"> hello </div></div>';
19+
var widgetHTML = '<div class="grid-stack-item" id="item3"><div class="grid-stack-item-content"> hello </div></div>';
2020

2121
beforeEach(function() {
2222
w = window;
@@ -457,6 +457,68 @@ describe('gridstack', function() {
457457
});
458458
});
459459

460+
describe('grid.removeAll', function() {
461+
beforeEach(function() {
462+
document.body.insertAdjacentHTML('afterbegin', gridstackHTML);
463+
});
464+
afterEach(function() {
465+
document.body.removeChild(document.getElementById('gs-cont'));
466+
});
467+
it('should remove all children by default', function() {
468+
$('.grid-stack').gridstack();
469+
var grid = $('.grid-stack').data('gridstack');
470+
grid.removeAll();
471+
expect(grid.grid.nodes).toEqual([]);
472+
expect(document.getElementById('item1')).toBe(null);
473+
});
474+
it('should remove all children', function() {
475+
$('.grid-stack').gridstack();
476+
var grid = $('.grid-stack').data('gridstack');
477+
grid.removeAll(true);
478+
expect(grid.grid.nodes).toEqual([]);
479+
expect(document.getElementById('item1')).toBe(null);
480+
});
481+
it('should remove gridstack part, leave DOM behind', function() {
482+
$('.grid-stack').gridstack();
483+
var grid = $('.grid-stack').data('gridstack');
484+
grid.removeAll(false);
485+
expect(grid.grid.nodes).toEqual([]);
486+
expect(document.getElementById('item1')).not.toBe(null);
487+
});
488+
});
489+
490+
describe('grid.removeWidget', function() {
491+
beforeEach(function() {
492+
document.body.insertAdjacentHTML('afterbegin', gridstackHTML);
493+
});
494+
afterEach(function() {
495+
document.body.removeChild(document.getElementById('gs-cont'));
496+
});
497+
it('should remove first item (default), then second (true), then third (false)', function() {
498+
$('.grid-stack').gridstack();
499+
var grid = $('.grid-stack').data('gridstack');
500+
expect(grid.grid.nodes.length).toEqual(2);
501+
502+
var el1 = document.getElementById('item1');
503+
expect(el1).not.toBe(null);
504+
grid.removeWidget(el1);
505+
expect(grid.grid.nodes.length).toEqual(1);
506+
expect(document.getElementById('item1')).toBe(null);
507+
expect(document.getElementById('item2')).not.toBe(null);
508+
509+
var el2 = document.getElementById('item2');
510+
grid.removeWidget(el2, true);
511+
expect(grid.grid.nodes.length).toEqual(0);
512+
expect(document.getElementById('item2')).toBe(null);
513+
514+
var el3 = grid.addWidget(widgetHTML);
515+
expect(el3).not.toBe(null);
516+
grid.removeWidget(el3, false);
517+
expect(grid.grid.nodes.length).toEqual(0);
518+
expect(document.getElementById('item3')).not.toBe(null);
519+
});
520+
});
521+
460522
describe('grid method obsolete warnings', function() {
461523
beforeEach(function() {
462524
document.body.insertAdjacentHTML('afterbegin', gridstackHTML);

src/gridstack.js

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,8 @@
460460
GridStackEngine.prototype._notify = function() {
461461
if (this._batchMode) { return; }
462462
var args = Array.prototype.slice.call(arguments, 0);
463-
args[0] = args[0] === undefined ? [] : [args[0]];
464-
args[1] = args[1] === undefined ? true : args[1];
463+
args[0] = (args[0] === undefined ? [] : (Array.isArray(args[0]) ? args[0] : [args[0]]) );
464+
args[1] = (args[1] === undefined ? true : args[1]);
465465
var dirtyNodes = args[0].concat(this.getDirtyNodes());
466466
this.onchange(dirtyNodes, args[1]);
467467
};
@@ -516,14 +516,23 @@
516516
};
517517

518518
GridStackEngine.prototype.removeNode = function(node, detachNode) {
519-
detachNode = detachNode === undefined ? true : detachNode;
520-
this._removedNodes.push(Utils.clone(node));
519+
detachNode = (detachNode === undefined ? true : detachNode);
520+
this._removedNodes.push(node);
521521
node._id = null;
522522
this.nodes = Utils.without(this.nodes, node);
523523
this._packNodes();
524524
this._notify(node, detachNode);
525525
};
526526

527+
GridStackEngine.prototype.removeAll = function(detachNode) {
528+
if (this.nodes.length === 0) { return; }
529+
detachNode = (detachNode === undefined ? true : detachNode);
530+
this.nodes.forEach(function(n) { n._id = null; }); // hint that node is being removed
531+
this._removedNodes = this.nodes;
532+
this.nodes = [];
533+
this._notify(this._removedNodes, detachNode);
534+
};
535+
527536
GridStackEngine.prototype.canMoveNode = function(node, x, y, width, height) {
528537
if (!this.isNodeChangedPosition(node, x, y, width, height)) {
529538
return false;
@@ -764,7 +773,7 @@
764773
this._initStyles();
765774

766775
this.grid = new GridStackEngine(this.opts.column, function(nodes, detachNode) {
767-
detachNode = detachNode === undefined ? true : detachNode;
776+
detachNode = (detachNode === undefined ? true : detachNode);
768777
var maxHeight = 0;
769778
this.nodes.forEach(function(n) {
770779
maxHeight = Math.max(maxHeight, n.y + n.height);
@@ -1475,31 +1484,27 @@
14751484
};
14761485

14771486
GridStack.prototype.removeWidget = function(el, detachNode) {
1478-
detachNode = detachNode === undefined ? true : detachNode;
1487+
detachNode = (detachNode === undefined ? true : detachNode);
14791488
el = $(el);
14801489
var node = el.data('_gridstack_node');
1481-
14821490
// For Meteor support: https://github.com/gridstack/gridstack.js/pull/272
14831491
if (!node) {
14841492
node = this.grid.getNodeDataByDOMEl(el);
14851493
}
14861494

1487-
this.grid.removeNode(node, detachNode);
14881495
el.removeData('_gridstack_node');
1489-
this._updateContainerHeight();
1490-
if (detachNode) {
1491-
el.remove();
1492-
}
1496+
this.grid.removeNode(node, detachNode);
14931497
this._triggerRemoveEvent();
14941498
// this._triggerChangeEvent(true); already have removeEvent
14951499
};
14961500

14971501
GridStack.prototype.removeAll = function(detachNode) {
1502+
// remove our data structure before list gets emptied (in case detachNode is false)
14981503
this.grid.nodes.forEach(function(node) {
1499-
this.removeWidget(node.el, detachNode);
1500-
}, this);
1501-
this.grid.nodes = [];
1502-
this._updateContainerHeight();
1504+
node.el.removeData('_gridstack_node');
1505+
});
1506+
this.grid.removeAll(detachNode);
1507+
this._triggerRemoveEvent();
15031508
};
15041509

15051510
GridStack.prototype.destroy = function(detachGrid) {
@@ -1761,7 +1766,6 @@
17611766

17621767
GridStack.prototype.commit = function() {
17631768
this.grid.commit();
1764-
this._updateContainerHeight();
17651769
this._triggerRemoveEvent();
17661770
this._triggerAddEvent();
17671771
this._triggerChangeEvent();

0 commit comments

Comments
 (0)