diff --git a/.jscsrc b/.jscsrc
index 423b011..c4a58f0 100644
--- a/.jscsrc
+++ b/.jscsrc
@@ -1,6 +1,6 @@
{
- "preset": "google",
- "validateIndentation": "\t",
+ "preset": "node-style-guide",
+ "validateIndentation": 4,
"maximumLineLength": 120,
"jsDoc": {
"checkAnnotations": {
@@ -10,5 +10,10 @@
}
}
},
- "requireCamelCaseOrUpperCaseIdentifiers": true
+ "requireCamelCaseOrUpperCaseIdentifiers": true,
+ "validateLineBreaks": false,
+ "requireTrailingComma": false,
+ "disallowTrailingWhitespace": true,
+ "requireCapitalizedComments": false,
+ "excludeFiles": ["dist/*.js", "demo/*"]
}
diff --git a/Gruntfile.js b/Gruntfile.js
index 1ae9dd9..6404f1d 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -1,9 +1,12 @@
-module.exports = function (grunt) {
+module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-doctoc');
+ grunt.loadNpmTasks('grunt-contrib-jshint');
+ grunt.loadNpmTasks('grunt-jscs');
+ grunt.loadNpmTasks('grunt-contrib-watch');
grunt.initConfig({
sass: {
@@ -53,10 +56,46 @@ module.exports = function (grunt) {
removeAd: false
},
readme: {
- target: "./README.md"
- }
- }
+ options: {
+ target: './README.md'
+ }
+ },
+ doc: {
+ options: {
+ target: './doc/README.md'
+ }
+ },
+ },
+
+ jshint: {
+ all: ['src/*.js']
+ },
+
+ jscs: {
+ all: ['*.js', 'src/*.js', ],
+ },
+
+ watch: {
+ scripts: {
+ files: ['src/*.js'],
+ tasks: ['uglify', 'copy'],
+ options: {
+ },
+ },
+ styles: {
+ files: ['src/*.scss'],
+ tasks: ['sass', 'cssmin'],
+ options: {
+ },
+ },
+ docs: {
+ files: ['README.md', 'doc/README.md'],
+ tasks: ['doctoc'],
+ options: {
+ },
+ },
+ },
});
- grunt.registerTask('default', ['sass', 'cssmin', 'copy', 'uglify', 'doctoc']);
+ grunt.registerTask('default', ['sass', 'cssmin', 'jshint', 'jscs', 'copy', 'uglify', 'doctoc']);
};
diff --git a/README.md b/README.md
index d76fd7d..8083e72 100644
--- a/README.md
+++ b/README.md
@@ -20,46 +20,7 @@ Join gridstack.js on Slack: https://gridstackjs.troolee.com
- [Install](#install)
- [Basic usage](#basic-usage)
- [Migrating to v0.2.5](#migrating-to-v025)
- - [Options](#options)
- - [Grid attributes](#grid-attributes)
- - [Item attributes](#item-attributes)
- - [Events](#events)
- - [onchange(items)](#onchangeitems)
- - [ondragstart(event, ui)](#ondragstartevent-ui)
- - [ondragstop(event, ui)](#ondragstopevent-ui)
- - [onresizestart(event, ui)](#onresizestartevent-ui)
- - [onresizestop(event, ui)](#onresizestopevent-ui)
- - [disable(event)](#disableevent)
- - [enable(event)](#enableevent)
- - [API](#api)
- - [addWidget(el, x, y, width, height, autoPosition)](#addwidgetel-x-y-width-height-autoposition)
- - [batchUpdate()](#batchupdate)
- - [cellHeight()](#cellheight)
- - [cellHeight(val)](#cellheightval)
- - [cellWidth()](#cellwidth)
- - [commit()](#commit)
- - [destroy()](#destroy)
- - [disable()](#disable)
- - [enable()](#enable)
- - [getCellFromPixel(position)](#getcellfrompixelposition)
- - [isAreaEmpty(x, y, width, height)](#isareaemptyx-y-width-height)
- - [locked(el, val)](#lockedel-val)
- - [makeWidget(el)](#makewidgetel)
- - [maxHeight(el, val)](#maxheightel-val)
- - [minHeight(el, val)](#minheightel-val)
- - [maxWidth(el, val)](#maxwidthel-val)
- - [minWidth(el, val)](#minwidthel-val)
- - [movable(el, val)](#movableel-val)
- - [move(el, x, y)](#moveel-x-y)
- - [removeWidget(el, detachNode)](#removewidgetel-detachnode)
- - [removeAll()](#removeall)
- - [resize(el, width, height)](#resizeel-width-height)
- - [resizable(el, val)](#resizableel-val)
- - [setStatic(static_value)](#setstaticstatic_value)
- - [update(el, x, y, width, height)](#updateel-x-y-width-height)
- - [willItFit(x, y, width, height, autoPosition)](#willitfitx-y-width-height-autoposition)
- - [Utils](#utils)
- - [GridStackUI.Utils.sort(nodes[, dir[, width]])](#gridstackuiutilssortnodes-dir-width)
+ - [API Documentation](#api-documentation)
- [Touch devices support](#touch-devices-support)
- [Use with knockout.js](#use-with-knockoutjs)
- [Use with angular.js](#use-with-angularjs)
@@ -72,6 +33,7 @@ Join gridstack.js on Slack: https://gridstackjs.troolee.com
- [Override resizable/draggable options](#override-resizabledraggable-options)
- [IE8 support](#ie8-support)
- [Nested grids](#nested-grids)
+ - [Resizing active grid](#resizing-active-grid)
- [Changes](#changes)
- [v0.2.5-dev (Development version)](#v025-dev-development-version)
- [v0.2.4 (2016-02-15)](#v024-2016-02-15)
@@ -145,8 +107,8 @@ You can download files from `dist` directory as well.
diff --git a/demo/index.html b/demo/index.html
new file mode 100644
index 0000000..f3402cf
--- /dev/null
+++ b/demo/index.html
@@ -0,0 +1,18 @@
+
+
+
+
+ Demo
+
+
+
+
+
diff --git a/demo/knockout.html b/demo/knockout.html
index dd16b3e..327018d 100644
--- a/demo/knockout.html
+++ b/demo/knockout.html
@@ -11,7 +11,6 @@
Knockout.js demo
-
diff --git a/demo/knockout2.html b/demo/knockout2.html
index 96d2819..3fccde3 100644
--- a/demo/knockout2.html
+++ b/demo/knockout2.html
@@ -11,7 +11,6 @@
Knockout.js demo
-
diff --git a/demo/nested.html b/demo/nested.html
index 0fff23f..3bcdedd 100644
--- a/demo/nested.html
+++ b/demo/nested.html
@@ -11,7 +11,6 @@
Nested grids demo
-
diff --git a/demo/responsive.html b/demo/responsive.html
new file mode 100644
index 0000000..b9f1840
--- /dev/null
+++ b/demo/responsive.html
@@ -0,0 +1,122 @@
+
+
+
+
+
+
+
+
+ Responsive grid demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Responsive grid demo
+
+
+ Number of Columns:
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/rtl.html b/demo/rtl.html
new file mode 100644
index 0000000..3bd096f
--- /dev/null
+++ b/demo/rtl.html
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+ RTL demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
RTL Demo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/serialization.html b/demo/serialization.html
index b8484ea..0da49e6 100644
--- a/demo/serialization.html
+++ b/demo/serialization.html
@@ -11,7 +11,6 @@
Serialization demo
-
diff --git a/demo/two.html b/demo/two.html
index 7219455..a796bd3 100644
--- a/demo/two.html
+++ b/demo/two.html
@@ -11,7 +11,6 @@
Two grids demo
-
@@ -35,6 +34,14 @@
text-align: center;
background-color: #18bc9c;
}
+
+ #grid2 .grid-stack-item-content {
+ background-color: #9caabc;
+ }
+
+ .grid-stack-item-removing {
+ opacity: 0.5;
+ }
@@ -58,7 +65,8 @@
$(function () {
var options = {
width: 6,
- float: true
+ float: true,
+ removable: true
};
$('#grid1').gridstack(options);
$('#grid2').gridstack(options);
diff --git a/dist/gridstack.css b/dist/gridstack.css
index 70ec399..194b3a5 100644
--- a/dist/gridstack.css
+++ b/dist/gridstack.css
@@ -6,6 +6,14 @@
position: relative;
}
+.grid-stack.grid-stack-rtl {
+ direction: ltr;
+}
+
+.grid-stack.grid-stack-rtl > .grid-stack-item {
+ direction: rtl;
+}
+
.grid-stack .grid-stack-placeholder > .placeholder-content {
border: 1px dashed lightgray;
margin: 0;
@@ -64,29 +72,22 @@
.grid-stack > .grid-stack-item > .ui-resizable-se,
.grid-stack > .grid-stack-item > .ui-resizable-sw {
- text-align: right;
- color: gray;
- padding: 2px 3px 0 0;
- margin: 0;
- font: normal normal normal 10px/1 FontAwesome;
- font-size: inherit;
- text-rendering: auto;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-.grid-stack > .grid-stack-item > .ui-resizable-se::before,
-.grid-stack > .grid-stack-item > .ui-resizable-sw::before {
- content: "\f065";
+ background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDUxMS42MjYgNTExLjYyNyIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTExLjYyNiA1MTEuNjI3OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTMyOC45MDYsNDAxLjk5NGgtMzYuNTUzVjEwOS42MzZoMzYuNTUzYzQuOTQ4LDAsOS4yMzYtMS44MDksMTIuODQ3LTUuNDI2YzMuNjEzLTMuNjE1LDUuNDIxLTcuODk4LDUuNDIxLTEyLjg0NSAgIGMwLTQuOTQ5LTEuODAxLTkuMjMxLTUuNDI4LTEyLjg1MWwtNzMuMDg3LTczLjA5QzI2NS4wNDQsMS44MDksMjYwLjc2LDAsMjU1LjgxMywwYy00Ljk0OCwwLTkuMjI5LDEuODA5LTEyLjg0Nyw1LjQyNCAgIGwtNzMuMDg4LDczLjA5Yy0zLjYxOCwzLjYxOS01LjQyNCw3LjkwMi01LjQyNCwxMi44NTFjMCw0Ljk0NiwxLjgwNyw5LjIyOSw1LjQyNCwxMi44NDVjMy42MTksMy42MTcsNy45MDEsNS40MjYsMTIuODUsNS40MjYgICBoMzYuNTQ1djI5Mi4zNThoLTM2LjU0MmMtNC45NTIsMC05LjIzNSwxLjgwOC0xMi44NSw1LjQyMWMtMy42MTcsMy42MjEtNS40MjQsNy45MDUtNS40MjQsMTIuODU0ICAgYzAsNC45NDUsMS44MDcsOS4yMjcsNS40MjQsMTIuODQ3bDczLjA4OSw3My4wODhjMy42MTcsMy42MTcsNy44OTgsNS40MjQsMTIuODQ3LDUuNDI0YzQuOTUsMCw5LjIzNC0xLjgwNywxMi44NDktNS40MjQgICBsNzMuMDg3LTczLjA4OGMzLjYxMy0zLjYyLDUuNDIxLTcuOTAxLDUuNDIxLTEyLjg0N2MwLTQuOTQ4LTEuODA4LTkuMjMyLTUuNDIxLTEyLjg1NCAgIEMzMzguMTQyLDQwMy44MDIsMzMzLjg1Nyw0MDEuOTk0LDMyOC45MDYsNDAxLjk5NHoiIGZpbGw9IiM2NjY2NjYiLz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K);
+ background-repeat: no-repeat;
+ background-position: center;
+ -webkit-transform: rotate(45deg);
+ -moz-transform: rotate(45deg);
+ -ms-transform: rotate(45deg);
+ -o-transform: rotate(45deg);
+ transform: rotate(45deg);
}
.grid-stack > .grid-stack-item > .ui-resizable-se {
- display: inline-block;
- -webkit-transform: rotate(90deg);
- -moz-transform: rotate(90deg);
- -ms-transform: rotate(90deg);
- -o-transform: rotate(90deg);
- transform: rotate(90deg);
+ -webkit-transform: rotate(-45deg);
+ -moz-transform: rotate(-45deg);
+ -ms-transform: rotate(-45deg);
+ -o-transform: rotate(-45deg);
+ transform: rotate(-45deg);
}
.grid-stack > .grid-stack-item > .ui-resizable-nw {
@@ -153,6 +154,10 @@
bottom: 15px;
}
+.grid-stack > .grid-stack-item.ui-draggable-dragging > .ui-resizable-handle {
+ display: none !important;
+}
+
.grid-stack > .grid-stack-item[data-gs-width='1'] {
width: 8.3333333333%;
}
@@ -364,13 +369,6 @@
transition: left 0s, top 0s, height 0s, width 0s;
}
-/** Uncomment this to show bottom-left resize handle **/
-/*
-.grid-stack > .grid-stack-item > .ui-resizable-sw {
- display: inline-block;
- @include vendor(transform, rotate(180deg));
-}
-*/
@media (max-width: 768px) {
.grid-stack-item {
position: relative !important;
diff --git a/dist/gridstack.js b/dist/gridstack.js
index 73bdd28..4a94617 100644
--- a/dist/gridstack.js
+++ b/dist/gridstack.js
@@ -22,8 +22,8 @@
var obsolete = function(f, oldName, newName) {
var wrapper = function() {
- console.warn('gridstack.js: Function `' + oldName + '` is deprecated as of v0.2.5 and has been replaced with `' +
- newName + '`. It will be **completely** removed in v1.0.');
+ console.warn('gridstack.js: Function `' + oldName + '` is deprecated as of v0.2.5 and has been replaced ' +
+ 'with `' + newName + '`. It will be **completely** removed in v1.0.');
return f.apply(this, arguments);
};
wrapper.prototype = f.prototype;
@@ -50,7 +50,7 @@
createStylesheet: function(id) {
var style = document.createElement('style');
style.setAttribute('type', 'text/css');
- style.setAttribute('data-gs-id', id);
+ style.setAttribute('data-gs-style-id', id);
if (style.styleSheet) {
style.styleSheet.cssText = '';
} else {
@@ -61,7 +61,7 @@
},
removeStylesheet: function(id) {
- $('STYLE[data-gs-id=' + id + ']').remove();
+ $('STYLE[data-gs-style-id=' + id + ']').remove();
},
insertCSSRule: function(sheet, selector, rules, index) {
@@ -98,6 +98,20 @@
_isAddNodeIntercepted: function(n) {
return Utils.isIntercepted({x: this.x, y: this.y, width: this.node.width, height: this.node.height}, n);
+ },
+
+ parseHeight: function(val) {
+ var height = val;
+ var heightUnit = 'px';
+ if (height && _.isString(height)) {
+ var match = height.match(/^([0-9]*\.[0-9]+|[0-9]+)(px|em|rem|vh|vw)?$/);
+ if (!match) {
+ throw new Error('Invalid height');
+ }
+ heightUnit = match[2];
+ height = parseFloat(match[1]);
+ }
+ return {height: height, unit: heightUnit};
}
};
@@ -131,14 +145,19 @@
};
GridStackEngine.prototype.commit = function() {
- this._updateCounter = 0;
- if (this._updateCounter === 0) {
+ if (this._updateCounter !== 0) {
+ this._updateCounter = 0;
this.float = this._float;
this._packNodes();
this._notify();
}
};
+ // For Meteor support: https://github.com/troolee/gridstack.js/pull/272
+ GridStackEngine.prototype.getNodeDataByDOMEl = function(el) {
+ return _.find(this.nodes, function(n) { return el.get(0) === n.el.get(0); });
+ };
+
GridStackEngine.prototype._fixCollisions = function(node) {
var self = this;
this._sortNodes(-1);
@@ -269,6 +288,9 @@
};
GridStackEngine.prototype.cleanNodes = function() {
+ if (this._updateCounter) {
+ return;
+ }
_.each(this.nodes, function(n) {n._dirty = false; });
};
@@ -427,7 +449,7 @@
var GridStack = function(el, opts) {
var self = this;
- var oneColumnMode;
+ var oneColumnMode, isAutoCellHeight;
opts = opts || {};
@@ -509,11 +531,30 @@
'.grid-stack-item-content',
scroll: false,
appendTo: 'body'
- })
+ }),
+ disableDrag: opts.disableDrag || false,
+ disableResize: opts.disableResize || false,
+ rtl: 'auto',
+ removable: false,
+ removeTimeout: 2000
});
+
+ if (this.opts.rtl === 'auto') {
+ this.opts.rtl = this.container.css('direction') === 'rtl';
+ }
+
+ if (this.opts.rtl) {
+ this.container.addClass('grid-stack-rtl');
+ }
+
this.opts.isNested = isNested;
- this.cellHeight(this.opts.cellHeight, true);
+ isAutoCellHeight = this.opts.cellHeight === 'auto';
+ if (isAutoCellHeight) {
+ self.cellHeight(self.cellWidth(), true);
+ } else {
+ this.cellHeight(this.opts.cellHeight, true);
+ }
this.verticalMargin(this.opts.verticalMargin, true);
this.container.addClass(this.opts._class);
@@ -567,7 +608,15 @@
this._updateContainerHeight();
+ this._updateHeightsOnResize = _.throttle(function() {
+ self.cellHeight(self.cellWidth(), false);
+ }, 100);
+
this.onResizeHandler = function() {
+ if (isAutoCellHeight) {
+ self._updateHeightsOnResize();
+ }
+
if (self._isOneColumnMode()) {
if (oneColumnMode) {
return;
@@ -582,10 +631,10 @@
if (self.opts.staticGrid) {
return;
}
- if (!node.noMove) {
+ if (node.noMove || self.opts.disableDrag) {
node.el.draggable('disable');
}
- if (!node.noResize) {
+ if (node.noResize || self.opts.disableResize) {
node.el.resizable('disable');
}
});
@@ -601,10 +650,10 @@
}
_.each(self.grid.nodes, function(node) {
- if (!node.noMove) {
+ if (!node.noMove && !self.opts.disableDrag) {
node.el.draggable('enable');
}
- if (!node.noResize) {
+ if (!node.noResize && !self.opts.disableResize) {
node.el.resizable('enable');
}
});
@@ -631,21 +680,18 @@
};
GridStack.prototype._initStyles = function() {
- if (!this.opts.cellHeight) { //that will be handled by CSS
- return ;
- }
if (this._stylesId) {
- $('[data-gs-id="' + this._stylesId + '"]').remove();
+ Utils.removeStylesheet(this._stylesId);
}
this._stylesId = 'gridstack-style-' + (Math.random() * 100000).toFixed();
this._styles = Utils.createStylesheet(this._stylesId);
- if (this._styles != null) {
+ if (this._styles !== null) {
this._styles._max = 0;
}
};
GridStack.prototype._updateStyles = function(maxHeight) {
- if (this._styles === null) {
+ if (this._styles === null || typeof this._styles === 'undefined') {
return;
}
@@ -658,7 +704,7 @@
this._initStyles();
this._updateContainerHeight();
}
- if (!this.opts.cellHeight) { //the rest will be handled by CSS
+ if (!this.opts.cellHeight) { // The rest will be handled by CSS
return ;
}
if (this._styles._max !== 0 && maxHeight <= this._styles._max) {
@@ -667,12 +713,14 @@
if (!this.opts.verticalMargin || this.opts.cellHeightUnit === this.opts.verticalMarginUnit) {
getHeight = function(nbRows, nbMargins) {
- return (self.opts.cellHeight * nbRows + self.opts.verticalMargin * nbMargins) + self.opts.cellHeightUnit;
+ return (self.opts.cellHeight * nbRows + self.opts.verticalMargin * nbMargins) +
+ self.opts.cellHeightUnit;
};
} else {
getHeight = function(nbRows, nbMargins) {
if (!nbRows || !nbMargins) {
- return (self.opts.cellHeight * nbRows + self.opts.verticalMargin * nbMargins) + self.opts.cellHeightUnit;
+ return (self.opts.cellHeight * nbRows + self.opts.verticalMargin * nbMargins) +
+ self.opts.cellHeightUnit;
}
return 'calc(' + ((self.opts.cellHeight * nbRows) + self.opts.cellHeightUnit) + ' + ' +
((self.opts.verticalMargin * nbMargins) + self.opts.verticalMarginUnit) + ')';
@@ -753,27 +801,80 @@
noResize: Utils.toBool(el.attr('data-gs-no-resize')),
noMove: Utils.toBool(el.attr('data-gs-no-move')),
locked: Utils.toBool(el.attr('data-gs-locked')),
- el: el
+ el: el,
+ id: el.attr('data-gs-id')
});
el.data('_gridstack_node', node);
- if (self.opts.staticGrid) {
- return;
- }
-
var cellWidth;
var cellHeight;
+ var removeTimeout;
+
+ var setupRemovingTimeout = function() {
+ if (removeTimeout || !self.opts.removable) {
+ return;
+ }
+ removeTimeout = setTimeout(function() {
+ el.addClass('grid-stack-item-removing');
+ node._isAboutToRemove = true;
+ }, self.opts.removeTimeout);
+ };
+ var clearRemovingTimeout = function() {
+ if (!removeTimeout) {
+ return;
+ }
+ clearTimeout(removeTimeout);
+ removeTimeout = null;
+ el.removeClass('grid-stack-item-removing');
+ node._isAboutToRemove = false;
+ };
var dragOrResize = function(event, ui) {
var x = Math.round(ui.position.left / cellWidth);
var y = Math.floor((ui.position.top + cellHeight / 2) / cellHeight);
var width;
var height;
+
if (event.type != 'drag') {
width = Math.round(ui.size.width / cellWidth);
height = Math.round(ui.size.height / cellHeight);
}
+ if (event.type == 'drag') {
+ if (x < 0 || x >= self.grid.width || y < 0) {
+ setupRemovingTimeout();
+
+ x = node._beforeDragX;
+ y = node._beforeDragY;
+
+ self.placeholder.detach();
+ self.placeholder.hide();
+ self.grid.removeNode(node);
+ self._updateContainerHeight();
+
+ node._temporaryRemoved = true;
+ } else {
+ clearRemovingTimeout();
+
+ if (node._temporaryRemoved) {
+ self.grid.addNode(node);
+ self.placeholder
+ .attr('data-gs-x', x)
+ .attr('data-gs-y', y)
+ .attr('data-gs-width', width)
+ .attr('data-gs-height', height)
+ .show();
+ self.container.append(self.placeholder);
+ node.el = self.placeholder;
+ node._temporaryRemoved = false;
+ }
+ }
+ } else if (event.type == 'resize') {
+ if (x < 0) {
+ return;
+ }
+ }
+
if (!self.grid.canMoveNode(node, x, y, width, height)) {
return;
}
@@ -796,6 +897,8 @@
.attr('data-gs-height', o.attr('data-gs-height'))
.show();
node.el = self.placeholder;
+ node._beforeDragX = node.x;
+ node._beforeDragY = node.y;
el.resizable('option', 'minWidth', cellWidth * (node.minWidth || 1));
el.resizable('option', 'minHeight', strictCellHeight * (node.minHeight || 1));
@@ -806,18 +909,39 @@
};
var onEndMoving = function(event, ui) {
+ var forceNotify = false;
self.placeholder.detach();
var o = $(this);
node.el = o;
self.placeholder.hide();
- o
- .attr('data-gs-x', node.x)
- .attr('data-gs-y', node.y)
- .attr('data-gs-width', node.width)
- .attr('data-gs-height', node.height)
- .removeAttr('style');
+
+ if (node._isAboutToRemove) {
+ forceNotify = true;
+ el.removeData('_gridstack_node');
+ el.remove();
+ } else {
+ clearRemovingTimeout();
+ if (!node._temporaryRemoved) {
+ o
+ .attr('data-gs-x', node.x)
+ .attr('data-gs-y', node.y)
+ .attr('data-gs-width', node.width)
+ .attr('data-gs-height', node.height)
+ .removeAttr('style');
+ } else {
+ o
+ .attr('data-gs-x', node._beforeDragX)
+ .attr('data-gs-y', node._beforeDragY)
+ .attr('data-gs-width', node.width)
+ .attr('data-gs-height', node.height)
+ .removeAttr('style');
+ node.x = node._beforeDragX;
+ node.y = node._beforeDragY;
+ self.grid.addNode(node);
+ }
+ }
self._updateContainerHeight();
- self._triggerChangeEvent();
+ self._triggerChangeEvent(forceNotify);
self.grid.endUpdate();
@@ -843,11 +967,11 @@
resize: dragOrResize
}));
- if (node.noMove || this._isOneColumnMode()) {
+ if (node.noMove || this._isOneColumnMode() || this.opts.staticGrid || this.opts.disableDrag) {
el.draggable('disable');
}
- if (node.noResize || this._isOneColumnMode()) {
+ if (node.noResize || this._isOneColumnMode() || this.opts.staticGrid || this.opts.disableResize) {
el.resizable('disable');
}
@@ -862,13 +986,19 @@
}
};
- GridStack.prototype.addWidget = function(el, x, y, width, height, autoPosition) {
+ GridStack.prototype.addWidget = function(el, x, y, width, height, autoPosition, minWidth, maxWidth,
+ minHeight, maxHeight, id) {
el = $(el);
if (typeof x != 'undefined') { el.attr('data-gs-x', x); }
if (typeof y != 'undefined') { el.attr('data-gs-y', y); }
if (typeof width != 'undefined') { el.attr('data-gs-width', width); }
if (typeof height != 'undefined') { el.attr('data-gs-height', height); }
if (typeof autoPosition != 'undefined') { el.attr('data-gs-auto-position', autoPosition ? 'yes' : null); }
+ if (typeof minWidth != 'undefined') { el.attr('data-gs-min-width', minWidth); }
+ if (typeof maxWidth != 'undefined') { el.attr('data-gs-max-width', maxWidth); }
+ if (typeof minHeight != 'undefined') { el.attr('data-gs-min-height', minHeight); }
+ if (typeof maxHeight != 'undefined') { el.attr('data-gs-max-height', maxHeight); }
+ if (typeof id != 'undefined') { el.attr('data-gs-id', id); }
this.container.append(el);
this._prepareElement(el);
this._updateContainerHeight();
@@ -895,6 +1025,12 @@
detachNode = typeof detachNode === 'undefined' ? true : detachNode;
el = $(el);
var node = el.data('_gridstack_node');
+
+ // For Meteor support: https://github.com/troolee/gridstack.js/pull/272
+ if (!node) {
+ node = this.grid.getNodeDataByDOMEl(el);
+ }
+
this.grid.removeNode(node);
el.removeData('_gridstack_node');
this._updateContainerHeight();
@@ -912,10 +1048,14 @@
this._updateContainerHeight();
};
- GridStack.prototype.destroy = function() {
+ GridStack.prototype.destroy = function(detachGrid) {
$(window).off('resize', this.onResizeHandler);
this.disable();
- this.container.remove();
+ if (typeof detachGrid != 'undefined' && !detachGrid) {
+ this.removeAll(true);
+ } else {
+ this.container.remove();
+ }
Utils.removeStylesheet(this._stylesId);
if (this.grid) {
this.grid = null;
@@ -964,6 +1104,20 @@
return this;
};
+ GridStack.prototype.enableMove = function(doEnable, includeNewWidgets) {
+ this.movable(this.container.children('.' + this.opts.itemClass), doEnable);
+ if (includeNewWidgets) {
+ this.opts.disableDrag = !doEnable;
+ }
+ };
+
+ GridStack.prototype.enableResize = function(doEnable, includeNewWidgets) {
+ this.resizable(this.container.children('.' + this.opts.itemClass), doEnable);
+ if (includeNewWidgets) {
+ this.opts.disableResize = !doEnable;
+ }
+ };
+
GridStack.prototype.disable = function() {
this.movable(this.container.children('.' + this.opts.itemClass), false);
this.resizable(this.container.children('.' + this.opts.itemClass), false);
@@ -996,7 +1150,7 @@
el.each(function(index, el) {
el = $(el);
var node = el.data('_gridstack_node');
- if (typeof node == 'undefined' || node == null) {
+ if (typeof node === 'undefined' || node === null) {
return;
}
@@ -1013,7 +1167,7 @@
el.each(function(index, el) {
el = $(el);
var node = el.data('_gridstack_node');
- if (typeof node == 'undefined' || node == null) {
+ if (typeof node === 'undefined' || node === null) {
return;
}
@@ -1030,7 +1184,7 @@
el.each(function(index, el) {
el = $(el);
var node = el.data('_gridstack_node');
- if (typeof node == 'undefined' || node == null) {
+ if (typeof node === 'undefined' || node === null) {
return;
}
@@ -1047,7 +1201,7 @@
el.each(function(index, el) {
el = $(el);
var node = el.data('_gridstack_node');
- if (typeof node == 'undefined' || node == null) {
+ if (typeof node === 'undefined' || node === null) {
return;
}
@@ -1108,26 +1262,12 @@
});
};
- function parseHeight(val) {
- var height = val;
- var heightUnit = 'px';
- if (height && _.isString(height)) {
- var match = height.match(/^([0-9]+)(px|em|rem)?$/);
- if (!match) {
- throw new Error('Invalid height');
- }
- heightUnit = match[2];
- height = parseInt(match[1]);
- }
- return {height: height, unit: heightUnit};
- }
-
GridStack.prototype.verticalMargin = function(val, noUpdate) {
if (typeof val == 'undefined') {
return this.opts.verticalMargin;
}
- var heightData = parseHeight(val);
+ var heightData = Utils.parseHeight(val);
if (this.opts.verticalMarginUnit === heightData.unit && this.opts.height === heightData.height) {
return ;
@@ -1144,13 +1284,11 @@
if (typeof val == 'undefined') {
if (this.opts.cellHeight) {
return this.opts.cellHeight;
- } else {
- var o = this.container.children('.' + this.opts.itemClass).first();
- return Math.ceil(o.outerHeight() / o.attr('data-gs-height'));
}
-
+ var o = this.container.children('.' + this.opts.itemClass).first();
+ return Math.ceil(o.outerHeight() / o.attr('data-gs-height'));
}
- var heightData = parseHeight(val);
+ var heightData = Utils.parseHeight(val);
if (this.opts.cellHeightUnit === heightData.heightUnit && this.opts.height === heightData.height) {
return ;
@@ -1169,8 +1307,9 @@
return Math.ceil(o.outerWidth() / o.attr('data-gs-width'));
};
- GridStack.prototype.getCellFromPixel = function(position) {
- var containerPos = this.container.position();
+ GridStack.prototype.getCellFromPixel = function(position, useOffset) {
+ var containerPos = (typeof useOffset != 'undefined' && useOffset) ?
+ this.container.offset() : this.container.position();
var relativeLeft = position.left - containerPos.left;
var relativeTop = position.top - containerPos.top;
@@ -1195,6 +1334,8 @@
GridStack.prototype.setStatic = function(staticValue) {
this.opts.staticGrid = (staticValue === true);
+ this.enableMove(!staticValue);
+ this.enableResize(!staticValue);
this._setStaticClass();
};
@@ -1208,6 +1349,25 @@
}
};
+ GridStack.prototype._updateNodeWidths = function(oldWidth, newWidth) {
+ this.grid._sortNodes();
+ this.grid.batchUpdate();
+ var node = {};
+ for (var i = 0; i < this.grid.nodes.length; i++) {
+ node = this.grid.nodes[i];
+ this.update(node.el, Math.round(node.x * newWidth / oldWidth), undefined,
+ Math.round(node.width * newWidth / oldWidth), undefined);
+ }
+ this.grid.commit();
+ };
+
+ GridStack.prototype.setGridWidth = function(gridWidth) {
+ this.container.removeClass('grid-stack-' + this.opts.width);
+ this._updateNodeWidths(this.opts.width, gridWidth);
+ this.opts.width = gridWidth;
+ this.container.addClass('grid-stack-' + gridWidth);
+ };
+
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
GridStackEngine.prototype.batch_update = obsolete(GridStackEngine.prototype.batchUpdate);
GridStackEngine.prototype._fix_collisions = obsolete(GridStackEngine.prototype._fixCollisions,
diff --git a/dist/gridstack.min.css b/dist/gridstack.min.css
index 9a0775e..810de47 100644
--- a/dist/gridstack.min.css
+++ b/dist/gridstack.min.css
@@ -1 +1 @@
-:root .grid-stack-item>.ui-resizable-handle{filter:none}.grid-stack{position:relative}.grid-stack .grid-stack-placeholder>.placeholder-content{border:1px dashed #d3d3d3;margin:0;position:absolute;top:0;left:10px;right:10px;bottom:0;width:auto;z-index:0!important;text-align:center}.grid-stack>.grid-stack-item{min-width:8.3333333333%;position:absolute;padding:0}.grid-stack>.grid-stack-item>.grid-stack-item-content{margin:0;position:absolute;top:0;left:10px;right:10px;bottom:0;width:auto;z-index:0!important;overflow-x:hidden;overflow-y:auto}.grid-stack>.grid-stack-item>.ui-resizable-handle{position:absolute;font-size:.1px;display:block;-ms-touch-action:none;touch-action:none}.grid-stack>.grid-stack-item.ui-resizable-autohide>.ui-resizable-handle,.grid-stack>.grid-stack-item.ui-resizable-disabled>.ui-resizable-handle{display:none}.grid-stack>.grid-stack-item.ui-draggable-dragging,.grid-stack>.grid-stack-item.ui-resizable-resizing{z-index:100}.grid-stack>.grid-stack-item.ui-draggable-dragging>.grid-stack-item-content,.grid-stack>.grid-stack-item.ui-resizable-resizing>.grid-stack-item-content{box-shadow:1px 4px 6px rgba(0,0,0,.2);opacity:.8}.grid-stack>.grid-stack-item>.ui-resizable-se,.grid-stack>.grid-stack-item>.ui-resizable-sw{text-align:right;color:gray;padding:2px 3px 0 0;margin:0;font:normal normal normal 10px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.grid-stack>.grid-stack-item>.ui-resizable-se::before,.grid-stack>.grid-stack-item>.ui-resizable-sw::before{content:"\f065"}.grid-stack>.grid-stack-item>.ui-resizable-nw{cursor:nw-resize;width:20px;height:20px;left:10px;top:0}.grid-stack>.grid-stack-item>.ui-resizable-n{cursor:n-resize;height:10px;top:0;left:25px;right:25px}.grid-stack>.grid-stack-item>.ui-resizable-ne{cursor:ne-resize;width:20px;height:20px;right:10px;top:0}.grid-stack>.grid-stack-item>.ui-resizable-e{cursor:e-resize;width:10px;right:10px;top:15px;bottom:15px}.grid-stack>.grid-stack-item>.ui-resizable-se{display:inline-block;-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg);cursor:se-resize;width:20px;height:20px;right:10px;bottom:0}.grid-stack>.grid-stack-item>.ui-resizable-s{cursor:s-resize;height:10px;left:25px;bottom:0;right:25px}.grid-stack>.grid-stack-item>.ui-resizable-sw{cursor:sw-resize;width:20px;height:20px;left:10px;bottom:0}.grid-stack>.grid-stack-item>.ui-resizable-w{cursor:w-resize;width:10px;left:10px;top:15px;bottom:15px}.grid-stack>.grid-stack-item[data-gs-width='1']{width:8.3333333333%}.grid-stack>.grid-stack-item[data-gs-x='1']{left:8.3333333333%}.grid-stack>.grid-stack-item[data-gs-min-width='1']{min-width:8.3333333333%}.grid-stack>.grid-stack-item[data-gs-max-width='1']{max-width:8.3333333333%}.grid-stack>.grid-stack-item[data-gs-width='2']{width:16.6666666667%}.grid-stack>.grid-stack-item[data-gs-x='2']{left:16.6666666667%}.grid-stack>.grid-stack-item[data-gs-min-width='2']{min-width:16.6666666667%}.grid-stack>.grid-stack-item[data-gs-max-width='2']{max-width:16.6666666667%}.grid-stack>.grid-stack-item[data-gs-width='3']{width:25%}.grid-stack>.grid-stack-item[data-gs-x='3']{left:25%}.grid-stack>.grid-stack-item[data-gs-min-width='3']{min-width:25%}.grid-stack>.grid-stack-item[data-gs-max-width='3']{max-width:25%}.grid-stack>.grid-stack-item[data-gs-width='4']{width:33.3333333333%}.grid-stack>.grid-stack-item[data-gs-x='4']{left:33.3333333333%}.grid-stack>.grid-stack-item[data-gs-min-width='4']{min-width:33.3333333333%}.grid-stack>.grid-stack-item[data-gs-max-width='4']{max-width:33.3333333333%}.grid-stack>.grid-stack-item[data-gs-width='5']{width:41.6666666667%}.grid-stack>.grid-stack-item[data-gs-x='5']{left:41.6666666667%}.grid-stack>.grid-stack-item[data-gs-min-width='5']{min-width:41.6666666667%}.grid-stack>.grid-stack-item[data-gs-max-width='5']{max-width:41.6666666667%}.grid-stack>.grid-stack-item[data-gs-width='6']{width:50%}.grid-stack>.grid-stack-item[data-gs-x='6']{left:50%}.grid-stack>.grid-stack-item[data-gs-min-width='6']{min-width:50%}.grid-stack>.grid-stack-item[data-gs-max-width='6']{max-width:50%}.grid-stack>.grid-stack-item[data-gs-width='7']{width:58.3333333333%}.grid-stack>.grid-stack-item[data-gs-x='7']{left:58.3333333333%}.grid-stack>.grid-stack-item[data-gs-min-width='7']{min-width:58.3333333333%}.grid-stack>.grid-stack-item[data-gs-max-width='7']{max-width:58.3333333333%}.grid-stack>.grid-stack-item[data-gs-width='8']{width:66.6666666667%}.grid-stack>.grid-stack-item[data-gs-x='8']{left:66.6666666667%}.grid-stack>.grid-stack-item[data-gs-min-width='8']{min-width:66.6666666667%}.grid-stack>.grid-stack-item[data-gs-max-width='8']{max-width:66.6666666667%}.grid-stack>.grid-stack-item[data-gs-width='9']{width:75%}.grid-stack>.grid-stack-item[data-gs-x='9']{left:75%}.grid-stack>.grid-stack-item[data-gs-min-width='9']{min-width:75%}.grid-stack>.grid-stack-item[data-gs-max-width='9']{max-width:75%}.grid-stack>.grid-stack-item[data-gs-width='10']{width:83.3333333333%}.grid-stack>.grid-stack-item[data-gs-x='10']{left:83.3333333333%}.grid-stack>.grid-stack-item[data-gs-min-width='10']{min-width:83.3333333333%}.grid-stack>.grid-stack-item[data-gs-max-width='10']{max-width:83.3333333333%}.grid-stack>.grid-stack-item[data-gs-width='11']{width:91.6666666667%}.grid-stack>.grid-stack-item[data-gs-x='11']{left:91.6666666667%}.grid-stack>.grid-stack-item[data-gs-min-width='11']{min-width:91.6666666667%}.grid-stack>.grid-stack-item[data-gs-max-width='11']{max-width:91.6666666667%}.grid-stack>.grid-stack-item[data-gs-width='12']{width:100%}.grid-stack>.grid-stack-item[data-gs-x='12']{left:100%}.grid-stack>.grid-stack-item[data-gs-min-width='12']{min-width:100%}.grid-stack>.grid-stack-item[data-gs-max-width='12']{max-width:100%}.grid-stack.grid-stack-animate,.grid-stack.grid-stack-animate .grid-stack-item{-webkit-transition:left .3s,top .3s,height .3s,width .3s;-moz-transition:left .3s,top .3s,height .3s,width .3s;-ms-transition:left .3s,top .3s,height .3s,width .3s;-o-transition:left .3s,top .3s,height .3s,width .3s;transition:left .3s,top .3s,height .3s,width .3s}.grid-stack.grid-stack-animate .grid-stack-item.grid-stack-placeholder,.grid-stack.grid-stack-animate .grid-stack-item.ui-draggable-dragging,.grid-stack.grid-stack-animate .grid-stack-item.ui-resizable-resizing{-webkit-transition:left 0s,top 0s,height 0s,width 0s;-moz-transition:left 0s,top 0s,height 0s,width 0s;-ms-transition:left 0s,top 0s,height 0s,width 0s;-o-transition:left 0s,top 0s,height 0s,width 0s;transition:left 0s,top 0s,height 0s,width 0s}@media (max-width:768px){.grid-stack-item{position:relative!important;width:auto!important;left:0!important;top:auto!important;margin-bottom:20px}.grid-stack-item .ui-resizable-handle{display:none}.grid-stack{height:auto!important}}
\ No newline at end of file
+:root .grid-stack-item>.ui-resizable-handle{filter:none}.grid-stack{position:relative}.grid-stack.grid-stack-rtl{direction:ltr}.grid-stack.grid-stack-rtl>.grid-stack-item{direction:rtl}.grid-stack .grid-stack-placeholder>.placeholder-content{border:1px dashed #d3d3d3;margin:0;position:absolute;top:0;left:10px;right:10px;bottom:0;width:auto;z-index:0!important;text-align:center}.grid-stack>.grid-stack-item{min-width:8.3333333333%;position:absolute;padding:0}.grid-stack>.grid-stack-item>.grid-stack-item-content{margin:0;position:absolute;top:0;left:10px;right:10px;bottom:0;width:auto;z-index:0!important;overflow-x:hidden;overflow-y:auto}.grid-stack>.grid-stack-item>.ui-resizable-handle{position:absolute;font-size:.1px;display:block;-ms-touch-action:none;touch-action:none}.grid-stack>.grid-stack-item.ui-resizable-autohide>.ui-resizable-handle,.grid-stack>.grid-stack-item.ui-resizable-disabled>.ui-resizable-handle{display:none}.grid-stack>.grid-stack-item.ui-draggable-dragging,.grid-stack>.grid-stack-item.ui-resizable-resizing{z-index:100}.grid-stack>.grid-stack-item.ui-draggable-dragging>.grid-stack-item-content,.grid-stack>.grid-stack-item.ui-resizable-resizing>.grid-stack-item-content{box-shadow:1px 4px 6px rgba(0,0,0,.2);opacity:.8}.grid-stack>.grid-stack-item>.ui-resizable-se,.grid-stack>.grid-stack-item>.ui-resizable-sw{background-image:url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDUxMS42MjYgNTExLjYyNyIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTExLjYyNiA1MTEuNjI3OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTMyOC45MDYsNDAxLjk5NGgtMzYuNTUzVjEwOS42MzZoMzYuNTUzYzQuOTQ4LDAsOS4yMzYtMS44MDksMTIuODQ3LTUuNDI2YzMuNjEzLTMuNjE1LDUuNDIxLTcuODk4LDUuNDIxLTEyLjg0NSAgIGMwLTQuOTQ5LTEuODAxLTkuMjMxLTUuNDI4LTEyLjg1MWwtNzMuMDg3LTczLjA5QzI2NS4wNDQsMS44MDksMjYwLjc2LDAsMjU1LjgxMywwYy00Ljk0OCwwLTkuMjI5LDEuODA5LTEyLjg0Nyw1LjQyNCAgIGwtNzMuMDg4LDczLjA5Yy0zLjYxOCwzLjYxOS01LjQyNCw3LjkwMi01LjQyNCwxMi44NTFjMCw0Ljk0NiwxLjgwNyw5LjIyOSw1LjQyNCwxMi44NDVjMy42MTksMy42MTcsNy45MDEsNS40MjYsMTIuODUsNS40MjYgICBoMzYuNTQ1djI5Mi4zNThoLTM2LjU0MmMtNC45NTIsMC05LjIzNSwxLjgwOC0xMi44NSw1LjQyMWMtMy42MTcsMy42MjEtNS40MjQsNy45MDUtNS40MjQsMTIuODU0ICAgYzAsNC45NDUsMS44MDcsOS4yMjcsNS40MjQsMTIuODQ3bDczLjA4OSw3My4wODhjMy42MTcsMy42MTcsNy44OTgsNS40MjQsMTIuODQ3LDUuNDI0YzQuOTUsMCw5LjIzNC0xLjgwNywxMi44NDktNS40MjQgICBsNzMuMDg3LTczLjA4OGMzLjYxMy0zLjYyLDUuNDIxLTcuOTAxLDUuNDIxLTEyLjg0N2MwLTQuOTQ4LTEuODA4LTkuMjMyLTUuNDIxLTEyLjg1NCAgIEMzMzguMTQyLDQwMy44MDIsMzMzLjg1Nyw0MDEuOTk0LDMyOC45MDYsNDAxLjk5NHoiIGZpbGw9IiM2NjY2NjYiLz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K);background-repeat:no-repeat;background-position:center;-webkit-transform:rotate(45deg);-moz-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.grid-stack>.grid-stack-item>.ui-resizable-nw{cursor:nw-resize;width:20px;height:20px;left:10px;top:0}.grid-stack>.grid-stack-item>.ui-resizable-n{cursor:n-resize;height:10px;top:0;left:25px;right:25px}.grid-stack>.grid-stack-item>.ui-resizable-ne{cursor:ne-resize;width:20px;height:20px;right:10px;top:0}.grid-stack>.grid-stack-item>.ui-resizable-e{cursor:e-resize;width:10px;right:10px;top:15px;bottom:15px}.grid-stack>.grid-stack-item>.ui-resizable-se{-webkit-transform:rotate(-45deg);-moz-transform:rotate(-45deg);-ms-transform:rotate(-45deg);-o-transform:rotate(-45deg);transform:rotate(-45deg);cursor:se-resize;width:20px;height:20px;right:10px;bottom:0}.grid-stack>.grid-stack-item>.ui-resizable-s{cursor:s-resize;height:10px;left:25px;bottom:0;right:25px}.grid-stack>.grid-stack-item>.ui-resizable-sw{cursor:sw-resize;width:20px;height:20px;left:10px;bottom:0}.grid-stack>.grid-stack-item>.ui-resizable-w{cursor:w-resize;width:10px;left:10px;top:15px;bottom:15px}.grid-stack>.grid-stack-item.ui-draggable-dragging>.ui-resizable-handle{display:none!important}.grid-stack>.grid-stack-item[data-gs-width='1']{width:8.3333333333%}.grid-stack>.grid-stack-item[data-gs-x='1']{left:8.3333333333%}.grid-stack>.grid-stack-item[data-gs-min-width='1']{min-width:8.3333333333%}.grid-stack>.grid-stack-item[data-gs-max-width='1']{max-width:8.3333333333%}.grid-stack>.grid-stack-item[data-gs-width='2']{width:16.6666666667%}.grid-stack>.grid-stack-item[data-gs-x='2']{left:16.6666666667%}.grid-stack>.grid-stack-item[data-gs-min-width='2']{min-width:16.6666666667%}.grid-stack>.grid-stack-item[data-gs-max-width='2']{max-width:16.6666666667%}.grid-stack>.grid-stack-item[data-gs-width='3']{width:25%}.grid-stack>.grid-stack-item[data-gs-x='3']{left:25%}.grid-stack>.grid-stack-item[data-gs-min-width='3']{min-width:25%}.grid-stack>.grid-stack-item[data-gs-max-width='3']{max-width:25%}.grid-stack>.grid-stack-item[data-gs-width='4']{width:33.3333333333%}.grid-stack>.grid-stack-item[data-gs-x='4']{left:33.3333333333%}.grid-stack>.grid-stack-item[data-gs-min-width='4']{min-width:33.3333333333%}.grid-stack>.grid-stack-item[data-gs-max-width='4']{max-width:33.3333333333%}.grid-stack>.grid-stack-item[data-gs-width='5']{width:41.6666666667%}.grid-stack>.grid-stack-item[data-gs-x='5']{left:41.6666666667%}.grid-stack>.grid-stack-item[data-gs-min-width='5']{min-width:41.6666666667%}.grid-stack>.grid-stack-item[data-gs-max-width='5']{max-width:41.6666666667%}.grid-stack>.grid-stack-item[data-gs-width='6']{width:50%}.grid-stack>.grid-stack-item[data-gs-x='6']{left:50%}.grid-stack>.grid-stack-item[data-gs-min-width='6']{min-width:50%}.grid-stack>.grid-stack-item[data-gs-max-width='6']{max-width:50%}.grid-stack>.grid-stack-item[data-gs-width='7']{width:58.3333333333%}.grid-stack>.grid-stack-item[data-gs-x='7']{left:58.3333333333%}.grid-stack>.grid-stack-item[data-gs-min-width='7']{min-width:58.3333333333%}.grid-stack>.grid-stack-item[data-gs-max-width='7']{max-width:58.3333333333%}.grid-stack>.grid-stack-item[data-gs-width='8']{width:66.6666666667%}.grid-stack>.grid-stack-item[data-gs-x='8']{left:66.6666666667%}.grid-stack>.grid-stack-item[data-gs-min-width='8']{min-width:66.6666666667%}.grid-stack>.grid-stack-item[data-gs-max-width='8']{max-width:66.6666666667%}.grid-stack>.grid-stack-item[data-gs-width='9']{width:75%}.grid-stack>.grid-stack-item[data-gs-x='9']{left:75%}.grid-stack>.grid-stack-item[data-gs-min-width='9']{min-width:75%}.grid-stack>.grid-stack-item[data-gs-max-width='9']{max-width:75%}.grid-stack>.grid-stack-item[data-gs-width='10']{width:83.3333333333%}.grid-stack>.grid-stack-item[data-gs-x='10']{left:83.3333333333%}.grid-stack>.grid-stack-item[data-gs-min-width='10']{min-width:83.3333333333%}.grid-stack>.grid-stack-item[data-gs-max-width='10']{max-width:83.3333333333%}.grid-stack>.grid-stack-item[data-gs-width='11']{width:91.6666666667%}.grid-stack>.grid-stack-item[data-gs-x='11']{left:91.6666666667%}.grid-stack>.grid-stack-item[data-gs-min-width='11']{min-width:91.6666666667%}.grid-stack>.grid-stack-item[data-gs-max-width='11']{max-width:91.6666666667%}.grid-stack>.grid-stack-item[data-gs-width='12']{width:100%}.grid-stack>.grid-stack-item[data-gs-x='12']{left:100%}.grid-stack>.grid-stack-item[data-gs-min-width='12']{min-width:100%}.grid-stack>.grid-stack-item[data-gs-max-width='12']{max-width:100%}.grid-stack.grid-stack-animate,.grid-stack.grid-stack-animate .grid-stack-item{-webkit-transition:left .3s,top .3s,height .3s,width .3s;-moz-transition:left .3s,top .3s,height .3s,width .3s;-ms-transition:left .3s,top .3s,height .3s,width .3s;-o-transition:left .3s,top .3s,height .3s,width .3s;transition:left .3s,top .3s,height .3s,width .3s}.grid-stack.grid-stack-animate .grid-stack-item.grid-stack-placeholder,.grid-stack.grid-stack-animate .grid-stack-item.ui-draggable-dragging,.grid-stack.grid-stack-animate .grid-stack-item.ui-resizable-resizing{-webkit-transition:left 0s,top 0s,height 0s,width 0s;-moz-transition:left 0s,top 0s,height 0s,width 0s;-ms-transition:left 0s,top 0s,height 0s,width 0s;-o-transition:left 0s,top 0s,height 0s,width 0s;transition:left 0s,top 0s,height 0s,width 0s}@media (max-width:768px){.grid-stack-item{position:relative!important;width:auto!important;left:0!important;top:auto!important;margin-bottom:20px}.grid-stack-item .ui-resizable-handle{display:none}.grid-stack{height:auto!important}}
\ No newline at end of file
diff --git a/dist/gridstack.min.js b/dist/gridstack.min.js
index 7c982de..b77af1d 100644
--- a/dist/gridstack.min.js
+++ b/dist/gridstack.min.js
@@ -5,12 +5,16 @@
* gridstack.js may be freely distributed under the MIT license.
* @preserve
*/
-!function(a){if("function"==typeof define&&define.amd)define(["jquery","lodash","jquery-ui/core","jquery-ui/widget","jquery-ui/mouse","jquery-ui/draggable","jquery-ui/resizable"],a);else if("undefined"!=typeof exports){try{jQuery=require("jquery")}catch(b){}try{_=require("lodash")}catch(b){}a(jQuery,_)}else a(jQuery,_)}(function(a,b){function c(a){var c=a,d="px";if(c&&b.isString(c)){var e=c.match(/^([0-9]+)(px|em|rem)?$/);if(!e)throw new Error("Invalid height");d=e[2],c=parseInt(e[1])}return{height:c,unit:d}}var d=window,e=function(a,b,c){var d=function(){return console.warn("gridstack.js: Function `"+b+"` is deprecated as of v0.2.5 and has been replaced with `"+c+"`. It will be **completely** removed in v1.0."),a.apply(this,arguments)};return d.prototype=a.prototype,d},f=function(a,b){console.warn("gridstack.js: Option `"+a+"` is deprecated as of v0.2.5 and has been replaced with `"+b+"`. It will be **completely** removed in v1.0.")},g={isIntercepted:function(a,b){return!(a.x+a.width<=b.x||b.x+b.width<=a.x||a.y+a.height<=b.y||b.y+b.height<=a.y)},sort:function(a,c,d){return d=d||b.chain(a).map(function(a){return a.x+a.width}).max().value(),c=-1!=c?1:-1,b.sortBy(a,function(a){return c*(a.x+a.y*d)})},createStylesheet:function(a){var b=document.createElement("style");return b.setAttribute("type","text/css"),b.setAttribute("data-gs-id",a),b.styleSheet?b.styleSheet.cssText="":b.appendChild(document.createTextNode("")),document.getElementsByTagName("head")[0].appendChild(b),b.sheet},removeStylesheet:function(b){a("STYLE[data-gs-id="+b+"]").remove()},insertCSSRule:function(a,b,c,d){"function"==typeof a.insertRule?a.insertRule(b+"{"+c+"}",d):"function"==typeof a.addRule&&a.addRule(b,c,d)},toBool:function(a){return"boolean"==typeof a?a:"string"==typeof a?(a=a.toLowerCase(),!(""===a||"no"==a||"false"==a||"0"==a)):Boolean(a)},_collisionNodeCheck:function(a){return a!=this.node&&g.isIntercepted(a,this.nn)},_didCollideFloat:function(a){return this.n!=a&&g.isIntercepted({x:this.n.x,y:this.newY,width:this.n.width,height:this.n.height},a)},_didCollide:function(a){return g.isIntercepted({x:this.n.x,y:this.newY,width:this.n.width,height:this.n.height},a)},_isAddNodeIntercepted:function(a){return g.isIntercepted({x:this.x,y:this.y,width:this.node.width,height:this.node.height},a)}};
+!function(a){if("function"==typeof define&&define.amd)define(["jquery","lodash","jquery-ui/core","jquery-ui/widget","jquery-ui/mouse","jquery-ui/draggable","jquery-ui/resizable"],a);else if("undefined"!=typeof exports){try{jQuery=require("jquery")}catch(b){}try{_=require("lodash")}catch(b){}a(jQuery,_)}else a(jQuery,_)}(function(a,b){var c=window,d=function(a,b,c){var d=function(){return console.warn("gridstack.js: Function `"+b+"` is deprecated as of v0.2.5 and has been replaced with `"+c+"`. It will be **completely** removed in v1.0."),a.apply(this,arguments)};return d.prototype=a.prototype,d},e=function(a,b){console.warn("gridstack.js: Option `"+a+"` is deprecated as of v0.2.5 and has been replaced with `"+b+"`. It will be **completely** removed in v1.0.")},f={isIntercepted:function(a,b){return!(a.x+a.width<=b.x||b.x+b.width<=a.x||a.y+a.height<=b.y||b.y+b.height<=a.y)},sort:function(a,c,d){return d=d||b.chain(a).map(function(a){return a.x+a.width}).max().value(),c=-1!=c?1:-1,b.sortBy(a,function(a){return c*(a.x+a.y*d)})},createStylesheet:function(a){var b=document.createElement("style");return b.setAttribute("type","text/css"),b.setAttribute("data-gs-style-id",a),b.styleSheet?b.styleSheet.cssText="":b.appendChild(document.createTextNode("")),document.getElementsByTagName("head")[0].appendChild(b),b.sheet},removeStylesheet:function(b){a("STYLE[data-gs-style-id="+b+"]").remove()},insertCSSRule:function(a,b,c,d){"function"==typeof a.insertRule?a.insertRule(b+"{"+c+"}",d):"function"==typeof a.addRule&&a.addRule(b,c,d)},toBool:function(a){return"boolean"==typeof a?a:"string"==typeof a?(a=a.toLowerCase(),!(""===a||"no"==a||"false"==a||"0"==a)):Boolean(a)},_collisionNodeCheck:function(a){return a!=this.node&&f.isIntercepted(a,this.nn)},_didCollideFloat:function(a){return this.n!=a&&f.isIntercepted({x:this.n.x,y:this.newY,width:this.n.width,height:this.n.height},a)},_didCollide:function(a){return f.isIntercepted({x:this.n.x,y:this.newY,width:this.n.width,height:this.n.height},a)},_isAddNodeIntercepted:function(a){return f.isIntercepted({x:this.x,y:this.y,width:this.node.width,height:this.node.height},a)},parseHeight:function(a){var c=a,d="px";if(c&&b.isString(c)){var e=c.match(/^([0-9]*\.[0-9]+|[0-9]+)(px|em|rem|vh|vw)?$/);if(!e)throw new Error("Invalid height");d=e[2],c=parseFloat(e[1])}return{height:c,unit:d}}};
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
-g.is_intercepted=e(g.isIntercepted,"is_intercepted","isIntercepted"),g.create_stylesheet=e(g.createStylesheet,"create_stylesheet","createStylesheet"),g.remove_stylesheet=e(g.removeStylesheet,"remove_stylesheet","removeStylesheet"),g.insert_css_rule=e(g.insertCSSRule,"insert_css_rule","insertCSSRule");
+f.is_intercepted=d(f.isIntercepted,"is_intercepted","isIntercepted"),f.create_stylesheet=d(f.createStylesheet,"create_stylesheet","createStylesheet"),f.remove_stylesheet=d(f.removeStylesheet,"remove_stylesheet","removeStylesheet"),f.insert_css_rule=d(f.insertCSSRule,"insert_css_rule","insertCSSRule");
// jscs:enable requireCamelCaseOrUpperCaseIdentifiers
-var h=0,i=function(a,b,c,d,e){this.width=a,this["float"]=c||!1,this.height=d||0,this.nodes=e||[],this.onchange=b||function(){},this._updateCounter=0,this._float=this["float"]};i.prototype.batchUpdate=function(){this._updateCounter=1,this["float"]=!0},i.prototype.commit=function(){this._updateCounter=0,0===this._updateCounter&&(this["float"]=this._float,this._packNodes(),this._notify())},i.prototype._fixCollisions=function(a){this._sortNodes(-1);var c=a,d=Boolean(b.find(this.nodes,function(a){return a.locked}));for(this["float"]||d||(c={x:0,y:a.y,width:this.width,height:a.height});;){var e=b.find(this.nodes,b.bind(g._collisionNodeCheck,{node:a,nn:c}));if("undefined"==typeof e)return;this.moveNode(e,e.x,a.y+a.height,e.width,e.height,!0)}},i.prototype.isAreaEmpty=function(a,c,d,e){var f={x:a||0,y:c||0,width:d||1,height:e||1},h=b.find(this.nodes,b.bind(function(a){return g.isIntercepted(a,f)},this));return null===h},i.prototype._sortNodes=function(a){this.nodes=g.sort(this.nodes,a,this.width)},i.prototype._packNodes=function(){this._sortNodes(),this["float"]?b.each(this.nodes,b.bind(function(a,c){if(!a._updating&&"undefined"!=typeof a._origY&&a.y!=a._origY)for(var d=a.y;d>=a._origY;){var e=b.chain(this.nodes).find(b.bind(g._didCollide,{n:a,newY:d})).value();e||(a._dirty=!0,a.y=d),--d}},this)):b.each(this.nodes,b.bind(function(a,c){if(!a.locked)for(;a.y>0;){var d=a.y-1,e=0===c;if(c>0){var f=b.chain(this.nodes).take(c).find(b.bind(g._didCollide,{n:a,newY:d})).value();e="undefined"==typeof f}if(!e)break;a._dirty=a.y!=d,a.y=d}},this))},i.prototype._prepareNode=function(a,c){return a=b.defaults(a||{},{width:1,height:1,x:0,y:0}),a.x=parseInt(""+a.x),a.y=parseInt(""+a.y),a.width=parseInt(""+a.width),a.height=parseInt(""+a.height),a.autoPosition=a.autoPosition||!1,a.noResize=a.noResize||!1,a.noMove=a.noMove||!1,a.width>this.width?a.width=this.width:a.width<1&&(a.width=1),a.height<1&&(a.height=1),a.x<0&&(a.x=0),a.x+a.width>this.width&&(c?a.width=this.width-a.x:a.x=this.width-a.width),a.y<0&&(a.y=0),a},i.prototype._notify=function(){if(!this._updateCounter){var a=Array.prototype.slice.call(arguments,1).concat(this.getDirtyNodes());a=a.concat(this.getDirtyNodes()),this.onchange(a)}},i.prototype.cleanNodes=function(){b.each(this.nodes,function(a){a._dirty=!1})},i.prototype.getDirtyNodes=function(){return b.filter(this.nodes,function(a){return a._dirty})},i.prototype.addNode=function(a){if(a=this._prepareNode(a),"undefined"!=typeof a.maxWidth&&(a.width=Math.min(a.width,a.maxWidth)),"undefined"!=typeof a.maxHeight&&(a.height=Math.min(a.height,a.maxHeight)),"undefined"!=typeof a.minWidth&&(a.width=Math.max(a.width,a.minWidth)),"undefined"!=typeof a.minHeight&&(a.height=Math.max(a.height,a.minHeight)),a._id=++h,a._dirty=!0,a.autoPosition){this._sortNodes();for(var c=0;;++c){var d=c%this.width,e=Math.floor(c/this.width);if(!(d+a.width>this.width||b.find(this.nodes,b.bind(g._isAddNodeIntercepted,{x:d,y:e,node:a})))){a.x=d,a.y=e;break}}}return this.nodes.push(a),this._fixCollisions(a),this._packNodes(),this._notify(),a},i.prototype.removeNode=function(a){a._id=null,this.nodes=b.without(this.nodes,a),this._packNodes(),this._notify(a)},i.prototype.canMoveNode=function(c,d,e,f,g){var h=Boolean(b.find(this.nodes,function(a){return a.locked}));if(!this.height&&!h)return!0;var j,k=new i(this.width,null,this["float"],0,b.map(this.nodes,function(b){return b==c?j=a.extend({},b):a.extend({},b)}));k.moveNode(j,d,e,f,g);var l=!0;return h&&(l&=!Boolean(b.find(k.nodes,function(a){return a!=j&&Boolean(a.locked)&&Boolean(a._dirty)}))),this.height&&(l&=k.getGridHeight()<=this.height),l},i.prototype.canBePlacedWithRespectToHeight=function(c){if(!this.height)return!0;var d=new i(this.width,null,this["float"],0,b.map(this.nodes,function(b){return a.extend({},b)}));return d.addNode(c),d.getGridHeight()<=this.height},i.prototype.moveNode=function(a,b,c,d,e,f){if("number"!=typeof b&&(b=a.x),"number"!=typeof c&&(c=a.y),"number"!=typeof d&&(d=a.width),"number"!=typeof e&&(e=a.height),"undefined"!=typeof a.maxWidth&&(d=Math.min(d,a.maxWidth)),"undefined"!=typeof a.maxHeight&&(e=Math.min(e,a.maxHeight)),"undefined"!=typeof a.minWidth&&(d=Math.max(d,a.minWidth)),"undefined"!=typeof a.minHeight&&(e=Math.max(e,a.minHeight)),a.x==b&&a.y==c&&a.width==d&&a.height==e)return a;var g=a.width!=d;return a._dirty=!0,a.x=b,a.y=c,a.width=d,a.height=e,a=this._prepareNode(a,g),this._fixCollisions(a),f||(this._packNodes(),this._notify()),a},i.prototype.getGridHeight=function(){return b.reduce(this.nodes,function(a,b){return Math.max(a,b.y+b.height)},0)},i.prototype.beginUpdate=function(a){b.each(this.nodes,function(a){a._origY=a.y}),a._updating=!0},i.prototype.endUpdate=function(){b.each(this.nodes,function(a){a._origY=a.y});var a=b.find(this.nodes,function(a){return a._updating});a&&(a._updating=!1)};var j=function(c,d){var e,g=this;d=d||{},this.container=a(c),"undefined"!=typeof d.handle_class&&(d.handleClass=d.handle_class,f("handle_class","handleClass")),"undefined"!=typeof d.item_class&&(d.itemClass=d.item_class,f("item_class","itemClass")),"undefined"!=typeof d.placeholder_class&&(d.placeholderClass=d.placeholder_class,f("placeholder_class","placeholderClass")),"undefined"!=typeof d.placeholder_text&&(d.placeholderText=d.placeholder_text,f("placeholder_text","placeholderText")),"undefined"!=typeof d.item_class&&(d.itemClass=d.item_class,f("item_class","itemClass")),"undefined"!=typeof d.cell_height&&(d.cellHeight=d.cell_height,f("cell_height","cellHeight")),"undefined"!=typeof d.vertical_margin&&(d.verticalMargin=d.vertical_margin,f("vertical_margin","verticalMargin")),"undefined"!=typeof d.min_width&&(d.minWidth=d.min_width,f("min_width","minWidth")),"undefined"!=typeof d.static_grid&&(d.staticGrid=d.static_grid,f("static_grid","staticGrid")),"undefined"!=typeof d.is_nested&&(d.isNested=d.is_nested,f("is_nested","isNested")),"undefined"!=typeof d.always_show_resize_handle&&(d.alwaysShowResizeHandle=d.always_show_resize_handle,f("always_show_resize_handle","alwaysShowResizeHandle")),d.itemClass=d.itemClass||"grid-stack-item";var h=this.container.closest("."+d.itemClass).size()>0;if(this.opts=b.defaults(d||{},{width:parseInt(this.container.attr("data-gs-width"))||12,height:parseInt(this.container.attr("data-gs-height"))||0,itemClass:"grid-stack-item",placeholderClass:"grid-stack-placeholder",placeholderText:"",handle:".grid-stack-item-content",handleClass:null,cellHeight:60,verticalMargin:20,auto:!0,minWidth:768,"float":!1,staticGrid:!1,_class:"grid-stack-instance-"+(1e4*Math.random()).toFixed(0),animate:Boolean(this.container.attr("data-gs-animate"))||!1,alwaysShowResizeHandle:d.alwaysShowResizeHandle||!1,resizable:b.defaults(d.resizable||{},{autoHide:!d.alwaysShowResizeHandle,handles:"se"}),draggable:b.defaults(d.draggable||{},{handle:(d.handleClass?"."+d.handleClass:d.handle?d.handle:"")||".grid-stack-item-content",scroll:!1,appendTo:"body"})}),this.opts.isNested=h,this.cellHeight(this.opts.cellHeight,!0),this.verticalMargin(this.opts.verticalMargin,!0),this.container.addClass(this.opts._class),this._setStaticClass(),h&&this.container.addClass("grid-stack-nested"),this._initStyles(),this.grid=new i(this.opts.width,function(a){var c=0;b.each(a,function(a){null===a._id?a.el.remove():(a.el.attr("data-gs-x",a.x).attr("data-gs-y",a.y).attr("data-gs-width",a.width).attr("data-gs-height",a.height),c=Math.max(c,a.y+a.height))}),g._updateStyles(c+10)},this.opts["float"],this.opts.height),this.opts.auto){var j=[],k=this;this.container.children("."+this.opts.itemClass+":not(."+this.opts.placeholderClass+")").each(function(b,c){c=a(c),j.push({el:c,i:parseInt(c.attr("data-gs-x"))+parseInt(c.attr("data-gs-y"))*k.opts.width})}),b.chain(j).sortBy(function(a){return a.i}).each(function(a){g._prepareElement(a.el)}).value()}this.setAnimation(this.opts.animate),this.placeholder=a(''+this.opts.placeholderText+"
").hide(),this._updateContainerHeight(),this.onResizeHandler=function(){if(g._isOneColumnMode()){if(e)return;e=!0,g.grid._sortNodes(),b.each(g.grid.nodes,function(a){g.container.append(a.el),g.opts.staticGrid||(a.noMove||a.el.draggable("disable"),a.noResize||a.el.resizable("disable"))})}else{if(!e)return;if(e=!1,g.opts.staticGrid)return;b.each(g.grid.nodes,function(a){a.noMove||a.el.draggable("enable"),a.noResize||a.el.resizable("enable")})}},a(window).resize(this.onResizeHandler),this.onResizeHandler()};
+var g=0,h=function(a,b,c,d,e){this.width=a,this["float"]=c||!1,this.height=d||0,this.nodes=e||[],this.onchange=b||function(){},this._updateCounter=0,this._float=this["float"]};h.prototype.batchUpdate=function(){this._updateCounter=1,this["float"]=!0},h.prototype.commit=function(){0!==this._updateCounter&&(this._updateCounter=0,this["float"]=this._float,this._packNodes(),this._notify())},
+// For Meteor support: https://github.com/troolee/gridstack.js/pull/272
+h.prototype.getNodeDataByDOMEl=function(a){return b.find(this.nodes,function(b){return a.get(0)===b.el.get(0)})},h.prototype._fixCollisions=function(a){this._sortNodes(-1);var c=a,d=Boolean(b.find(this.nodes,function(a){return a.locked}));for(this["float"]||d||(c={x:0,y:a.y,width:this.width,height:a.height});;){var e=b.find(this.nodes,b.bind(f._collisionNodeCheck,{node:a,nn:c}));if("undefined"==typeof e)return;this.moveNode(e,e.x,a.y+a.height,e.width,e.height,!0)}},h.prototype.isAreaEmpty=function(a,c,d,e){var g={x:a||0,y:c||0,width:d||1,height:e||1},h=b.find(this.nodes,b.bind(function(a){return f.isIntercepted(a,g)},this));return null===h},h.prototype._sortNodes=function(a){this.nodes=f.sort(this.nodes,a,this.width)},h.prototype._packNodes=function(){this._sortNodes(),this["float"]?b.each(this.nodes,b.bind(function(a,c){if(!a._updating&&"undefined"!=typeof a._origY&&a.y!=a._origY)for(var d=a.y;d>=a._origY;){var e=b.chain(this.nodes).find(b.bind(f._didCollide,{n:a,newY:d})).value();e||(a._dirty=!0,a.y=d),--d}},this)):b.each(this.nodes,b.bind(function(a,c){if(!a.locked)for(;a.y>0;){var d=a.y-1,e=0===c;if(c>0){var g=b.chain(this.nodes).take(c).find(b.bind(f._didCollide,{n:a,newY:d})).value();e="undefined"==typeof g}if(!e)break;a._dirty=a.y!=d,a.y=d}},this))},h.prototype._prepareNode=function(a,c){return a=b.defaults(a||{},{width:1,height:1,x:0,y:0}),a.x=parseInt(""+a.x),a.y=parseInt(""+a.y),a.width=parseInt(""+a.width),a.height=parseInt(""+a.height),a.autoPosition=a.autoPosition||!1,a.noResize=a.noResize||!1,a.noMove=a.noMove||!1,a.width>this.width?a.width=this.width:a.width<1&&(a.width=1),a.height<1&&(a.height=1),a.x<0&&(a.x=0),a.x+a.width>this.width&&(c?a.width=this.width-a.x:a.x=this.width-a.width),a.y<0&&(a.y=0),a},h.prototype._notify=function(){if(!this._updateCounter){var a=Array.prototype.slice.call(arguments,1).concat(this.getDirtyNodes());a=a.concat(this.getDirtyNodes()),this.onchange(a)}},h.prototype.cleanNodes=function(){this._updateCounter||b.each(this.nodes,function(a){a._dirty=!1})},h.prototype.getDirtyNodes=function(){return b.filter(this.nodes,function(a){return a._dirty})},h.prototype.addNode=function(a){if(a=this._prepareNode(a),"undefined"!=typeof a.maxWidth&&(a.width=Math.min(a.width,a.maxWidth)),"undefined"!=typeof a.maxHeight&&(a.height=Math.min(a.height,a.maxHeight)),"undefined"!=typeof a.minWidth&&(a.width=Math.max(a.width,a.minWidth)),"undefined"!=typeof a.minHeight&&(a.height=Math.max(a.height,a.minHeight)),a._id=++g,a._dirty=!0,a.autoPosition){this._sortNodes();for(var c=0;;++c){var d=c%this.width,e=Math.floor(c/this.width);if(!(d+a.width>this.width||b.find(this.nodes,b.bind(f._isAddNodeIntercepted,{x:d,y:e,node:a})))){a.x=d,a.y=e;break}}}return this.nodes.push(a),this._fixCollisions(a),this._packNodes(),this._notify(),a},h.prototype.removeNode=function(a){a._id=null,this.nodes=b.without(this.nodes,a),this._packNodes(),this._notify(a)},h.prototype.canMoveNode=function(c,d,e,f,g){var i=Boolean(b.find(this.nodes,function(a){return a.locked}));if(!this.height&&!i)return!0;var j,k=new h(this.width,null,this["float"],0,b.map(this.nodes,function(b){return b==c?j=a.extend({},b):a.extend({},b)}));k.moveNode(j,d,e,f,g);var l=!0;return i&&(l&=!Boolean(b.find(k.nodes,function(a){return a!=j&&Boolean(a.locked)&&Boolean(a._dirty)}))),this.height&&(l&=k.getGridHeight()<=this.height),l},h.prototype.canBePlacedWithRespectToHeight=function(c){if(!this.height)return!0;var d=new h(this.width,null,this["float"],0,b.map(this.nodes,function(b){return a.extend({},b)}));return d.addNode(c),d.getGridHeight()<=this.height},h.prototype.moveNode=function(a,b,c,d,e,f){if("number"!=typeof b&&(b=a.x),"number"!=typeof c&&(c=a.y),"number"!=typeof d&&(d=a.width),"number"!=typeof e&&(e=a.height),"undefined"!=typeof a.maxWidth&&(d=Math.min(d,a.maxWidth)),"undefined"!=typeof a.maxHeight&&(e=Math.min(e,a.maxHeight)),"undefined"!=typeof a.minWidth&&(d=Math.max(d,a.minWidth)),"undefined"!=typeof a.minHeight&&(e=Math.max(e,a.minHeight)),a.x==b&&a.y==c&&a.width==d&&a.height==e)return a;var g=a.width!=d;return a._dirty=!0,a.x=b,a.y=c,a.width=d,a.height=e,a=this._prepareNode(a,g),this._fixCollisions(a),f||(this._packNodes(),this._notify()),a},h.prototype.getGridHeight=function(){return b.reduce(this.nodes,function(a,b){return Math.max(a,b.y+b.height)},0)},h.prototype.beginUpdate=function(a){b.each(this.nodes,function(a){a._origY=a.y}),a._updating=!0},h.prototype.endUpdate=function(){b.each(this.nodes,function(a){a._origY=a.y});var a=b.find(this.nodes,function(a){return a._updating});a&&(a._updating=!1)};var i=function(c,d){var f,g,i=this;d=d||{},this.container=a(c),"undefined"!=typeof d.handle_class&&(d.handleClass=d.handle_class,e("handle_class","handleClass")),"undefined"!=typeof d.item_class&&(d.itemClass=d.item_class,e("item_class","itemClass")),"undefined"!=typeof d.placeholder_class&&(d.placeholderClass=d.placeholder_class,e("placeholder_class","placeholderClass")),"undefined"!=typeof d.placeholder_text&&(d.placeholderText=d.placeholder_text,e("placeholder_text","placeholderText")),"undefined"!=typeof d.item_class&&(d.itemClass=d.item_class,e("item_class","itemClass")),"undefined"!=typeof d.cell_height&&(d.cellHeight=d.cell_height,e("cell_height","cellHeight")),"undefined"!=typeof d.vertical_margin&&(d.verticalMargin=d.vertical_margin,e("vertical_margin","verticalMargin")),"undefined"!=typeof d.min_width&&(d.minWidth=d.min_width,e("min_width","minWidth")),"undefined"!=typeof d.static_grid&&(d.staticGrid=d.static_grid,e("static_grid","staticGrid")),"undefined"!=typeof d.is_nested&&(d.isNested=d.is_nested,e("is_nested","isNested")),"undefined"!=typeof d.always_show_resize_handle&&(d.alwaysShowResizeHandle=d.always_show_resize_handle,e("always_show_resize_handle","alwaysShowResizeHandle")),d.itemClass=d.itemClass||"grid-stack-item";var j=this.container.closest("."+d.itemClass).size()>0;if(this.opts=b.defaults(d||{},{width:parseInt(this.container.attr("data-gs-width"))||12,height:parseInt(this.container.attr("data-gs-height"))||0,itemClass:"grid-stack-item",placeholderClass:"grid-stack-placeholder",placeholderText:"",handle:".grid-stack-item-content",handleClass:null,cellHeight:60,verticalMargin:20,auto:!0,minWidth:768,"float":!1,staticGrid:!1,_class:"grid-stack-instance-"+(1e4*Math.random()).toFixed(0),animate:Boolean(this.container.attr("data-gs-animate"))||!1,alwaysShowResizeHandle:d.alwaysShowResizeHandle||!1,resizable:b.defaults(d.resizable||{},{autoHide:!d.alwaysShowResizeHandle,handles:"se"}),draggable:b.defaults(d.draggable||{},{handle:(d.handleClass?"."+d.handleClass:d.handle?d.handle:"")||".grid-stack-item-content",scroll:!1,appendTo:"body"}),disableDrag:d.disableDrag||!1,disableResize:d.disableResize||!1,rtl:"auto",removable:!1,removeTimeout:2e3}),"auto"===this.opts.rtl&&(this.opts.rtl="rtl"===this.container.css("direction")),this.opts.rtl&&this.container.addClass("grid-stack-rtl"),this.opts.isNested=j,g="auto"===this.opts.cellHeight,g?i.cellHeight(i.cellWidth(),!0):this.cellHeight(this.opts.cellHeight,!0),this.verticalMargin(this.opts.verticalMargin,!0),this.container.addClass(this.opts._class),this._setStaticClass(),j&&this.container.addClass("grid-stack-nested"),this._initStyles(),this.grid=new h(this.opts.width,function(a){var c=0;b.each(a,function(a){null===a._id?a.el.remove():(a.el.attr("data-gs-x",a.x).attr("data-gs-y",a.y).attr("data-gs-width",a.width).attr("data-gs-height",a.height),c=Math.max(c,a.y+a.height))}),i._updateStyles(c+10)},this.opts["float"],this.opts.height),this.opts.auto){var k=[],l=this;this.container.children("."+this.opts.itemClass+":not(."+this.opts.placeholderClass+")").each(function(b,c){c=a(c),k.push({el:c,i:parseInt(c.attr("data-gs-x"))+parseInt(c.attr("data-gs-y"))*l.opts.width})}),b.chain(k).sortBy(function(a){return a.i}).each(function(a){i._prepareElement(a.el)}).value()}this.setAnimation(this.opts.animate),this.placeholder=a(''+this.opts.placeholderText+"
").hide(),this._updateContainerHeight(),this._updateHeightsOnResize=b.throttle(function(){i.cellHeight(i.cellWidth(),!1)},100),this.onResizeHandler=function(){if(g&&i._updateHeightsOnResize(),i._isOneColumnMode()){if(f)return;f=!0,i.grid._sortNodes(),b.each(i.grid.nodes,function(a){i.container.append(a.el),i.opts.staticGrid||((a.noMove||i.opts.disableDrag)&&a.el.draggable("disable"),(a.noResize||i.opts.disableResize)&&a.el.resizable("disable"))})}else{if(!f)return;if(f=!1,i.opts.staticGrid)return;b.each(i.grid.nodes,function(a){a.noMove||i.opts.disableDrag||a.el.draggable("enable"),a.noResize||i.opts.disableResize||a.el.resizable("enable")})}},a(window).resize(this.onResizeHandler),this.onResizeHandler()};
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
// jscs:enable requireCamelCaseOrUpperCaseIdentifiers
-return j.prototype._triggerChangeEvent=function(a){var b=this.grid.getDirtyNodes(),c=!1,d=[];b&&b.length&&(d.push(b),c=!0),(c||a===!0)&&this.container.trigger("change",d)},j.prototype._initStyles=function(){this.opts.cellHeight&&(this._stylesId&&a('[data-gs-id="'+this._stylesId+'"]').remove(),this._stylesId="gridstack-style-"+(1e5*Math.random()).toFixed(),this._styles=g.createStylesheet(this._stylesId),null!=this._styles&&(this._styles._max=0))},j.prototype._updateStyles=function(a){if(null!==this._styles){var b,c="."+this.opts._class+" ."+this.opts.itemClass,d=this;if("undefined"==typeof a&&(a=this._styles._max,this._initStyles(),this._updateContainerHeight()),this.opts.cellHeight&&!(0!==this._styles._max&&a<=this._styles._max)&&(b=this.opts.verticalMargin&&this.opts.cellHeightUnit!==this.opts.verticalMarginUnit?function(a,b){return a&&b?"calc("+(d.opts.cellHeight*a+d.opts.cellHeightUnit)+" + "+(d.opts.verticalMargin*b+d.opts.verticalMarginUnit)+")":d.opts.cellHeight*a+d.opts.verticalMargin*b+d.opts.cellHeightUnit}:function(a,b){return d.opts.cellHeight*a+d.opts.verticalMargin*b+d.opts.cellHeightUnit},0===this._styles._max&&g.insertCSSRule(this._styles,c,"min-height: "+b(1,0)+";",0),a>this._styles._max)){for(var e=this._styles._max;a>e;++e)g.insertCSSRule(this._styles,c+'[data-gs-height="'+(e+1)+'"]',"height: "+b(e+1,e)+";",e),g.insertCSSRule(this._styles,c+'[data-gs-min-height="'+(e+1)+'"]',"min-height: "+b(e+1,e)+";",e),g.insertCSSRule(this._styles,c+'[data-gs-max-height="'+(e+1)+'"]',"max-height: "+b(e+1,e)+";",e),g.insertCSSRule(this._styles,c+'[data-gs-y="'+e+'"]',"top: "+b(e,e)+";",e);this._styles._max=a}}},j.prototype._updateContainerHeight=function(){if(!this.grid._updateCounter){var a=this.grid.getGridHeight();this.container.attr("data-gs-current-height",a),this.opts.cellHeight&&(this.opts.verticalMargin?this.opts.cellHeightUnit===this.opts.verticalMarginUnit?this.container.css("height",a*(this.opts.cellHeight+this.opts.verticalMargin)-this.opts.verticalMargin+this.opts.cellHeightUnit):this.container.css("height","calc("+(a*this.opts.cellHeight+this.opts.cellHeightUnit)+" + "+(a*(this.opts.verticalMargin-1)+this.opts.verticalMarginUnit)+")"):this.container.css("height",a*this.opts.cellHeight+this.opts.cellHeightUnit))}},j.prototype._isOneColumnMode=function(){return(window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth)<=this.opts.minWidth},j.prototype._prepareElement=function(c){var d=this;c=a(c),c.addClass(this.opts.itemClass);var e=d.grid.addNode({x:c.attr("data-gs-x"),y:c.attr("data-gs-y"),width:c.attr("data-gs-width"),height:c.attr("data-gs-height"),maxWidth:c.attr("data-gs-max-width"),minWidth:c.attr("data-gs-min-width"),maxHeight:c.attr("data-gs-max-height"),minHeight:c.attr("data-gs-min-height"),autoPosition:g.toBool(c.attr("data-gs-auto-position")),noResize:g.toBool(c.attr("data-gs-no-resize")),noMove:g.toBool(c.attr("data-gs-no-move")),locked:g.toBool(c.attr("data-gs-locked")),el:c});if(c.data("_gridstack_node",e),!d.opts.staticGrid){var f,h,i=function(a,b){var c,g,i=Math.round(b.position.left/f),j=Math.floor((b.position.top+h/2)/h);"drag"!=a.type&&(c=Math.round(b.size.width/f),g=Math.round(b.size.height/h)),d.grid.canMoveNode(e,i,j,c,g)&&(d.grid.moveNode(e,i,j,c,g),d._updateContainerHeight())},j=function(b,g){d.container.append(d.placeholder);var i=a(this);d.grid.cleanNodes(),d.grid.beginUpdate(e),f=Math.ceil(i.outerWidth()/i.attr("data-gs-width"));var j=Math.ceil(i.outerHeight()/i.attr("data-gs-height"));h=d.container.height()/parseInt(d.container.attr("data-gs-current-height")),d.placeholder.attr("data-gs-x",i.attr("data-gs-x")).attr("data-gs-y",i.attr("data-gs-y")).attr("data-gs-width",i.attr("data-gs-width")).attr("data-gs-height",i.attr("data-gs-height")).show(),e.el=d.placeholder,c.resizable("option","minWidth",f*(e.minWidth||1)),c.resizable("option","minHeight",j*(e.minHeight||1)),"resizestart"==b.type&&i.find(".grid-stack-item").trigger("resizestart")},k=function(b,c){d.placeholder.detach();var f=a(this);e.el=f,d.placeholder.hide(),f.attr("data-gs-x",e.x).attr("data-gs-y",e.y).attr("data-gs-width",e.width).attr("data-gs-height",e.height).removeAttr("style"),d._updateContainerHeight(),d._triggerChangeEvent(),d.grid.endUpdate();var g=f.find(".grid-stack");g.length&&"resizestop"==b.type&&(g.each(function(b,c){a(c).data("gridstack").onResizeHandler()}),f.find(".grid-stack-item").trigger("resizestop"))};c.draggable(b.extend(this.opts.draggable,{containment:this.opts.isNested?this.container.parent():null,start:j,stop:k,drag:i})).resizable(b.extend(this.opts.resizable,{start:j,stop:k,resize:i})),(e.noMove||this._isOneColumnMode())&&c.draggable("disable"),(e.noResize||this._isOneColumnMode())&&c.resizable("disable"),c.attr("data-gs-locked",e.locked?"yes":null)}},j.prototype.setAnimation=function(a){a?this.container.addClass("grid-stack-animate"):this.container.removeClass("grid-stack-animate")},j.prototype.addWidget=function(b,c,d,e,f,g){return b=a(b),"undefined"!=typeof c&&b.attr("data-gs-x",c),"undefined"!=typeof d&&b.attr("data-gs-y",d),"undefined"!=typeof e&&b.attr("data-gs-width",e),"undefined"!=typeof f&&b.attr("data-gs-height",f),"undefined"!=typeof g&&b.attr("data-gs-auto-position",g?"yes":null),this.container.append(b),this._prepareElement(b),this._updateContainerHeight(),this._triggerChangeEvent(!0),b},j.prototype.makeWidget=function(b){return b=a(b),this._prepareElement(b),this._updateContainerHeight(),this._triggerChangeEvent(!0),b},j.prototype.willItFit=function(a,b,c,d,e){var f={x:a,y:b,width:c,height:d,autoPosition:e};return this.grid.canBePlacedWithRespectToHeight(f)},j.prototype.removeWidget=function(b,c){c="undefined"==typeof c?!0:c,b=a(b);var d=b.data("_gridstack_node");this.grid.removeNode(d),b.removeData("_gridstack_node"),this._updateContainerHeight(),c&&b.remove(),this._triggerChangeEvent(!0)},j.prototype.removeAll=function(a){b.each(this.grid.nodes,b.bind(function(b){this.removeWidget(b.el,a)},this)),this.grid.nodes=[],this._updateContainerHeight()},j.prototype.destroy=function(){a(window).off("resize",this.onResizeHandler),this.disable(),this.container.remove(),g.removeStylesheet(this._stylesId),this.grid&&(this.grid=null)},j.prototype.resizable=function(b,c){var d=this;return b=a(b),b.each(function(b,e){e=a(e);var f=e.data("_gridstack_node");"undefined"!=typeof f&&null!==f&&(f.noResize=!c,f.noResize||d._isOneColumnMode()?e.resizable("disable"):e.resizable("enable"))}),this},j.prototype.movable=function(b,c){var d=this;return b=a(b),b.each(function(b,e){e=a(e);var f=e.data("_gridstack_node");"undefined"!=typeof f&&null!==f&&(f.noMove=!c,f.noMove||d._isOneColumnMode()?(e.draggable("disable"),e.removeClass("ui-draggable-handle")):(e.draggable("enable"),e.addClass("ui-draggable-handle")))}),this},j.prototype.disable=function(){this.movable(this.container.children("."+this.opts.itemClass),!1),this.resizable(this.container.children("."+this.opts.itemClass),!1),this.container.trigger("disable")},j.prototype.enable=function(){this.movable(this.container.children("."+this.opts.itemClass),!0),this.resizable(this.container.children("."+this.opts.itemClass),!0),this.container.trigger("enable")},j.prototype.locked=function(b,c){return b=a(b),b.each(function(b,d){d=a(d);var e=d.data("_gridstack_node");"undefined"!=typeof e&&null!==e&&(e.locked=c||!1,d.attr("data-gs-locked",e.locked?"yes":null))}),this},j.prototype.maxHeight=function(b,c){return b=a(b),b.each(function(b,d){d=a(d);var e=d.data("_gridstack_node");"undefined"!=typeof e&&null!=e&&(isNaN(c)||(e.maxHeight=c||!1,d.attr("data-gs-max-height",c)))}),this},j.prototype.minHeight=function(b,c){return b=a(b),b.each(function(b,d){d=a(d);var e=d.data("_gridstack_node");"undefined"!=typeof e&&null!=e&&(isNaN(c)||(e.minHeight=c||!1,d.attr("data-gs-min-height",c)))}),this},j.prototype.maxWidth=function(b,c){return b=a(b),b.each(function(b,d){d=a(d);var e=d.data("_gridstack_node");"undefined"!=typeof e&&null!=e&&(isNaN(c)||(e.maxWidth=c||!1,d.attr("data-gs-max-width",c)))}),this},j.prototype.minWidth=function(b,c){return b=a(b),b.each(function(b,d){d=a(d);var e=d.data("_gridstack_node");"undefined"!=typeof e&&null!=e&&(isNaN(c)||(e.minWidth=c||!1,d.attr("data-gs-min-width",c)))}),this},j.prototype._updateElement=function(b,c){b=a(b).first();var d=b.data("_gridstack_node");if("undefined"!=typeof d&&null!==d){var e=this;e.grid.cleanNodes(),e.grid.beginUpdate(d),c.call(this,b,d),e._updateContainerHeight(),e._triggerChangeEvent(),e.grid.endUpdate()}},j.prototype.resize=function(a,b,c){this._updateElement(a,function(a,d){b=null!==b&&"undefined"!=typeof b?b:d.width,c=null!==c&&"undefined"!=typeof c?c:d.height,this.grid.moveNode(d,d.x,d.y,b,c)})},j.prototype.move=function(a,b,c){this._updateElement(a,function(a,d){b=null!==b&&"undefined"!=typeof b?b:d.x,c=null!==c&&"undefined"!=typeof c?c:d.y,this.grid.moveNode(d,b,c,d.width,d.height)})},j.prototype.update=function(a,b,c,d,e){this._updateElement(a,function(a,f){b=null!==b&&"undefined"!=typeof b?b:f.x,c=null!==c&&"undefined"!=typeof c?c:f.y,d=null!==d&&"undefined"!=typeof d?d:f.width,e=null!==e&&"undefined"!=typeof e?e:f.height,this.grid.moveNode(f,b,c,d,e)})},j.prototype.verticalMargin=function(a,b){if("undefined"==typeof a)return this.opts.verticalMargin;var d=c(a);(this.opts.verticalMarginUnit!==d.unit||this.opts.height!==d.height)&&(this.opts.verticalMarginUnit=d.unit,this.opts.verticalMargin=d.height,b||this._updateStyles())},j.prototype.cellHeight=function(a,b){if("undefined"==typeof a){if(this.opts.cellHeight)return this.opts.cellHeight;var d=this.container.children("."+this.opts.itemClass).first();return Math.ceil(d.outerHeight()/d.attr("data-gs-height"))}var e=c(a);(this.opts.cellHeightUnit!==e.heightUnit||this.opts.height!==e.height)&&(this.opts.cellHeightUnit=e.unit,this.opts.cellHeight=e.height,b||this._updateStyles())},j.prototype.cellWidth=function(){var a=this.container.children("."+this.opts.itemClass).first();return Math.ceil(a.outerWidth()/a.attr("data-gs-width"))},j.prototype.getCellFromPixel=function(a){var b=this.container.position(),c=a.left-b.left,d=a.top-b.top,e=Math.floor(this.container.width()/this.opts.width),f=Math.floor(this.container.height()/parseInt(this.container.attr("data-gs-current-height")));return{x:Math.floor(c/e),y:Math.floor(d/f)}},j.prototype.batchUpdate=function(){this.grid.batchUpdate()},j.prototype.commit=function(){this.grid.commit(),this._updateContainerHeight()},j.prototype.isAreaEmpty=function(a,b,c,d){return this.grid.isAreaEmpty(a,b,c,d)},j.prototype.setStatic=function(a){this.opts.staticGrid=a===!0,this._setStaticClass()},j.prototype._setStaticClass=function(){var a="grid-stack-static";this.opts.staticGrid===!0?this.container.addClass(a):this.container.removeClass(a)},i.prototype.batch_update=e(i.prototype.batchUpdate),i.prototype._fix_collisions=e(i.prototype._fixCollisions,"_fix_collisions","_fixCollisions"),i.prototype.is_area_empty=e(i.prototype.isAreaEmpty,"is_area_empty","isAreaEmpty"),i.prototype._sort_nodes=e(i.prototype._sortNodes,"_sort_nodes","_sortNodes"),i.prototype._pack_nodes=e(i.prototype._packNodes,"_pack_nodes","_packNodes"),i.prototype._prepare_node=e(i.prototype._prepareNode,"_prepare_node","_prepareNode"),i.prototype.clean_nodes=e(i.prototype.cleanNodes,"clean_nodes","cleanNodes"),i.prototype.get_dirty_nodes=e(i.prototype.getDirtyNodes,"get_dirty_nodes","getDirtyNodes"),i.prototype.add_node=e(i.prototype.addNode,"add_node","addNode, "),i.prototype.remove_node=e(i.prototype.removeNode,"remove_node","removeNode"),i.prototype.can_move_node=e(i.prototype.canMoveNode,"can_move_node","canMoveNode"),i.prototype.move_node=e(i.prototype.moveNode,"move_node","moveNode"),i.prototype.get_grid_height=e(i.prototype.getGridHeight,"get_grid_height","getGridHeight"),i.prototype.begin_update=e(i.prototype.beginUpdate,"begin_update","beginUpdate"),i.prototype.end_update=e(i.prototype.endUpdate,"end_update","endUpdate"),i.prototype.can_be_placed_with_respect_to_height=e(i.prototype.canBePlacedWithRespectToHeight,"can_be_placed_with_respect_to_height","canBePlacedWithRespectToHeight"),j.prototype._trigger_change_event=e(j.prototype._triggerChangeEvent,"_trigger_change_event","_triggerChangeEvent"),j.prototype._init_styles=e(j.prototype._initStyles,"_init_styles","_initStyles"),j.prototype._update_styles=e(j.prototype._updateStyles,"_update_styles","_updateStyles"),j.prototype._update_container_height=e(j.prototype._updateContainerHeight,"_update_container_height","_updateContainerHeight"),j.prototype._is_one_column_mode=e(j.prototype._isOneColumnMode,"_is_one_column_mode"," _isOneColumnMode"),j.prototype._prepare_element=e(j.prototype._prepareElement,"_prepare_element","_prepareElement"),j.prototype.set_animation=e(j.prototype.setAnimation,"set_animation","setAnimation"),j.prototype.add_widget=e(j.prototype.addWidget,"add_widget","addWidget"),j.prototype.make_widget=e(j.prototype.makeWidget,"make_widget","makeWidget"),j.prototype.will_it_fit=e(j.prototype.willItFit,"will_it_fit","willItFit"),j.prototype.remove_widget=e(j.prototype.removeWidget,"remove_widget","removeWidget"),j.prototype.remove_all=e(j.prototype.removeAll,"remove_all","removeAll"),j.prototype.min_height=e(j.prototype.minHeight,"min_height","minHeight"),j.prototype.min_width=e(j.prototype.minWidth,"min_width","minWidth"),j.prototype._update_element=e(j.prototype._updateElement,"_update_element","_updateElement"),j.prototype.cell_height=e(j.prototype.cellHeight,"cell_height","cellHeight"),j.prototype.cell_width=e(j.prototype.cellWidth,"cell_width","cellWidth"),j.prototype.get_cell_from_pixel=e(j.prototype.getCellFromPixel,"get_cell_from_pixel","getCellFromPixel"),j.prototype.batch_update=e(j.prototype.batchUpdate,"batch_update","batchUpdate"),j.prototype.is_area_empty=e(j.prototype.isAreaEmpty,"is_area_empty","isAreaEmpty"),j.prototype.set_static=e(j.prototype.setStatic,"set_static","setStatic"),j.prototype._set_static_class=e(j.prototype._setStaticClass,"_set_static_class","_setStaticClass"),d.GridStackUI=j,d.GridStackUI.Utils=g,a.fn.gridstack=function(b){return this.each(function(){var c=a(this);c.data("gridstack")||c.data("gridstack",new j(this,b))})},d.GridStackUI});
+return i.prototype._triggerChangeEvent=function(a){var b=this.grid.getDirtyNodes(),c=!1,d=[];b&&b.length&&(d.push(b),c=!0),(c||a===!0)&&this.container.trigger("change",d)},i.prototype._initStyles=function(){this._stylesId&&f.removeStylesheet(this._stylesId),this._stylesId="gridstack-style-"+(1e5*Math.random()).toFixed(),this._styles=f.createStylesheet(this._stylesId),null!==this._styles&&(this._styles._max=0)},i.prototype._updateStyles=function(a){if(null!==this._styles&&"undefined"!=typeof this._styles){var b,c="."+this.opts._class+" ."+this.opts.itemClass,d=this;if("undefined"==typeof a&&(a=this._styles._max,this._initStyles(),this._updateContainerHeight()),this.opts.cellHeight&&!(0!==this._styles._max&&a<=this._styles._max)&&(b=this.opts.verticalMargin&&this.opts.cellHeightUnit!==this.opts.verticalMarginUnit?function(a,b){return a&&b?"calc("+(d.opts.cellHeight*a+d.opts.cellHeightUnit)+" + "+(d.opts.verticalMargin*b+d.opts.verticalMarginUnit)+")":d.opts.cellHeight*a+d.opts.verticalMargin*b+d.opts.cellHeightUnit}:function(a,b){return d.opts.cellHeight*a+d.opts.verticalMargin*b+d.opts.cellHeightUnit},0===this._styles._max&&f.insertCSSRule(this._styles,c,"min-height: "+b(1,0)+";",0),a>this._styles._max)){for(var e=this._styles._max;a>e;++e)f.insertCSSRule(this._styles,c+'[data-gs-height="'+(e+1)+'"]',"height: "+b(e+1,e)+";",e),f.insertCSSRule(this._styles,c+'[data-gs-min-height="'+(e+1)+'"]',"min-height: "+b(e+1,e)+";",e),f.insertCSSRule(this._styles,c+'[data-gs-max-height="'+(e+1)+'"]',"max-height: "+b(e+1,e)+";",e),f.insertCSSRule(this._styles,c+'[data-gs-y="'+e+'"]',"top: "+b(e,e)+";",e);this._styles._max=a}}},i.prototype._updateContainerHeight=function(){if(!this.grid._updateCounter){var a=this.grid.getGridHeight();this.container.attr("data-gs-current-height",a),this.opts.cellHeight&&(this.opts.verticalMargin?this.opts.cellHeightUnit===this.opts.verticalMarginUnit?this.container.css("height",a*(this.opts.cellHeight+this.opts.verticalMargin)-this.opts.verticalMargin+this.opts.cellHeightUnit):this.container.css("height","calc("+(a*this.opts.cellHeight+this.opts.cellHeightUnit)+" + "+(a*(this.opts.verticalMargin-1)+this.opts.verticalMarginUnit)+")"):this.container.css("height",a*this.opts.cellHeight+this.opts.cellHeightUnit))}},i.prototype._isOneColumnMode=function(){return(window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth)<=this.opts.minWidth},i.prototype._prepareElement=function(c){var d=this;c=a(c),c.addClass(this.opts.itemClass);var e=d.grid.addNode({x:c.attr("data-gs-x"),y:c.attr("data-gs-y"),width:c.attr("data-gs-width"),height:c.attr("data-gs-height"),maxWidth:c.attr("data-gs-max-width"),minWidth:c.attr("data-gs-min-width"),maxHeight:c.attr("data-gs-max-height"),minHeight:c.attr("data-gs-min-height"),autoPosition:f.toBool(c.attr("data-gs-auto-position")),noResize:f.toBool(c.attr("data-gs-no-resize")),noMove:f.toBool(c.attr("data-gs-no-move")),locked:f.toBool(c.attr("data-gs-locked")),el:c,id:c.attr("data-gs-id")});c.data("_gridstack_node",e);var g,h,i,j=function(){!i&&d.opts.removable&&(i=setTimeout(function(){c.addClass("grid-stack-item-removing"),e._isAboutToRemove=!0},d.opts.removeTimeout))},k=function(){i&&(clearTimeout(i),i=null,c.removeClass("grid-stack-item-removing"),e._isAboutToRemove=!1)},l=function(a,b){var c,f,i=Math.round(b.position.left/g),l=Math.floor((b.position.top+h/2)/h);if("drag"!=a.type&&(c=Math.round(b.size.width/g),f=Math.round(b.size.height/h)),"drag"==a.type)0>i||i>=d.grid.width||0>l?(j(),i=e._beforeDragX,l=e._beforeDragY,d.placeholder.detach(),d.placeholder.hide(),d.grid.removeNode(e),d._updateContainerHeight(),e._temporaryRemoved=!0):(k(),e._temporaryRemoved&&(d.grid.addNode(e),d.placeholder.attr("data-gs-x",i).attr("data-gs-y",l).attr("data-gs-width",c).attr("data-gs-height",f).show(),d.container.append(d.placeholder),e.el=d.placeholder,e._temporaryRemoved=!1));else if("resize"==a.type&&0>i)return;d.grid.canMoveNode(e,i,l,c,f)&&(d.grid.moveNode(e,i,l,c,f),d._updateContainerHeight())},m=function(b,f){d.container.append(d.placeholder);var i=a(this);d.grid.cleanNodes(),d.grid.beginUpdate(e),g=Math.ceil(i.outerWidth()/i.attr("data-gs-width"));var j=Math.ceil(i.outerHeight()/i.attr("data-gs-height"));h=d.container.height()/parseInt(d.container.attr("data-gs-current-height")),d.placeholder.attr("data-gs-x",i.attr("data-gs-x")).attr("data-gs-y",i.attr("data-gs-y")).attr("data-gs-width",i.attr("data-gs-width")).attr("data-gs-height",i.attr("data-gs-height")).show(),e.el=d.placeholder,e._beforeDragX=e.x,e._beforeDragY=e.y,c.resizable("option","minWidth",g*(e.minWidth||1)),c.resizable("option","minHeight",j*(e.minHeight||1)),"resizestart"==b.type&&i.find(".grid-stack-item").trigger("resizestart")},n=function(b,f){var g=!1;d.placeholder.detach();var h=a(this);e.el=h,d.placeholder.hide(),e._isAboutToRemove?(g=!0,c.removeData("_gridstack_node"),c.remove()):(k(),e._temporaryRemoved?(h.attr("data-gs-x",e._beforeDragX).attr("data-gs-y",e._beforeDragY).attr("data-gs-width",e.width).attr("data-gs-height",e.height).removeAttr("style"),e.x=e._beforeDragX,e.y=e._beforeDragY,d.grid.addNode(e)):h.attr("data-gs-x",e.x).attr("data-gs-y",e.y).attr("data-gs-width",e.width).attr("data-gs-height",e.height).removeAttr("style")),d._updateContainerHeight(),d._triggerChangeEvent(g),d.grid.endUpdate();var i=h.find(".grid-stack");i.length&&"resizestop"==b.type&&(i.each(function(b,c){a(c).data("gridstack").onResizeHandler()}),h.find(".grid-stack-item").trigger("resizestop"))};c.draggable(b.extend(this.opts.draggable,{containment:this.opts.isNested?this.container.parent():null,start:m,stop:n,drag:l})).resizable(b.extend(this.opts.resizable,{start:m,stop:n,resize:l})),(e.noMove||this._isOneColumnMode()||this.opts.staticGrid||this.opts.disableDrag)&&c.draggable("disable"),(e.noResize||this._isOneColumnMode()||this.opts.staticGrid||this.opts.disableResize)&&c.resizable("disable"),c.attr("data-gs-locked",e.locked?"yes":null)},i.prototype.setAnimation=function(a){a?this.container.addClass("grid-stack-animate"):this.container.removeClass("grid-stack-animate")},i.prototype.addWidget=function(b,c,d,e,f,g,h,i,j,k,l){return b=a(b),"undefined"!=typeof c&&b.attr("data-gs-x",c),"undefined"!=typeof d&&b.attr("data-gs-y",d),"undefined"!=typeof e&&b.attr("data-gs-width",e),"undefined"!=typeof f&&b.attr("data-gs-height",f),"undefined"!=typeof g&&b.attr("data-gs-auto-position",g?"yes":null),"undefined"!=typeof h&&b.attr("data-gs-min-width",h),"undefined"!=typeof i&&b.attr("data-gs-max-width",i),"undefined"!=typeof j&&b.attr("data-gs-min-height",j),"undefined"!=typeof k&&b.attr("data-gs-max-height",k),"undefined"!=typeof l&&b.attr("data-gs-id",l),this.container.append(b),this._prepareElement(b),this._updateContainerHeight(),this._triggerChangeEvent(!0),b},i.prototype.makeWidget=function(b){return b=a(b),this._prepareElement(b),this._updateContainerHeight(),this._triggerChangeEvent(!0),b},i.prototype.willItFit=function(a,b,c,d,e){var f={x:a,y:b,width:c,height:d,autoPosition:e};return this.grid.canBePlacedWithRespectToHeight(f)},i.prototype.removeWidget=function(b,c){c="undefined"==typeof c?!0:c,b=a(b);var d=b.data("_gridstack_node");
+// For Meteor support: https://github.com/troolee/gridstack.js/pull/272
+d||(d=this.grid.getNodeDataByDOMEl(b)),this.grid.removeNode(d),b.removeData("_gridstack_node"),this._updateContainerHeight(),c&&b.remove(),this._triggerChangeEvent(!0)},i.prototype.removeAll=function(a){b.each(this.grid.nodes,b.bind(function(b){this.removeWidget(b.el,a)},this)),this.grid.nodes=[],this._updateContainerHeight()},i.prototype.destroy=function(b){a(window).off("resize",this.onResizeHandler),this.disable(),"undefined"==typeof b||b?this.container.remove():this.removeAll(!0),f.removeStylesheet(this._stylesId),this.grid&&(this.grid=null)},i.prototype.resizable=function(b,c){var d=this;return b=a(b),b.each(function(b,e){e=a(e);var f=e.data("_gridstack_node");"undefined"!=typeof f&&null!==f&&(f.noResize=!c,f.noResize||d._isOneColumnMode()?e.resizable("disable"):e.resizable("enable"))}),this},i.prototype.movable=function(b,c){var d=this;return b=a(b),b.each(function(b,e){e=a(e);var f=e.data("_gridstack_node");"undefined"!=typeof f&&null!==f&&(f.noMove=!c,f.noMove||d._isOneColumnMode()?(e.draggable("disable"),e.removeClass("ui-draggable-handle")):(e.draggable("enable"),e.addClass("ui-draggable-handle")))}),this},i.prototype.enableMove=function(a,b){this.movable(this.container.children("."+this.opts.itemClass),a),b&&(this.opts.disableDrag=!a)},i.prototype.enableResize=function(a,b){this.resizable(this.container.children("."+this.opts.itemClass),a),b&&(this.opts.disableResize=!a)},i.prototype.disable=function(){this.movable(this.container.children("."+this.opts.itemClass),!1),this.resizable(this.container.children("."+this.opts.itemClass),!1),this.container.trigger("disable")},i.prototype.enable=function(){this.movable(this.container.children("."+this.opts.itemClass),!0),this.resizable(this.container.children("."+this.opts.itemClass),!0),this.container.trigger("enable")},i.prototype.locked=function(b,c){return b=a(b),b.each(function(b,d){d=a(d);var e=d.data("_gridstack_node");"undefined"!=typeof e&&null!==e&&(e.locked=c||!1,d.attr("data-gs-locked",e.locked?"yes":null))}),this},i.prototype.maxHeight=function(b,c){return b=a(b),b.each(function(b,d){d=a(d);var e=d.data("_gridstack_node");"undefined"!=typeof e&&null!==e&&(isNaN(c)||(e.maxHeight=c||!1,d.attr("data-gs-max-height",c)))}),this},i.prototype.minHeight=function(b,c){return b=a(b),b.each(function(b,d){d=a(d);var e=d.data("_gridstack_node");"undefined"!=typeof e&&null!==e&&(isNaN(c)||(e.minHeight=c||!1,d.attr("data-gs-min-height",c)))}),this},i.prototype.maxWidth=function(b,c){return b=a(b),b.each(function(b,d){d=a(d);var e=d.data("_gridstack_node");"undefined"!=typeof e&&null!==e&&(isNaN(c)||(e.maxWidth=c||!1,d.attr("data-gs-max-width",c)))}),this},i.prototype.minWidth=function(b,c){return b=a(b),b.each(function(b,d){d=a(d);var e=d.data("_gridstack_node");"undefined"!=typeof e&&null!==e&&(isNaN(c)||(e.minWidth=c||!1,d.attr("data-gs-min-width",c)))}),this},i.prototype._updateElement=function(b,c){b=a(b).first();var d=b.data("_gridstack_node");if("undefined"!=typeof d&&null!==d){var e=this;e.grid.cleanNodes(),e.grid.beginUpdate(d),c.call(this,b,d),e._updateContainerHeight(),e._triggerChangeEvent(),e.grid.endUpdate()}},i.prototype.resize=function(a,b,c){this._updateElement(a,function(a,d){b=null!==b&&"undefined"!=typeof b?b:d.width,c=null!==c&&"undefined"!=typeof c?c:d.height,this.grid.moveNode(d,d.x,d.y,b,c)})},i.prototype.move=function(a,b,c){this._updateElement(a,function(a,d){b=null!==b&&"undefined"!=typeof b?b:d.x,c=null!==c&&"undefined"!=typeof c?c:d.y,this.grid.moveNode(d,b,c,d.width,d.height)})},i.prototype.update=function(a,b,c,d,e){this._updateElement(a,function(a,f){b=null!==b&&"undefined"!=typeof b?b:f.x,c=null!==c&&"undefined"!=typeof c?c:f.y,d=null!==d&&"undefined"!=typeof d?d:f.width,e=null!==e&&"undefined"!=typeof e?e:f.height,this.grid.moveNode(f,b,c,d,e)})},i.prototype.verticalMargin=function(a,b){if("undefined"==typeof a)return this.opts.verticalMargin;var c=f.parseHeight(a);(this.opts.verticalMarginUnit!==c.unit||this.opts.height!==c.height)&&(this.opts.verticalMarginUnit=c.unit,this.opts.verticalMargin=c.height,b||this._updateStyles())},i.prototype.cellHeight=function(a,b){if("undefined"==typeof a){if(this.opts.cellHeight)return this.opts.cellHeight;var c=this.container.children("."+this.opts.itemClass).first();return Math.ceil(c.outerHeight()/c.attr("data-gs-height"))}var d=f.parseHeight(a);(this.opts.cellHeightUnit!==d.heightUnit||this.opts.height!==d.height)&&(this.opts.cellHeightUnit=d.unit,this.opts.cellHeight=d.height,b||this._updateStyles())},i.prototype.cellWidth=function(){var a=this.container.children("."+this.opts.itemClass).first();return Math.ceil(a.outerWidth()/a.attr("data-gs-width"))},i.prototype.getCellFromPixel=function(a,b){var c="undefined"!=typeof b&&b?this.container.offset():this.container.position(),d=a.left-c.left,e=a.top-c.top,f=Math.floor(this.container.width()/this.opts.width),g=Math.floor(this.container.height()/parseInt(this.container.attr("data-gs-current-height")));return{x:Math.floor(d/f),y:Math.floor(e/g)}},i.prototype.batchUpdate=function(){this.grid.batchUpdate()},i.prototype.commit=function(){this.grid.commit(),this._updateContainerHeight()},i.prototype.isAreaEmpty=function(a,b,c,d){return this.grid.isAreaEmpty(a,b,c,d)},i.prototype.setStatic=function(a){this.opts.staticGrid=a===!0,this.enableMove(!a),this.enableResize(!a),this._setStaticClass()},i.prototype._setStaticClass=function(){var a="grid-stack-static";this.opts.staticGrid===!0?this.container.addClass(a):this.container.removeClass(a)},i.prototype._updateNodeWidths=function(a,b){this.grid._sortNodes(),this.grid.batchUpdate();for(var c={},d=0;d
+
+**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*
+
+- [Options](#options)
+- [Grid attributes](#grid-attributes)
+- [Item attributes](#item-attributes)
+- [Events](#events)
+ - [onchange(items)](#onchangeitems)
+ - [ondragstart(event, ui)](#ondragstartevent-ui)
+ - [ondragstop(event, ui)](#ondragstopevent-ui)
+ - [onresizestart(event, ui)](#onresizestartevent-ui)
+ - [onresizestop(event, ui)](#onresizestopevent-ui)
+ - [disable(event)](#disableevent)
+ - [enable(event)](#enableevent)
+- [API](#api)
+ - [addWidget(el[, x, y, width, height, autoPosition, minWidth, maxWidth, minHeight, maxHeight, id])](#addwidgetel-x-y-width-height-autoposition-minwidth-maxwidth-minheight-maxheight-id)
+ - [batchUpdate()](#batchupdate)
+ - [cellHeight()](#cellheight)
+ - [cellHeight(val)](#cellheightval)
+ - [cellWidth()](#cellwidth)
+ - [commit()](#commit)
+ - [destroy([detachGrid])](#destroydetachgrid)
+ - [disable()](#disable)
+ - [enable()](#enable)
+ - [enableMove(doEnable, includeNewWidgets)](#enablemovedoenable-includenewwidgets)
+ - [enableResize(doEnable, includeNewWidgets)](#enableresizedoenable-includenewwidgets)
+ - [getCellFromPixel(position[, useOffset])](#getcellfrompixelposition-useoffset)
+ - [isAreaEmpty(x, y, width, height)](#isareaemptyx-y-width-height)
+ - [locked(el, val)](#lockedel-val)
+ - [makeWidget(el)](#makewidgetel)
+ - [maxHeight(el, val)](#maxheightel-val)
+ - [minHeight(el, val)](#minheightel-val)
+ - [maxWidth(el, val)](#maxwidthel-val)
+ - [minWidth(el, val)](#minwidthel-val)
+ - [movable(el, val)](#movableel-val)
+ - [move(el, x, y)](#moveel-x-y)
+ - [removeWidget(el[, detachNode])](#removewidgetel-detachnode)
+ - [removeAll([detachNode])](#removealldetachnode)
+ - [resize(el, width, height)](#resizeel-width-height)
+ - [resizable(el, val)](#resizableel-val)
+ - [setAnimation(doAnimate)](#setanimationdoanimate)
+ - [setGridWidth(gridWidth)](#setgridwidthgridwidth)
+ - [setStatic(staticValue)](#setstaticstaticvalue)
+ - [update(el, x, y, width, height)](#updateel-x-y-width-height)
+ - [willItFit(x, y, width, height, autoPosition)](#willitfitx-y-width-height-autoposition)
+- [Utils](#utils)
+ - [GridStackUI.Utils.sort(nodes[, dir[, width]])](#gridstackuiutilssortnodes-dir-width)
+
+
+
+## Options
+
+- `alwaysShowResizeHandle` - if `true` the resizing handles are shown even if the user is not hovering over the widget
+ (default: `false`)
+- `animate` - turns animation on (default: `false`)
+- `auto` - if `false` gridstack will not initialize existing items (default: `true`)
+- `cellHeight` - one cell height (default: `60`). Can be:
+ - an integer (px)
+ - a string (ex: '10em', '100px', '10rem')
+ - 0 or null, in which case the library will not generate styles for rows. Everything must be defined in CSS files.
+ - `'auto'` - height will be calculated from cell width.
+- `disableDrag` - disallows dragging of widgets (default: `false`).
+- `disableResize` - disallows resizing of widgets (default: `false`).
+- `draggable` - allows to override jQuery UI draggable options. (default: `{handle: '.grid-stack-item-content', scroll: true, appendTo: 'body'}`)
+- `handle` - draggable handle selector (default: `'.grid-stack-item-content'`)
+- `handleClass` - draggable handle class (e.g. `'grid-stack-item-content'`). If set `handle` is ignored (default: `null`)
+- `height` - maximum rows amount. Default is `0` which means no maximum rows
+- `float` - enable floating widgets (default: `false`) See [example](http://troolee.github.io/gridstack.js/demo/float.html)
+- `itemClass` - widget class (default: `'grid-stack-item'`)
+- `minWidth` - minimal width. If window width is less, grid will be shown in one-column mode. You need also update your css file (`@media (max-width: 768px) {...}`) with corresponding value (default: `768`)
+- `placeholderClass` - class for placeholder (default: `'grid-stack-placeholder'`)
+- `placeholderText` - placeholder default content (default: `''`)
+- `resizable` - allows to override jQuery UI resizable options. (default: `{autoHide: true, handles: 'se'}`)
+- `removable` - if `true` widgets could be removed by dragging outside of the grid (default: `false`)
+- `removeTimeout` - time in milliseconds before widget is being removed while dragging outside of the grid. (default: `2000`)
+- `rtl` - if `true` turns grid to RTL. Possible values are `true`, `false`, `'auto'` (default: `'auto'`) See [example](http://troolee.github.io/gridstack.js/demo/rtl.html)
+- `staticGrid` - makes grid static (default `false`). If true widgets are not movable/resizable. You don't even need jQueryUI draggable/resizable. A CSS class `grid-stack-static` is also added to the container.
+- `verticalMargin` - vertical gap size (default: `20`). Can be:
+ - an integer (px)
+ - a string (ex: '2em', '20px', '2rem')
+- `width` - amount of columns (default: `12`)
+
+## Grid attributes
+
+- `data-gs-animate` - turns animation on
+- `data-gs-width` - amount of columns
+- `data-gs-height` - maximum rows amount. Default is `0` which means no maximum rows.
+- `data-gs-current-height` - current rows amount. Set by the library only. Can be used by the CSS rules.
+
+## Item attributes
+
+- `data-gs-x`, `data-gs-y` - element position
+- `data-gs-width`, `data-gs-height` - element size
+- `data-gs-max-width`, `data-gs-min-width`, `data-gs-max-height`, `data-gs-min-height` - element constraints
+- `data-gs-no-resize` - disable element resizing
+- `data-gs-no-move` - disable element moving
+- `data-gs-auto-position` - tells to ignore `data-gs-x` and `data-gs-y` attributes and to place element to the first
+ available position
+- `data-gs-locked` - the widget will be locked. It means another widget wouldn't be able to move it during dragging or resizing.
+The widget can still be dragged or resized. You need to add `data-gs-no-resize` and `data-gs-no-move` attributes
+to completely lock the widget.
+
+## Events
+
+### onchange(items)
+
+Occurs when adding/removing widgets or existing widgets change their position/size
+
+```javascript
+var serializeWidgetMap = function (items) {
+ console.log(items);
+};
+
+$('.grid-stack').on('change', function (e, items) {
+ serializeWidgetMap(items);
+});
+```
+
+### ondragstart(event, ui)
+
+```javascript
+$('.grid-stack').on('dragstart', function (event, ui) {
+ var grid = this;
+ var element = event.target;
+});
+```
+
+### ondragstop(event, ui)
+
+```javascript
+$('.grid-stack').on('dragstop', function (event, ui) {
+ var grid = this;
+ var element = event.target;
+});
+```
+
+### onresizestart(event, ui)
+
+```javascript
+$('.grid-stack').on('resizestart', function (event, ui) {
+ var grid = this;
+ var element = event.target;
+});
+```
+
+### onresizestop(event, ui)
+
+```javascript
+$('.grid-stack').on('resizestop', function (event, ui) {
+ var grid = this;
+ var element = event.target;
+});
+```
+
+### disable(event)
+
+```javascript
+$('.grid-stack').on('disable', function(event) {
+ var grid = event.target;
+});
+```
+
+### enable(event)
+
+```javascript
+$('.grid-stack').on('enable', function(event) {
+ var grid = event.target;
+});
+```
+
+## API
+
+### addWidget(el[, x, y, width, height, autoPosition, minWidth, maxWidth, minHeight, maxHeight, id])
+
+Creates new widget and returns it.
+
+Parameters:
+
+- `el` - widget to add
+- `x`, `y`, `width`, `height` - widget position/dimensions (optional)
+- `autoPosition` - if `true` then `x`, `y` parameters will be ignored and widget will be places on the first available
+position (optional)
+- `minWidth` minimum width allowed during resize/creation (optional)
+- `maxWidth` maximum width allowed during resize/creation (optional)
+- `minHeight` minimum height allowed during resize/creation (optional)
+- `maxHeight` maximum height allowed during resize/creation (optional)
+- `id` value for `data-gs-id` (optional)
+
+Widget will be always placed even if result height is more than actual grid height. You need to use `willItFit` method
+before calling `addWidget` for additional check.
+
+```javascript
+$('.grid-stack').gridstack();
+
+var grid = $('.grid-stack').data('gridstack');
+grid.addWidget(el, 0, 0, 3, 2, true);
+```
+
+### batchUpdate()
+
+Initailizes batch updates. You will see no changes until `commit` method is called.
+
+### cellHeight()
+
+Gets current cell height.
+
+### cellHeight(val)
+
+Update current cell height. This method rebuilds an internal CSS stylesheet. Note: You can expect performance issues if
+call this method too often.
+
+```javascript
+grid.cellHeight(grid.cellWidth() * 1.2);
+```
+
+### cellWidth()
+
+Gets current cell width.
+
+### commit()
+
+Finishes batch updates. Updates DOM nodes. You must call it after `batchUpdate`.
+
+### destroy([detachGrid])
+
+Destroys a grid instance.
+
+Parameters:
+
+- `detachGrid` - if `false` nodes and grid will not be removed from the DOM (Optional. Default `true`).
+
+### disable()
+
+Disables widgets moving/resizing. This is a shortcut for:
+
+```javascript
+grid.movable('.grid-stack-item', false);
+grid.resizable('.grid-stack-item', false);
+```
+
+### enable()
+
+Enables widgets moving/resizing. This is a shortcut for:
+
+```javascript
+grid.movable('.grid-stack-item', true);
+grid.resizable('.grid-stack-item', true);
+```
+
+### enableMove(doEnable, includeNewWidgets)
+
+Enables/disables widget moving. `includeNewWidgets` will force new widgets to be draggable as per `doEnable`'s value by changing the `disableDrag` grid option. This is a shortcut for:
+
+```javascript
+grid.movable(this.container.children('.' + this.opts.itemClass), doEnable);
+```
+
+### enableResize(doEnable, includeNewWidgets)
+
+Enables/disables widget resizing. `includeNewWidgets` will force new widgets to be resizable as per `doEnable`'s value by changing the `disableResize` grid option. This is a shortcut for:
+
+```javascript
+grid.resizable(this.container.children('.' + this.opts.itemClass), doEnable);
+```
+
+### getCellFromPixel(position[, useOffset])
+
+Get the position of the cell under a pixel on screen.
+
+Parameters :
+
+- `position` - the position of the pixel to resolve in absolute coordinates, as an object with `top` and `left` properties
+- `useOffset` - if `true`, value will be based on offset vs position (Optional. Default `false`). Useful when grid is within `position: relative` element.
+
+Returns an object with properties `x` and `y` i.e. the column and row in the grid.
+
+### isAreaEmpty(x, y, width, height)
+
+Checks if specified area is empty.
+
+### locked(el, val)
+
+Locks/unlocks widget.
+
+- `el` - widget to modify.
+- `val` - if `true` widget will be locked.
+
+### makeWidget(el)
+
+If you add elements to your gridstack container by hand, you have to tell gridstack afterwards to make them widgets. If you want gridstack to add the elements for you, use `addWidget` instead.
+Makes the given element a widget and returns it.
+
+Parameters:
+
+- `el` - element to convert to a widget
+
+```javascript
+$('.grid-stack').gridstack();
+
+$('.grid-stack').append('')
+var grid = $('.grid-stack').data('gridstack');
+grid.makeWidget('gsi-1');
+```
+
+### maxHeight(el, val)
+
+Set the `maxHeight` for a widget.
+
+- `el` - widget to modify.
+- `val` - A numeric value of the number of rows
+
+### minHeight(el, val)
+
+Set the `minHeight` for a widget.
+
+- `el` - widget to modify.
+- `val` - A numeric value of the number of rows
+
+### maxWidth(el, val)
+
+Set the `maxWidth` for a widget.
+
+- `el` - widget to modify.
+- `val` - A numeric value of the number of columns
+
+### minWidth(el, val)
+
+Set the `minWidth` for a widget.
+
+- `el` - widget to modify.
+- `val` - A numeric value of the number of columns
+
+### movable(el, val)
+
+Enables/Disables moving.
+
+- `el` - widget to modify
+- `val` - if `true` widget will be draggable.
+
+### move(el, x, y)
+
+Changes widget position
+
+Parameters:
+
+- `el` - widget to move
+- `x`, `y` - new position. If value is `null` or `undefined` it will be ignored.
+
+### removeWidget(el[, detachNode])
+
+Removes widget from the grid.
+
+Parameters:
+
+- `el` - widget to remove.
+- `detachNode` - if `false` node won't be removed from the DOM (Optional. Default `true`).
+
+### removeAll([detachNode])
+
+Removes all widgets from the grid.
+
+Parameters:
+
+- `detachNode` - if `false` nodes won't be removed from the DOM (Optional. Default `true`).
+
+### resize(el, width, height)
+
+Changes widget size
+
+Parameters:
+
+- `el` - widget to resize
+- `width`, `height` - new dimensions. If value is `null` or `undefined` it will be ignored.
+
+### resizable(el, val)
+
+Enables/Disables resizing.
+
+- `el` - widget to modify
+- `val` - if `true` widget will be resizable.
+
+### setAnimation(doAnimate)
+
+Toggle the grid animation state. Toggles the `grid-stack-animate` class.
+
+- `doAnimate` - if `true` the grid will animate.
+
+### setGridWidth(gridWidth)
+
+(Experimental) Modify number of columns in the grid. Will attempt to update existing widgets to conform to new number of columns. Requires `gridstack-extra.css` or `gridstack-extra.min.css`.
+
+- `gridWidth` - Integer between 1 and 12.
+
+### setStatic(staticValue)
+
+Toggle the grid static state. Also toggle the `grid-stack-static` class.
+
+- `staticValue` - if `true` the grid becomes static.
+
+### update(el, x, y, width, height)
+
+Parameters:
+
+- `el` - widget to move
+- `x`, `y` - new position. If value is `null` or `undefined` it will be ignored.
+- `width`, `height` - new dimensions. If value is `null` or `undefined` it will be ignored.
+
+Updates widget position/size.
+
+### willItFit(x, y, width, height, autoPosition)
+
+Returns `true` if the `height` of the grid will be less the vertical constraint. Always returns `true` if grid doesn't
+have `height` constraint.
+
+```javascript
+if (grid.willItFit(newNode.x, newNode.y, newNode.width, newNode.height, true)) {
+ grid.addWidget(newNode.el, newNode.x, newNode.y, newNode.width, newNode.height, true);
+}
+else {
+ alert('Not enough free space to place the widget');
+}
+```
+
+
+## Utils
+
+### GridStackUI.Utils.sort(nodes[, dir[, width]])
+
+Sorts array of nodes
+
+- `nodes` - array to sort
+- `dir` - `1` for asc, `-1` for desc (optional)
+- `width` - width of the grid. If `undefined` the width will be calculated automatically (optional).
diff --git a/package.json b/package.json
index 2e6c4a5..69ccdc6 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,7 @@
"grunt": "^0.4.5",
"grunt-contrib-copy": "^0.8.2",
"grunt-contrib-cssmin": "^0.14.0",
+ "grunt-contrib-jshint": "^1.0.0",
"grunt-contrib-uglify": "^0.10.1",
"grunt-doctoc": "^0.1.1",
"grunt-sass": "^1.1.0",
@@ -34,5 +35,7 @@
"karma-phantomjs-launcher": "^1.0.0",
"phantomjs": "^2.1.3",
"phantomjs-prebuilt": "^2.1.4"
+ "grunt-contrib-watch": "^0.6.1",
+ "grunt-jscs": "^2.7.0"
}
}
diff --git a/src/gridstack.js b/src/gridstack.js
index c4d140a..9880fc0 100644
--- a/src/gridstack.js
+++ b/src/gridstack.js
@@ -22,8 +22,8 @@
var obsolete = function(f, oldName, newName) {
var wrapper = function() {
- console.warn('gridstack.js: Function `' + oldName + '` is deprecated as of v0.2.5 and has been replaced with `' +
- newName + '`. It will be **completely** removed in v1.0.');
+ console.warn('gridstack.js: Function `' + oldName + '` is deprecated as of v0.2.5 and has been replaced ' +
+ 'with `' + newName + '`. It will be **completely** removed in v1.0.');
return f.apply(this, arguments);
};
wrapper.prototype = f.prototype;
@@ -50,7 +50,7 @@
createStylesheet: function(id) {
var style = document.createElement('style');
style.setAttribute('type', 'text/css');
- style.setAttribute('data-gs-id', id);
+ style.setAttribute('data-gs-style-id', id);
if (style.styleSheet) {
style.styleSheet.cssText = '';
} else {
@@ -61,7 +61,7 @@
},
removeStylesheet: function(id) {
- $('STYLE[data-gs-id=' + id + ']').remove();
+ $('STYLE[data-gs-style-id=' + id + ']').remove();
},
insertCSSRule: function(sheet, selector, rules, index) {
@@ -98,6 +98,20 @@
_isAddNodeIntercepted: function(n) {
return Utils.isIntercepted({x: this.x, y: this.y, width: this.node.width, height: this.node.height}, n);
+ },
+
+ parseHeight: function(val) {
+ var height = val;
+ var heightUnit = 'px';
+ if (height && _.isString(height)) {
+ var match = height.match(/^([0-9]*\.[0-9]+|[0-9]+)(px|em|rem|vh|vw)?$/);
+ if (!match) {
+ throw new Error('Invalid height');
+ }
+ heightUnit = match[2];
+ height = parseFloat(match[1]);
+ }
+ return {height: height, unit: heightUnit};
}
};
@@ -131,14 +145,19 @@
};
GridStackEngine.prototype.commit = function() {
- this._updateCounter = 0;
- if (this._updateCounter === 0) {
+ if (this._updateCounter !== 0) {
+ this._updateCounter = 0;
this.float = this._float;
this._packNodes();
this._notify();
}
};
+ // For Meteor support: https://github.com/troolee/gridstack.js/pull/272
+ GridStackEngine.prototype.getNodeDataByDOMEl = function(el) {
+ return _.find(this.nodes, function(n) { return el.get(0) === n.el.get(0); });
+ };
+
GridStackEngine.prototype._fixCollisions = function(node) {
var self = this;
this._sortNodes(-1);
@@ -269,6 +288,9 @@
};
GridStackEngine.prototype.cleanNodes = function() {
+ if (this._updateCounter) {
+ return;
+ }
_.each(this.nodes, function(n) {n._dirty = false; });
};
@@ -427,7 +449,7 @@
var GridStack = function(el, opts) {
var self = this;
- var oneColumnMode;
+ var oneColumnMode, isAutoCellHeight;
opts = opts || {};
@@ -509,11 +531,30 @@
'.grid-stack-item-content',
scroll: false,
appendTo: 'body'
- })
+ }),
+ disableDrag: opts.disableDrag || false,
+ disableResize: opts.disableResize || false,
+ rtl: 'auto',
+ removable: false,
+ removeTimeout: 2000
});
+
+ if (this.opts.rtl === 'auto') {
+ this.opts.rtl = this.container.css('direction') === 'rtl';
+ }
+
+ if (this.opts.rtl) {
+ this.container.addClass('grid-stack-rtl');
+ }
+
this.opts.isNested = isNested;
- this.cellHeight(this.opts.cellHeight, true);
+ isAutoCellHeight = this.opts.cellHeight === 'auto';
+ if (isAutoCellHeight) {
+ self.cellHeight(self.cellWidth(), true);
+ } else {
+ this.cellHeight(this.opts.cellHeight, true);
+ }
this.verticalMargin(this.opts.verticalMargin, true);
this.container.addClass(this.opts._class);
@@ -567,7 +608,15 @@
this._updateContainerHeight();
+ this._updateHeightsOnResize = _.throttle(function() {
+ self.cellHeight(self.cellWidth(), false);
+ }, 100);
+
this.onResizeHandler = function() {
+ if (isAutoCellHeight) {
+ self._updateHeightsOnResize();
+ }
+
if (self._isOneColumnMode()) {
if (oneColumnMode) {
return;
@@ -582,10 +631,10 @@
if (self.opts.staticGrid) {
return;
}
- if (!node.noMove) {
+ if (node.noMove || self.opts.disableDrag) {
node.el.draggable('disable');
}
- if (!node.noResize) {
+ if (node.noResize || self.opts.disableResize) {
node.el.resizable('disable');
}
});
@@ -601,10 +650,10 @@
}
_.each(self.grid.nodes, function(node) {
- if (!node.noMove) {
+ if (!node.noMove && !self.opts.disableDrag) {
node.el.draggable('enable');
}
- if (!node.noResize) {
+ if (!node.noResize && !self.opts.disableResize) {
node.el.resizable('enable');
}
});
@@ -631,21 +680,18 @@
};
GridStack.prototype._initStyles = function() {
- if (!this.opts.cellHeight) { //that will be handled by CSS
- return ;
- }
if (this._stylesId) {
- $('[data-gs-id="' + this._stylesId + '"]').remove();
+ Utils.removeStylesheet(this._stylesId);
}
this._stylesId = 'gridstack-style-' + (Math.random() * 100000).toFixed();
this._styles = Utils.createStylesheet(this._stylesId);
- if (this._styles != null) {
+ if (this._styles !== null) {
this._styles._max = 0;
}
};
GridStack.prototype._updateStyles = function(maxHeight) {
- if (this._styles === null) {
+ if (this._styles === null || typeof this._styles === 'undefined') {
return;
}
@@ -658,7 +704,7 @@
this._initStyles();
this._updateContainerHeight();
}
- if (!this.opts.cellHeight) { //the rest will be handled by CSS
+ if (!this.opts.cellHeight) { // The rest will be handled by CSS
return ;
}
if (this._styles._max !== 0 && maxHeight <= this._styles._max) {
@@ -667,12 +713,14 @@
if (!this.opts.verticalMargin || this.opts.cellHeightUnit === this.opts.verticalMarginUnit) {
getHeight = function(nbRows, nbMargins) {
- return (self.opts.cellHeight * nbRows + self.opts.verticalMargin * nbMargins) + self.opts.cellHeightUnit;
+ return (self.opts.cellHeight * nbRows + self.opts.verticalMargin * nbMargins) +
+ self.opts.cellHeightUnit;
};
} else {
getHeight = function(nbRows, nbMargins) {
if (!nbRows || !nbMargins) {
- return (self.opts.cellHeight * nbRows + self.opts.verticalMargin * nbMargins) + self.opts.cellHeightUnit;
+ return (self.opts.cellHeight * nbRows + self.opts.verticalMargin * nbMargins) +
+ self.opts.cellHeightUnit;
}
return 'calc(' + ((self.opts.cellHeight * nbRows) + self.opts.cellHeightUnit) + ' + ' +
((self.opts.verticalMargin * nbMargins) + self.opts.verticalMarginUnit) + ')';
@@ -753,27 +801,80 @@
noResize: Utils.toBool(el.attr('data-gs-no-resize')),
noMove: Utils.toBool(el.attr('data-gs-no-move')),
locked: Utils.toBool(el.attr('data-gs-locked')),
- el: el
+ el: el,
+ id: el.attr('data-gs-id')
});
el.data('_gridstack_node', node);
- if (self.opts.staticGrid) {
- return;
- }
-
var cellWidth;
var cellHeight;
+ var removeTimeout;
+
+ var setupRemovingTimeout = function() {
+ if (removeTimeout || !self.opts.removable) {
+ return;
+ }
+ removeTimeout = setTimeout(function() {
+ el.addClass('grid-stack-item-removing');
+ node._isAboutToRemove = true;
+ }, self.opts.removeTimeout);
+ };
+ var clearRemovingTimeout = function() {
+ if (!removeTimeout) {
+ return;
+ }
+ clearTimeout(removeTimeout);
+ removeTimeout = null;
+ el.removeClass('grid-stack-item-removing');
+ node._isAboutToRemove = false;
+ };
var dragOrResize = function(event, ui) {
var x = Math.round(ui.position.left / cellWidth);
var y = Math.floor((ui.position.top + cellHeight / 2) / cellHeight);
var width;
var height;
+
if (event.type != 'drag') {
width = Math.round(ui.size.width / cellWidth);
height = Math.round(ui.size.height / cellHeight);
}
+ if (event.type == 'drag') {
+ if (x < 0 || x >= self.grid.width || y < 0) {
+ setupRemovingTimeout();
+
+ x = node._beforeDragX;
+ y = node._beforeDragY;
+
+ self.placeholder.detach();
+ self.placeholder.hide();
+ self.grid.removeNode(node);
+ self._updateContainerHeight();
+
+ node._temporaryRemoved = true;
+ } else {
+ clearRemovingTimeout();
+
+ if (node._temporaryRemoved) {
+ self.grid.addNode(node);
+ self.placeholder
+ .attr('data-gs-x', x)
+ .attr('data-gs-y', y)
+ .attr('data-gs-width', width)
+ .attr('data-gs-height', height)
+ .show();
+ self.container.append(self.placeholder);
+ node.el = self.placeholder;
+ node._temporaryRemoved = false;
+ }
+ }
+ } else if (event.type == 'resize') {
+ if (x < 0) {
+ return;
+ }
+ }
+
if (!self.grid.canMoveNode(node, x, y, width, height)) {
return;
}
@@ -796,6 +897,8 @@
.attr('data-gs-height', o.attr('data-gs-height'))
.show();
node.el = self.placeholder;
+ node._beforeDragX = node.x;
+ node._beforeDragY = node.y;
el.resizable('option', 'minWidth', cellWidth * (node.minWidth || 1));
el.resizable('option', 'minHeight', strictCellHeight * (node.minHeight || 1));
@@ -806,18 +909,39 @@
};
var onEndMoving = function(event, ui) {
+ var forceNotify = false;
self.placeholder.detach();
var o = $(this);
node.el = o;
self.placeholder.hide();
- o
- .attr('data-gs-x', node.x)
- .attr('data-gs-y', node.y)
- .attr('data-gs-width', node.width)
- .attr('data-gs-height', node.height)
- .removeAttr('style');
+
+ if (node._isAboutToRemove) {
+ forceNotify = true;
+ el.removeData('_gridstack_node');
+ el.remove();
+ } else {
+ clearRemovingTimeout();
+ if (!node._temporaryRemoved) {
+ o
+ .attr('data-gs-x', node.x)
+ .attr('data-gs-y', node.y)
+ .attr('data-gs-width', node.width)
+ .attr('data-gs-height', node.height)
+ .removeAttr('style');
+ } else {
+ o
+ .attr('data-gs-x', node._beforeDragX)
+ .attr('data-gs-y', node._beforeDragY)
+ .attr('data-gs-width', node.width)
+ .attr('data-gs-height', node.height)
+ .removeAttr('style');
+ node.x = node._beforeDragX;
+ node.y = node._beforeDragY;
+ self.grid.addNode(node);
+ }
+ }
self._updateContainerHeight();
- self._triggerChangeEvent();
+ self._triggerChangeEvent(forceNotify);
self.grid.endUpdate();
@@ -843,11 +967,11 @@
resize: dragOrResize
}));
- if (node.noMove || this._isOneColumnMode()) {
+ if (node.noMove || this._isOneColumnMode() || this.opts.staticGrid || this.opts.disableDrag) {
el.draggable('disable');
}
- if (node.noResize || this._isOneColumnMode()) {
+ if (node.noResize || this._isOneColumnMode() || this.opts.staticGrid || this.opts.disableResize) {
el.resizable('disable');
}
@@ -862,13 +986,19 @@
}
};
- GridStack.prototype.addWidget = function(el, x, y, width, height, autoPosition) {
+ GridStack.prototype.addWidget = function(el, x, y, width, height, autoPosition, minWidth, maxWidth,
+ minHeight, maxHeight, id) {
el = $(el);
if (typeof x != 'undefined') { el.attr('data-gs-x', x); }
if (typeof y != 'undefined') { el.attr('data-gs-y', y); }
if (typeof width != 'undefined') { el.attr('data-gs-width', width); }
if (typeof height != 'undefined') { el.attr('data-gs-height', height); }
if (typeof autoPosition != 'undefined') { el.attr('data-gs-auto-position', autoPosition ? 'yes' : null); }
+ if (typeof minWidth != 'undefined') { el.attr('data-gs-min-width', minWidth); }
+ if (typeof maxWidth != 'undefined') { el.attr('data-gs-max-width', maxWidth); }
+ if (typeof minHeight != 'undefined') { el.attr('data-gs-min-height', minHeight); }
+ if (typeof maxHeight != 'undefined') { el.attr('data-gs-max-height', maxHeight); }
+ if (typeof id != 'undefined') { el.attr('data-gs-id', id); }
this.container.append(el);
this._prepareElement(el);
this._updateContainerHeight();
@@ -895,6 +1025,12 @@
detachNode = typeof detachNode === 'undefined' ? true : detachNode;
el = $(el);
var node = el.data('_gridstack_node');
+
+ // For Meteor support: https://github.com/troolee/gridstack.js/pull/272
+ if (!node) {
+ node = this.grid.getNodeDataByDOMEl(el);
+ }
+
this.grid.removeNode(node);
el.removeData('_gridstack_node');
this._updateContainerHeight();
@@ -912,10 +1048,14 @@
this._updateContainerHeight();
};
- GridStack.prototype.destroy = function() {
+ GridStack.prototype.destroy = function(detachGrid) {
$(window).off('resize', this.onResizeHandler);
this.disable();
- this.container.remove();
+ if (typeof detachGrid != 'undefined' && !detachGrid) {
+ this.removeAll(true);
+ } else {
+ this.container.remove();
+ }
Utils.removeStylesheet(this._stylesId);
if (this.grid) {
this.grid = null;
@@ -964,6 +1104,20 @@
return this;
};
+ GridStack.prototype.enableMove = function(doEnable, includeNewWidgets) {
+ this.movable(this.container.children('.' + this.opts.itemClass), doEnable);
+ if (includeNewWidgets) {
+ this.opts.disableDrag = !doEnable;
+ }
+ };
+
+ GridStack.prototype.enableResize = function(doEnable, includeNewWidgets) {
+ this.resizable(this.container.children('.' + this.opts.itemClass), doEnable);
+ if (includeNewWidgets) {
+ this.opts.disableResize = !doEnable;
+ }
+ };
+
GridStack.prototype.disable = function() {
this.movable(this.container.children('.' + this.opts.itemClass), false);
this.resizable(this.container.children('.' + this.opts.itemClass), false);
@@ -996,7 +1150,7 @@
el.each(function(index, el) {
el = $(el);
var node = el.data('_gridstack_node');
- if (typeof node == 'undefined' || node == null) {
+ if (typeof node === 'undefined' || node === null) {
return;
}
@@ -1013,7 +1167,7 @@
el.each(function(index, el) {
el = $(el);
var node = el.data('_gridstack_node');
- if (typeof node == 'undefined' || node == null) {
+ if (typeof node === 'undefined' || node === null) {
return;
}
@@ -1030,7 +1184,7 @@
el.each(function(index, el) {
el = $(el);
var node = el.data('_gridstack_node');
- if (typeof node == 'undefined' || node == null) {
+ if (typeof node === 'undefined' || node === null) {
return;
}
@@ -1047,7 +1201,7 @@
el.each(function(index, el) {
el = $(el);
var node = el.data('_gridstack_node');
- if (typeof node == 'undefined' || node == null) {
+ if (typeof node === 'undefined' || node === null) {
return;
}
@@ -1108,26 +1262,12 @@
});
};
- function parseHeight(val) {
- var height = val;
- var heightUnit = 'px';
- if (height && _.isString(height)) {
- var match = height.match(/^([0-9]+)(px|em|rem)?$/);
- if (!match) {
- throw new Error('Invalid height');
- }
- heightUnit = match[2];
- height = parseInt(match[1]);
- }
- return {height: height, unit: heightUnit};
- }
-
GridStack.prototype.verticalMargin = function(val, noUpdate) {
if (typeof val == 'undefined') {
return this.opts.verticalMargin;
}
- var heightData = parseHeight(val);
+ var heightData = Utils.parseHeight(val);
if (this.opts.verticalMarginUnit === heightData.unit && this.opts.height === heightData.height) {
return ;
@@ -1144,13 +1284,11 @@
if (typeof val == 'undefined') {
if (this.opts.cellHeight) {
return this.opts.cellHeight;
- } else {
- var o = this.container.children('.' + this.opts.itemClass).first();
- return Math.ceil(o.outerHeight() / o.attr('data-gs-height'));
}
-
+ var o = this.container.children('.' + this.opts.itemClass).first();
+ return Math.ceil(o.outerHeight() / o.attr('data-gs-height'));
}
- var heightData = parseHeight(val);
+ var heightData = Utils.parseHeight(val);
if (this.opts.cellHeightUnit === heightData.heightUnit && this.opts.height === heightData.height) {
return ;
@@ -1169,8 +1307,9 @@
return Math.ceil(o.outerWidth() / o.attr('data-gs-width'));
};
- GridStack.prototype.getCellFromPixel = function(position) {
- var containerPos = this.container.position();
+ GridStack.prototype.getCellFromPixel = function(position, useOffset) {
+ var containerPos = (typeof useOffset != 'undefined' && useOffset) ?
+ this.container.offset() : this.container.position();
var relativeLeft = position.left - containerPos.left;
var relativeTop = position.top - containerPos.top;
@@ -1195,6 +1334,8 @@
GridStack.prototype.setStatic = function(staticValue) {
this.opts.staticGrid = (staticValue === true);
+ this.enableMove(!staticValue);
+ this.enableResize(!staticValue);
this._setStaticClass();
};
@@ -1208,6 +1349,25 @@
}
};
+ GridStack.prototype._updateNodeWidths = function(oldWidth, newWidth) {
+ this.grid._sortNodes();
+ this.grid.batchUpdate();
+ var node = {};
+ for (var i = 0; i < this.grid.nodes.length; i++) {
+ node = this.grid.nodes[i];
+ this.update(node.el, Math.round(node.x * newWidth / oldWidth), undefined,
+ Math.round(node.width * newWidth / oldWidth), undefined);
+ }
+ this.grid.commit();
+ };
+
+ GridStack.prototype.setGridWidth = function(gridWidth) {
+ this.container.removeClass('grid-stack-' + this.opts.width);
+ this._updateNodeWidths(this.opts.width, gridWidth);
+ this.opts.width = gridWidth;
+ this.container.addClass('grid-stack-' + gridWidth);
+ };
+
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
GridStackEngine.prototype.batch_update = obsolete(GridStackEngine.prototype.batchUpdate);
GridStackEngine.prototype._fix_collisions = obsolete(GridStackEngine.prototype._fixCollisions,
diff --git a/src/gridstack.scss b/src/gridstack.scss
index 46fa37a..cb5f854 100644
--- a/src/gridstack.scss
+++ b/src/gridstack.scss
@@ -16,6 +16,14 @@ $animation_speed: .3s !default;
.grid-stack {
position: relative;
+ &.grid-stack-rtl {
+ direction: ltr;
+
+ > .grid-stack-item {
+ direction: rtl;
+ }
+ }
+
.grid-stack-placeholder > .placeholder-content {
border: 1px dashed lightgray;
margin: 0;
@@ -71,26 +79,17 @@ $animation_speed: .3s !default;
> .ui-resizable-se,
> .ui-resizable-sw {
- text-align: right;
- color: gray;
-
- padding: 2px 3px 0 0;
- margin: 0;
-
- font: normal normal normal 10px/1 FontAwesome;
- font-size: inherit;
- text-rendering: auto;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-
- &::before { content: "\f065"; }
+ background-image: url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDUxMS42MjYgNTExLjYyNyIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTExLjYyNiA1MTEuNjI3OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTMyOC45MDYsNDAxLjk5NGgtMzYuNTUzVjEwOS42MzZoMzYuNTUzYzQuOTQ4LDAsOS4yMzYtMS44MDksMTIuODQ3LTUuNDI2YzMuNjEzLTMuNjE1LDUuNDIxLTcuODk4LDUuNDIxLTEyLjg0NSAgIGMwLTQuOTQ5LTEuODAxLTkuMjMxLTUuNDI4LTEyLjg1MWwtNzMuMDg3LTczLjA5QzI2NS4wNDQsMS44MDksMjYwLjc2LDAsMjU1LjgxMywwYy00Ljk0OCwwLTkuMjI5LDEuODA5LTEyLjg0Nyw1LjQyNCAgIGwtNzMuMDg4LDczLjA5Yy0zLjYxOCwzLjYxOS01LjQyNCw3LjkwMi01LjQyNCwxMi44NTFjMCw0Ljk0NiwxLjgwNyw5LjIyOSw1LjQyNCwxMi44NDVjMy42MTksMy42MTcsNy45MDEsNS40MjYsMTIuODUsNS40MjYgICBoMzYuNTQ1djI5Mi4zNThoLTM2LjU0MmMtNC45NTIsMC05LjIzNSwxLjgwOC0xMi44NSw1LjQyMWMtMy42MTcsMy42MjEtNS40MjQsNy45MDUtNS40MjQsMTIuODU0ICAgYzAsNC45NDUsMS44MDcsOS4yMjcsNS40MjQsMTIuODQ3bDczLjA4OSw3My4wODhjMy42MTcsMy42MTcsNy44OTgsNS40MjQsMTIuODQ3LDUuNDI0YzQuOTUsMCw5LjIzNC0xLjgwNywxMi44NDktNS40MjQgICBsNzMuMDg3LTczLjA4OGMzLjYxMy0zLjYyLDUuNDIxLTcuOTAxLDUuNDIxLTEyLjg0N2MwLTQuOTQ4LTEuODA4LTkuMjMyLTUuNDIxLTEyLjg1NCAgIEMzMzguMTQyLDQwMy44MDIsMzMzLjg1Nyw0MDEuOTk0LDMyOC45MDYsNDAxLjk5NHoiIGZpbGw9IiM2NjY2NjYiLz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K);
+ background-repeat: no-repeat;
+ background-position: center;
+ @include vendor(transform, rotate(45deg));
}
> .ui-resizable-se {
- display: inline-block;
- @include vendor(transform, rotate(90deg));
+ @include vendor(transform, rotate(-45deg));
}
+
> .ui-resizable-nw { cursor: nw-resize; width: 20px; height: 20px; left: 10px; top: 0; }
> .ui-resizable-n { cursor: n-resize; height: 10px; top: 0; left: 25px; right: 25px; }
> .ui-resizable-ne { cursor: ne-resize; width: 20px; height: 20px; right: 10px; top: 0; }
@@ -100,6 +99,12 @@ $animation_speed: .3s !default;
> .ui-resizable-sw { cursor: sw-resize; width: 20px; height: 20px; left: 10px; bottom: 0; }
> .ui-resizable-w { cursor: w-resize; width: 10px; left: $horizontal_padding / 2; top: 15px; bottom: 15px; }
+ &.ui-draggable-dragging {
+ &> .ui-resizable-handle {
+ display: none !important;
+ }
+ }
+
@for $i from 1 through $gridstack-columns {
&[data-gs-width='#{$i}'] { width: (100% / $gridstack-columns) * $i; }
&[data-gs-x='#{$i}'] { left: (100% / $gridstack-columns) * $i; }
@@ -120,14 +125,6 @@ $animation_speed: .3s !default;
}
}
-/** Uncomment this to show bottom-left resize handle **/
-/*
-.grid-stack > .grid-stack-item > .ui-resizable-sw {
- display: inline-block;
- @include vendor(transform, rotate(180deg));
-}
-*/
-
@media (max-width: 768px) {
.grid-stack-item {
position: relative !important;