Skip to content

Commit d52cc93

Browse files
Improved minRow and row is not a shortcut for minRow and maxRow
1 parent baa8cde commit d52cc93

File tree

1 file changed

+63
-49
lines changed

1 file changed

+63
-49
lines changed

src/gridstack.js

Lines changed: 63 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -296,12 +296,10 @@
296296

297297
var idSeq = 0;
298298

299-
var GridStackEngine = function(row, column, onchange, float, minRow, maxRow, items) {
300-
this.row = row || 0;
299+
var GridStackEngine = function(column, onchange, float, maxRow, items) {
301300
this.column = column || 12;
302301
this.float = float || false;
303-
this.minRow = minRow || 0;
304-
this.maxRow = this.row ? this.row : maxRow || 0;
302+
this.maxRow = maxRow || 0;
305303

306304
this.nodes = items || [];
307305
this.onchange = onchange || function() {};
@@ -344,8 +342,9 @@
344342
while (true) {
345343
var collisionNode = this.nodes.find(Utils._collisionNodeCheck, {node: node, nn: nn});
346344
if (!collisionNode) { return; }
347-
this.moveNode(collisionNode, collisionNode.x, node.y + node.height,
345+
var moved = this.moveNode(collisionNode, collisionNode.x, node.y + node.height,
348346
collisionNode.width, collisionNode.height, true);
347+
if (!moved) { return; } // break inf loop if we couldn't move after all (ex: maxRow, fixed)
349348
}
350349
};
351350

@@ -434,19 +433,28 @@
434433
if (Number.isNaN(node.width)) { node.width = defaults.width; }
435434
if (Number.isNaN(node.height)) { node.height = defaults.height; }
436435

436+
if (node.maxWidth !== undefined) { node.width = Math.min(node.width, node.maxWidth); }
437+
if (node.maxHeight !== undefined) { node.height = Math.min(node.height, node.maxHeight); }
438+
if (node.minWidth !== undefined) { node.width = Math.max(node.width, node.minWidth); }
439+
if (node.minHeight !== undefined) { node.height = Math.max(node.height, node.minHeight); }
440+
437441
if (node.width > this.column) {
438442
node.width = this.column;
439443
} else if (node.width < 1) {
440444
node.width = 1;
441445
}
442-
443-
if (node.height < 1) {
446+
if (this.maxRow && node.height > this.maxRow) {
447+
node.height = this.maxRow;
448+
} else if (node.height < 1) {
444449
node.height = 1;
445450
}
446451

447452
if (node.x < 0) {
448453
node.x = 0;
449454
}
455+
if (node.y < 0) {
456+
node.y = 0;
457+
}
450458

451459
if (node.x + node.width > this.column) {
452460
if (resizing) {
@@ -455,9 +463,12 @@
455463
node.x = this.column - node.width;
456464
}
457465
}
458-
459-
if (node.y < 0) {
460-
node.y = 0;
466+
if (this.maxRow && node.y + node.height > this.maxRow) {
467+
if (resizing) {
468+
node.height = this.maxRow - node.y;
469+
} else {
470+
node.y = this.maxRow - node.height;
471+
}
461472
}
462473

463474
return node;
@@ -499,11 +510,6 @@
499510
GridStackEngine.prototype.addNode = function(node, triggerAddEvent) {
500511
node = this._prepareNode(node);
501512

502-
if (node.maxWidth !== undefined) { node.width = Math.min(node.width, node.maxWidth); }
503-
if (node.maxHeight !== undefined) { node.height = Math.min(node.height, node.maxHeight); }
504-
if (node.minWidth !== undefined) { node.width = Math.max(node.width, node.minWidth); }
505-
if (node.minHeight !== undefined) { node.height = Math.max(node.height, node.minHeight); }
506-
507513
node._id = node._id || ++idSeq;
508514

509515
if (node.autoPosition) {
@@ -560,18 +566,16 @@
560566
}
561567
var hasLocked = Boolean(this.nodes.find(function(n) { return n.locked; }));
562568

563-
if (!this.maxRow && !this.row && !hasLocked) {
569+
if (!this.maxRow && !hasLocked) {
564570
return true;
565571
}
566572

567573
var clonedNode;
568574
var clone = new GridStackEngine(
569-
0,
570575
this.column,
571576
null,
572577
this.float,
573578
0,
574-
0,
575579
this.nodes.map(function(n) {
576580
if (n === node) {
577581
clonedNode = $.extend({}, n);
@@ -591,24 +595,23 @@
591595
return n !== clonedNode && Boolean(n.locked) && Boolean(n._dirty);
592596
}));
593597
}
594-
if (this.maxRow || this.row) {
598+
if (this.maxRow) {
595599
res &= clone.getRow() <= this.maxRow;
596600
}
597601

598602
return res;
599603
};
600604

601605
GridStackEngine.prototype.canBePlacedWithRespectToHeight = function(node) {
602-
if (!this.maxRow && !this.row) {
606+
if (!this.maxRow) {
603607
return true;
604608
}
609+
605610
var clone = new GridStackEngine(
606-
0,
607611
this.column,
608612
null,
609613
this.float,
610614
0,
611-
0,
612615
this.nodes.map(function(n) { return $.extend({}, n); }));
613616
clone.addNode(node);
614617
return clone.getRow() <= this.maxRow;
@@ -637,29 +640,21 @@
637640
if (typeof width !== 'number') { width = node.width; }
638641
if (typeof height !== 'number') { height = node.height; }
639642

640-
if (node.maxWidth !== undefined) { width = Math.min(width, node.maxWidth); }
641-
if (node.maxHeight !== undefined) { height = Math.min(height, node.maxHeight); }
642-
if (node.minWidth !== undefined) { width = Math.max(width, node.minWidth); }
643-
if (node.minHeight !== undefined) { height = Math.max(height, node.minHeight); }
644-
645-
if (node.x === x && node.y === y && node.width === width && node.height === height) {
646-
return node;
643+
// constrain the passed in values and check if we're still changing our node
644+
var resizing = (node.width !== width || node.height !== height);
645+
var nn = { x: x, y: y, width: width, height: height,
646+
maxWidth: node.maxWidth, maxHeight: NodeIterator.maxHeight, minWidth: node.minWidth, minHeight: node.minHeight};
647+
nn = this._prepareNode(nn, resizing);
648+
if (node.x === nn.x && node.y === nn.y && node.width === nn.width && node.height === nn.height) {
649+
return null;
647650
}
648651

649-
var resizing = node.width !== width;
650652
node._dirty = true;
651653

652-
node.x = x;
653-
node.y = y;
654-
node.width = width;
655-
node.height = height;
656-
657-
node.lastTriedX = x;
658-
node.lastTriedY = y;
659-
node.lastTriedWidth = width;
660-
node.lastTriedHeight = height;
661-
662-
node = this._prepareNode(node, resizing);
654+
node.x = node.lastTriedX = nn.x;
655+
node.y = node.lastTriedY = nn.y;
656+
node.width = node.lastTriedWidth = nn.width;
657+
node.height = node.lastTriedHeight = nn.height;
663658

664659
this._fixCollisions(node);
665660
if (!noPack) {
@@ -670,7 +665,7 @@
670665
};
671666

672667
GridStackEngine.prototype.getRow = function() {
673-
return this.row ? this.row : this.nodes.reduce(function(memo, n) { return Math.max(memo, n.y + n.height); }, 0);
668+
return this.nodes.reduce(function(memo, n) { return Math.max(memo, n.y + n.height); }, 0);
674669
};
675670

676671
GridStackEngine.prototype.beginUpdate = function(node) {
@@ -716,8 +711,8 @@
716711
this.opts = Utils.defaults(opts, {
717712
row: parseInt(this.$el.attr('data-gs-row')) || 0,
718713
column: parseInt(this.$el.attr('data-gs-column')) || 12,
719-
maxRow: parseInt(this.$el.attr('data-gs-row')) || 0 ? parseInt(this.$el.attr('data-gs-row')) : parseInt(this.$el.attr('data-gs-max-row')) || 0,
720-
minRow: parseInt(this.$el.attr('data-gs-min-row')) || 0,
714+
minRow: opts.row || parseInt(this.$el.attr('data-gs-row')) ? opts.row || parseInt(this.$el.attr('data-gs-row')) : parseInt(this.$el.attr('data-gs-min-row')) || 0,
715+
maxRow: opts.row || parseInt(this.$el.attr('data-gs-row')) ? opts.row || parseInt(this.$el.attr('data-gs-row')) : parseInt(this.$el.attr('data-gs-max-row')) || 0,
721716
itemClass: 'grid-stack-item',
722717
placeholderClass: 'grid-stack-placeholder',
723718
placeholderText: '',
@@ -794,7 +789,7 @@
794789

795790
this._initStyles();
796791

797-
this.engine = new GridStackEngine(this.opts.row, this.opts.column, function(nodes, detachNode) {
792+
this.engine = new GridStackEngine(this.opts.column, function(nodes, detachNode) {
798793
detachNode = (detachNode === undefined ? true : detachNode);
799794
var maxHeight = 0;
800795
this.nodes.forEach(function(n) {
@@ -814,7 +809,7 @@
814809
}
815810
});
816811
self._updateStyles(maxHeight + 10);
817-
}, this.opts.float, this.opts.minRow, this.opts.maxRow);
812+
}, this.opts.float, this.opts.maxRow);
818813

819814
if (this.opts.auto) {
820815
var elements = [];
@@ -1162,12 +1157,15 @@
11621157

11631158
GridStack.prototype._updateContainerHeight = function() {
11641159
if (this.engine._batchMode) { return; }
1165-
var row = this.opts.minRow > this.engine.getRow() ? this.opts.minRow : this.engine.getRow();
1160+
var row = this.engine.getRow();
1161+
if (row < this.opts.minRow) {
1162+
row = this.opts.minRow;
1163+
}
11661164
// check for css min height. Each row is cellHeight + verticalMargin, until last one which has no margin below
11671165
var cssMinHeight = parseInt(this.$el.css('min-height'));
11681166
if (cssMinHeight > 0) {
11691167
var verticalMargin = this.opts.verticalMargin;
1170-
var minRow = Math.round((cssMinHeight + verticalMargin) / (this.cellHeight() + verticalMargin));
1168+
var minRow = Math.round((cssMinHeight + verticalMargin) / (this.cellHeight() + verticalMargin));
11711169
if (row < minRow) {
11721170
row = minRow;
11731171
}
@@ -1469,14 +1467,16 @@
14691467
// Tempting to initialize the passed in opt with default and valid values, but this break knockout demos
14701468
// as the actual value are filled in when _prepareElement() calls el.attr('data-gs-xyz) before adding the node.
14711469
// opt = this.engine._prepareNode(opt);
1472-
opt = opt || {};
14731470
} else {
14741471
// old legacy way of calling with items spelled out - call us back with single object instead (so we can properly initialized values)
14751472
return this.addWidget(el, {x: opt, y: y, width: width, height: height, autoPosition: autoPosition,
14761473
minWidth: minWidth, maxWidth: maxWidth, minHeight: minHeight, maxHeight: maxHeight, id: id});
14771474
}
14781475

14791476
el = $(el);
1477+
if (opt) { // see knockout above
1478+
this.engine._prepareNode(opt);
1479+
}
14801480
this._writeAttr(el, opt);
14811481
this.$el.append(el);
14821482
return this.makeWidget(el);
@@ -2030,6 +2030,13 @@
20302030
* notifications (see doc for supported events)
20312031
*/
20322032
GridStack.prototype.on = function(eventName, callback) {
2033+
// check for array of names being passed instead
2034+
if (eventName.indexOf(' ') !== -1) {
2035+
var names = eventName.split(' ');
2036+
names.forEach(function(name) { this.on(name, callback) }, this);
2037+
return;
2038+
}
2039+
20332040
if (eventName === 'change' || eventName === 'added' || eventName === 'removed') {
20342041
// native CustomEvent handlers - cash the generic handlers so we can remove
20352042
this._gsEventHandler = this._gsEventHandler || {};
@@ -2043,6 +2050,13 @@
20432050

20442051
/** unsubscribe from the 'on' event */
20452052
GridStack.prototype.off = function(eventName) {
2053+
// check for array of names being passed instead
2054+
if (eventName.indexOf(' ') !== -1) {
2055+
var names = eventName.split(' ');
2056+
names.forEach(function(name) { this.off(name, callback) }, this);
2057+
return;
2058+
}
2059+
20462060
if (eventName === 'change' || eventName === 'added' || eventName === 'removed') {
20472061
// remove native CustomEvent handlers
20482062
if (this._gsEventHandler && this._gsEventHandler[eventName]) {

0 commit comments

Comments
 (0)