|
473 | 473 | this.nodes.forEach(function(n) { delete n._dirty; }); |
474 | 474 | }; |
475 | 475 |
|
476 | | - GridStackEngine.prototype.getDirtyNodes = function() { |
| 476 | + GridStackEngine.prototype.getDirtyNodes = function(verify) { |
| 477 | + // compare original X,Y,W,H (or entire node?) instead as _dirty can be a temporary state |
| 478 | + if (verify) { |
| 479 | + var dirtNodes = []; |
| 480 | + this.nodes.forEach(function (n) { |
| 481 | + if (n._dirty) { |
| 482 | + if (n.y === n._origY && n.x === n._origX && n.width === n._origW && n.height === n._origH) { |
| 483 | + delete n._dirty; |
| 484 | + } else { |
| 485 | + dirtNodes.push(n); |
| 486 | + } |
| 487 | + } |
| 488 | + }); |
| 489 | + return dirtNodes; |
| 490 | + } |
| 491 | + |
477 | 492 | return this.nodes.filter(function(n) { return n._dirty; }); |
478 | 493 | }; |
479 | 494 |
|
480 | 495 | GridStackEngine.prototype.addNode = function(node, triggerAddEvent) { |
481 | | - var prev = {x: node.x, y: node.y, width: node.width, height: node.height}; |
482 | | - |
483 | 496 | node = this._prepareNode(node); |
484 | 497 |
|
485 | 498 | if (node.maxWidth !== undefined) { node.width = Math.min(node.width, node.maxWidth); } |
|
511 | 524 | if (triggerAddEvent) { |
512 | 525 | this._addedNodes.push(node); |
513 | 526 | } |
514 | | - // use single equal as they come as string/undefined but end as number.... |
515 | | - if (!node._dirty && (prev.x != node.x || prev.y != node.y || prev.width != node.width || prev.height != node.height)) { |
516 | | - node._dirty = true; |
517 | | - } |
518 | 527 |
|
519 | 528 | this._fixCollisions(node); |
520 | 529 | this._packNodes(); |
|
671 | 680 | } |
672 | 681 | }; |
673 | 682 |
|
| 683 | + /** |
| 684 | + * Construct a grid from the given element and options |
| 685 | + * @param {GridStackElement} el |
| 686 | + * @param {GridstackOptions} opts |
| 687 | + */ |
674 | 688 | var GridStack = function(el, opts) { |
675 | 689 | var self = this; |
676 | 690 | var oneColumnMode, _prevColumn, isAutoCellHeight; |
|
809 | 823 | this._prepareElement(item.el); |
810 | 824 | }, this); |
811 | 825 | } |
| 826 | + this.grid._saveInitial(); // initial start of items |
812 | 827 |
|
813 | 828 | this.setAnimation(this.opts.animate); |
814 | 829 |
|
|
1018 | 1033 |
|
1019 | 1034 | GridStack.prototype._triggerChangeEvent = function(/*forceTrigger*/) { |
1020 | 1035 | if (this.grid._batchMode) { return; } |
1021 | | - // TODO: compare original X,Y,W,H (or entire node?) instead as _dirty can be a temporary state |
1022 | | - var elements = this.grid.getDirtyNodes(); |
| 1036 | + var elements = this.grid.getDirtyNodes(true); // verify they really changed |
1023 | 1037 | if (elements && elements.length) { |
1024 | 1038 | this.grid._layoutsNodesChange(elements); |
1025 | 1039 | this.container.trigger('change', [elements]); |
1026 | | - this.grid.cleanNodes(); // clear dirty flags now that we called |
1027 | 1040 | } |
| 1041 | + this.grid._saveInitial(); // we called, now reset initial values & dirty flags |
1028 | 1042 | }; |
1029 | 1043 |
|
1030 | 1044 | GridStack.prototype._triggerAddEvent = function() { |
1031 | 1045 | if (this.grid._batchMode) { return; } |
1032 | 1046 | if (this.grid._addedNodes && this.grid._addedNodes.length > 0) { |
1033 | 1047 | this.grid._layoutsNodesChange(this.grid._addedNodes); |
| 1048 | + // prevent added nodes from also triggering 'change' event (which is called next) |
| 1049 | + this.grid._addedNodes.forEach(function (n) { delete n._dirty; }); |
1034 | 1050 | this.container.trigger('added', [this.grid._addedNodes]); |
1035 | 1051 | this.grid._addedNodes = []; |
1036 | 1052 | } |
|
1450 | 1466 | el = $(el); |
1451 | 1467 | this._writeAttr(el, node); |
1452 | 1468 | this.container.append(el); |
1453 | | - this._prepareElement(el, true); |
1454 | | - this._updateContainerHeight(); |
1455 | | - this._triggerAddEvent(); |
1456 | | - this._triggerChangeEvent(true); // trigger any other changes |
1457 | | - |
1458 | | - return el; |
| 1469 | + return this.makeWidget(el); |
1459 | 1470 | }; |
1460 | 1471 |
|
1461 | 1472 | GridStack.prototype.makeWidget = function(el) { |
|
1697 | 1708 | this.grid._sortNodes(); |
1698 | 1709 | var nodes = this.grid.nodes; |
1699 | 1710 | this.grid.nodes = []; // pretend we have no nodes to conflict layout to start with... |
1700 | | - nodes.forEach(function(n) { |
1701 | | - if (!n.noMove && !n.locked) { |
1702 | | - n.autoPosition = true; |
| 1711 | + nodes.forEach(function(node) { |
| 1712 | + if (!node.noMove && !node.locked) { |
| 1713 | + node.autoPosition = true; |
1703 | 1714 | } |
1704 | | - this.grid.addNode(n, false); // 'false' for add event trigger |
| 1715 | + this.grid.addNode(node, false); // 'false' for add event trigger... |
| 1716 | + node._dirty = true; // force attr update |
1705 | 1717 | }, this); |
1706 | 1718 | this.commit(); |
1707 | 1719 | }; |
|
1833 | 1845 | }, this); |
1834 | 1846 | } |
1835 | 1847 | }, this); |
1836 | | - |
1837 | | - this._saveInitial(); // reset current value now that we diffed. |
1838 | 1848 | } |
1839 | 1849 |
|
1840 | 1850 | /** |
|
1923 | 1933 | }, this); |
1924 | 1934 | this.commit(); |
1925 | 1935 | delete this._ignoreLayoutsNodeChange; |
1926 | | - |
1927 | | - // save this initial layout so we can see what changed and apply changes to other layouts better (diff) |
1928 | | - this._saveInitial(); |
1929 | 1936 | } |
1930 | 1937 |
|
1931 | 1938 | /** called to save initial position/size */ |
|
1935 | 1942 | n._origY = n.y; |
1936 | 1943 | n._origW = n.width; |
1937 | 1944 | n._origH = n.height; |
| 1945 | + delete n._dirty; |
1938 | 1946 | }); |
1939 | 1947 | } |
1940 | 1948 |
|
|
1992 | 2000 | if (!val) { |
1993 | 2001 | this.grid._packNodes(); |
1994 | 2002 | this.grid._notify(); |
| 2003 | + this._triggerChangeEvent(); |
1995 | 2004 | } |
1996 | 2005 | }; |
1997 | 2006 |
|
|
0 commit comments