diff --git a/Gruntfile.js b/Gruntfile.js old mode 100755 new mode 100644 diff --git a/README.md b/README.md index 9044c6541..8192f7554 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ Note: You can still use [underscore.js](http://underscorejs.org) (>= 1.7.0) inst ## Basic usage -```html +```
@@ -525,7 +531,7 @@ $(function () { and HTML: -```html +```
``` @@ -590,7 +596,7 @@ and so on. Here is a SASS code snipped which can make life easier (Thanks to @ascendantofrain, [#81](https://github.com/troolee/gridstack.js/issues/81)): -```sass +``` .grid-stack-item { $gridstack-columns: 12; @@ -614,7 +620,7 @@ There are few extra CSS batteries in `gridstack-extra.css` (`gridstack-extra.min You can use other than 12 grid width: -```html +```
...
``` ```javascript @@ -700,7 +706,7 @@ CSS stylesheet dynamically. As a workaround you can do the following: - Create `gridstack-ie8.css` for your configuration (sample for grid with cell height of 60px can be found [here](https://gist.github.com/troolee/6edfea5857f4cd73e6f1)). - Include this CSS: -```html +``` diff --git a/dist/gridstack.js b/dist/gridstack.js old mode 100755 new mode 100644 diff --git a/package.json b/package.json old mode 100755 new mode 100644 diff --git a/src/gridstack.js b/src/gridstack.js index 09bfba47f..e045226f4 100644 --- a/src/gridstack.js +++ b/src/gridstack.js @@ -424,6 +424,9 @@ }); this.opts.is_nested = is_nested; + this.cell_height(this.opts.cell_height, true); + this.vertical_margin(this.opts.vertical_margin, true); + this.container.addClass(this.opts._class); this._set_static_class(); @@ -473,9 +476,7 @@ '
' + '
' + this.opts.placeholder_text + '
').hide(); - this.container.height( - this.grid.get_grid_height() * (this.opts.cell_height + this.opts.vertical_margin) - - this.opts.vertical_margin); + this._update_container_height(); this.on_resize_handler = function() { if (self._is_one_column_mode()) { @@ -540,6 +541,9 @@ }; GridStack.prototype._init_styles = function() { + if (!this.opts.cell_height) { //that will be handled by CSS + return ; + } if (this._styles_id) { $('[data-gs-id="' + this._styles_id + '"]').remove(); } @@ -554,7 +558,10 @@ return; } - var prefix = '.' + this.opts._class + ' .' + this.opts.item_class; + var prefix = '.' + this.opts._class + ' .' + this.opts.item_class, + self = this, + get_height + ; if (typeof max_height == 'undefined') { max_height = this._styles._max; @@ -562,30 +569,50 @@ this._update_container_height(); } + if (!this.opts.cell_height) { //the rest will be handled by CSS + return ; + } + if (this._styles._max !== 0 && max_height <= this._styles._max) { + return ; + } + + if (!this.opts.vertical_margin || this.opts.cell_height_unit === this.opts.vertical_margin_unit) { + get_height = function (nbRows, nbMargins) { + return (self.opts.cell_height * nbRows + self.opts.vertical_margin * nbMargins) + self.opts.cell_height_unit; + } + } else { + get_height = function (nbRows, nbMargins) { + if (!nbRows || !nbMargins) { + return (self.opts.cell_height * nbRows + self.opts.vertical_margin * nbMargins) + self.opts.cell_height_unit; + } + return 'calc(' + ((self.opts.cell_height * nbRows) + self.opts.cell_height_unit) + ' + ' + ((self.opts.vertical_margin * nbMargins) + self.opts.vertical_margin_unit) + ')'; + } + } + if (this._styles._max == 0) { - Utils.insert_css_rule(this._styles, prefix, 'min-height: ' + (this.opts.cell_height) + 'px;', 0); + Utils.insert_css_rule(this._styles, prefix, 'min-height: ' + get_height(1, 0) + ';', 0); } if (max_height > this._styles._max) { for (var i = this._styles._max; i < max_height; ++i) { Utils.insert_css_rule(this._styles, prefix + '[data-gs-height="' + (i + 1) + '"]', - 'height: ' + (this.opts.cell_height * (i + 1) + this.opts.vertical_margin * i) + 'px;', + 'height: ' + get_height(i + 1, i) + ';', i ); Utils.insert_css_rule(this._styles, prefix + '[data-gs-min-height="' + (i + 1) + '"]', - 'min-height: ' + (this.opts.cell_height * (i + 1) + this.opts.vertical_margin * i) + 'px;', + 'min-height: ' + get_height(i + 1, i) + ';', i ); Utils.insert_css_rule(this._styles, prefix + '[data-gs-max-height="' + (i + 1) + '"]', - 'max-height: ' + (this.opts.cell_height * (i + 1) + this.opts.vertical_margin * i) + 'px;', + 'max-height: ' + get_height(i + 1, i) + ';', i ); Utils.insert_css_rule(this._styles, prefix + '[data-gs-y="' + i + '"]', - 'top: ' + (this.opts.cell_height * i + this.opts.vertical_margin * i) + 'px;', + 'top: ' + get_height(i, i) + ';', i ); } @@ -597,9 +624,18 @@ if (this.grid._update_counter) { return; } - this.container.height( - this.grid.get_grid_height() * (this.opts.cell_height + this.opts.vertical_margin) - - this.opts.vertical_margin); + var height = this.grid.get_grid_height(); + this.container.attr('data-gs-current-height', height); + if (!this.opts.cell_height) { + return ; + } + if (!this.opts.vertical_margin) { + this.container.css('height', (height * (this.opts.cell_height)) + this.opts.cell_height_unit); + } else if (this.opts.cell_height_unit === this.opts.vertical_margin_unit) { + this.container.css('height', (height * (this.opts.cell_height + this.opts.vertical_margin) - this.opts.vertical_margin) + this.opts.cell_height_unit); + } else { + this.container.css('height', 'calc(' + ((height * (this.opts.cell_height)) + this.opts.cell_height_unit) + ' + ' + ((height * (this.opts.vertical_margin - 1)) + this.opts.vertical_margin_unit) + ')'); + } }; GridStack.prototype._is_one_column_mode = function() { @@ -657,8 +693,9 @@ var o = $(this); self.grid.clean_nodes(); self.grid.begin_update(node); - cell_width = o.outerWidth() / o.attr('data-gs-width'); - cell_height = self.opts.cell_height + self.opts.vertical_margin; + cell_width = Math.ceil(o.outerWidth() / o.attr('data-gs-width')); + var strict_cell_height = Math.ceil(o.outerHeight() / o.attr('data-gs-height')); + cell_height = self.container.height() / parseInt(self.container.attr('data-gs-current-height')); self.placeholder .attr('data-gs-x', o.attr('data-gs-x')) .attr('data-gs-y', o.attr('data-gs-y')) @@ -667,8 +704,8 @@ .show(); node.el = self.placeholder; - el.resizable('option', 'minWidth', Math.round(cell_width * (node.min_width || 1))); - el.resizable('option', 'minHeight', self.opts.cell_height * (node.min_height || 1)); + el.resizable('option', 'minWidth', cell_width * (node.min_width || 1)); + el.resizable('option', 'minHeight', strict_cell_height * (node.min_height || 1)); if (event.type == 'resizestart') { o.find('.grid-stack-item').trigger('resizestart'); @@ -862,39 +899,39 @@ return this; }; - GridStack.prototype.min_height = function (el, val) { - el = $(el); - el.each(function (index, el) { - el = $(el); - var node = el.data('_gridstack_node'); - if (typeof node == 'undefined' || node == null) { - return; - } - - if(!isNaN(val)){ - node.min_height = (val || false); - el.attr('data-gs-min-height', val); - } - }); - return this; - }; - - GridStack.prototype.min_width = function (el, val) { - el = $(el); - el.each(function (index, el) { - el = $(el); - var node = el.data('_gridstack_node'); - if (typeof node == 'undefined' || node == null) { - return; - } - - if(!isNaN(val)){ - node.min_width = (val || false); - el.attr('data-gs-min-width', val); - } - }); - return this; - }; + GridStack.prototype.min_height = function (el, val) { + el = $(el); + el.each(function (index, el) { + el = $(el); + var node = el.data('_gridstack_node'); + if (typeof node == 'undefined' || node == null) { + return; + } + + if(!isNaN(val)){ + node.min_height = (val || false); + el.attr('data-gs-min-height', val); + } + }); + return this; + }; + + GridStack.prototype.min_width = function (el, val) { + el = $(el); + el.each(function (index, el) { + el = $(el); + var node = el.data('_gridstack_node'); + if (typeof node == 'undefined' || node == null) { + return; + } + + if(!isNaN(val)){ + node.min_width = (val || false); + el.attr('data-gs-min-width', val); + } + }); + return this; + }; GridStack.prototype._update_element = function(el, callback) { el = $(el).first(); @@ -945,15 +982,59 @@ }); }; - GridStack.prototype.cell_height = function(val) { + function parseHeight(val) { + var height = val; + var height_unit = 'px'; + if (height && _.isString(height)) { + var match = height.match(/^([0-9]+)(px|em|rem)?$/); + if (!match) { + throw new Error('Invalid height'); + } + height_unit = match[2]; + height = parseInt(match[1]); + } + return {height: height, unit: height_unit}; + } + + GridStack.prototype.vertical_margin = function (val, noUpdate) { if (typeof val == 'undefined') { - return this.opts.cell_height; + return this.opts.vertical_margin; + } + + var heightData = parseHeight(val); + + if (this.opts.vertical_margin_unit === heightData.unit && this.opts.height === heightData.height) { + return ; + } + this.opts.vertical_margin_unit = heightData.unit; + this.opts.vertical_margin = heightData.height; + + if (!noUpdate) { + this._update_styles(); + } + }; + + GridStack.prototype.cell_height = function (val, noUpdate) { + if (typeof val == 'undefined') { + if (this.opts.cell_height) { + return this.opts.cell_height; + } else { + var o = this.container.children('.' + this.opts.item_class).first(); + return Math.ceil(o.outerHeight() / o.attr('data-gs-height')); + } + } + + var heightData = parseHeight(val); + + if (this.opts.cell_height_unit === heightData.height_unit && this.opts.height === heightData.height) { + return ; + } + this.opts.cell_height_unit = heightData.unit; + this.opts.cell_height = heightData.height; + + if (!noUpdate) { + this._update_styles(); } - val = parseInt(val); - if (val == this.opts.cell_height) - return; - this.opts.cell_height = val || this.opts.cell_height; - this._update_styles(); }; GridStack.prototype.cell_width = function() { @@ -967,7 +1048,7 @@ var relativeTop = position.top - containerPos.top; var column_width = Math.floor(this.container.width() / this.opts.width); - var row_height = this.opts.cell_height + this.opts.vertical_margin; + var row_height = Math.floor(this.container.height() / parseInt(this.container.attr('data-gs-current-height'))); return {x: Math.floor(relativeLeft / column_width), y: Math.floor(relativeTop / row_height)}; };