From b0d9a8f1ec53fa6105ecc6a03923ef15ea8624bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Wagner?= Date: Thu, 12 Feb 2015 23:05:19 +0100 Subject: [PATCH 1/2] enabled auto-height feature --- demo/main/script.js | 9 ++- demo/main/view.html | 5 +- src/angular-gridster.js | 120 ++++++++++++++++++++++++---------------- test/e2e/gridster.js | 4 +- test/spec/gridster.js | 24 ++++++++ 5 files changed, 111 insertions(+), 51 deletions(-) diff --git a/demo/main/script.js b/demo/main/script.js index e97ff89f..f742853e 100644 --- a/demo/main/script.js +++ b/demo/main/script.js @@ -8,6 +8,9 @@ angular.module('app') if (viewValue === '' || viewValue === null || typeof viewValue === 'undefined') { return null; } + if (viewValue === 'a') { + return 'auto'; + } return parseInt(viewValue, 10); }); } @@ -40,7 +43,8 @@ angular.module('app') sizeX: 2, sizeY: 2, row: 0, - col: 2 + col: 2, + lines: 3 }, { sizeX: 2, sizeY: 1, @@ -175,4 +179,7 @@ angular.module('app') col: 'item.position[1]' }; + $scope.getList = function(num) { + return new Array(parseInt(num, 10)); + } }); diff --git a/demo/main/view.html b/demo/main/view.html index 98e20025..8e3bb805 100644 --- a/demo/main/view.html +++ b/demo/main/view.html @@ -12,7 +12,7 @@

Standard Items

- Each item provides its own dimensions and position using the standard fields: { row: row, col: col, sizeX: sizeX, sizeY: sizeY }. + Each item provides its own dimensions and position using the standard fields: { row: row, col: col, sizeX: sizeX, sizeY: sizeY, lines: lines }. sizeY could be 'a' for auto height.

diff --git a/src/angular-gridster.js b/src/angular-gridster.js index d009d7f2..8794ec28 100644 --- a/src/angular-gridster.js +++ b/src/angular-gridster.js @@ -62,7 +62,7 @@ if (gridster.loaded) { gridster.floatItemsUp(); } - gridster.updateHeight(gridster.movingItem ? gridster.movingItem.sizeY : 0); + gridster.updateHeight(gridster.movingItem ? gridster.movingItem.getSizeY() : 0); }); }; @@ -126,7 +126,7 @@ * @returns {boolean} True if if item fits */ this.canItemOccupy = function(item, row, column) { - return row > -1 && column > -1 && item.sizeX + column <= this.columns && item.sizeY + row <= this.maxRows; + return row > -1 && column > -1 && item.getSizeX() + column <= this.columns && item.getSizeY() + row <= this.maxRows; }; /** @@ -139,7 +139,7 @@ for (var rowIndex = 0; rowIndex < this.maxRows; ++rowIndex) { for (var colIndex = 0; colIndex < this.columns; ++colIndex) { // only insert if position is not already taken and it can fit - var items = this.getItems(rowIndex, colIndex, item.sizeX, item.sizeY, item); + var items = this.getItems(rowIndex, colIndex, item.getSizeX(), item.getSizeY(), item); if (items.length === 0 && this.canItemOccupy(item, rowIndex, colIndex)) { this.putItem(item, rowIndex, colIndex); return; @@ -187,8 +187,8 @@ return { row: items[0].row, col: items[0].col, - sizeY: items[0].sizeY, - sizeX: items[0].sizeX + sizeY: items[0].getSizeY(), + sizeX: items[0].getSizeX() }; } @@ -201,8 +201,8 @@ var item = items[i]; minRow = Math.min(item.row, minRow); minCol = Math.min(item.col, minCol); - maxRow = Math.max(item.row + item.sizeY, maxRow); - maxCol = Math.max(item.col + item.sizeX, maxCol); + maxRow = Math.max(item.row + item.getSizeY(), maxRow); + maxCol = Math.max(item.col + item.getSizeX(), maxCol); } return { @@ -254,7 +254,7 @@ var items = this.grid[row]; if (items) { var item = items[col]; - if (item && (!excludeItems || excludeItems.indexOf(item) === -1) && item.sizeX >= sizeX && item.sizeY >= sizeY) { + if (item && (!excludeItems || excludeItems.indexOf(item) === -1) && item.getSizeX() >= sizeX && item.getSizeY() >= sizeY) { return item; } } @@ -296,8 +296,8 @@ } } if (!this.canItemOccupy(item, row, column)) { - column = Math.min(this.columns - item.sizeX, Math.max(0, column)); - row = Math.min(this.maxRows - item.sizeY, Math.max(0, row)); + column = Math.min(this.columns - item.getSizeX(), Math.max(0, column)); + row = Math.min(this.maxRows - item.getSizeY(), Math.max(0, row)); } if (item.oldRow !== null && typeof item.oldRow !== 'undefined') { @@ -368,11 +368,11 @@ var overlappingItems = this.getItems( item.row, item.col, - item.sizeX, - item.sizeY, + item.getSizeX(), + item.getSizeY(), ignoreItems ); - this.moveItemsDown(overlappingItems, item.row + item.sizeY, ignoreItems); + this.moveItemsDown(overlappingItems, item.row + item.getSizeY(), ignoreItems); }; /** @@ -451,8 +451,8 @@ return; } var colIndex = item.col, - sizeY = item.sizeY, - sizeX = item.sizeX, + sizeY = item.getSizeY(), + sizeX = item.getSizeX(), bestRow = null, bestColumn = null, rowIndex = item.row - 1; @@ -486,7 +486,7 @@ } for (var colIndex = 0, len = columns.length; colIndex < len; ++colIndex) { if (columns[colIndex]) { - maxHeight = Math.max(maxHeight, rowIndex + plus + columns[colIndex].sizeY); + maxHeight = Math.max(maxHeight, rowIndex + plus + columns[colIndex].getSizeY()); } } } @@ -895,8 +895,8 @@ return { display: 'block', - height: (gridster.movingItem.sizeY * gridster.curRowHeight - gridster.margins[0]) + 'px', - width: (gridster.movingItem.sizeX * gridster.curColWidth - gridster.margins[1]) + 'px', + height: (gridster.movingItem.getSizeY() * gridster.curRowHeight - gridster.margins[0]) + 'px', + width: (gridster.movingItem.getSizeX() * gridster.curColWidth - gridster.margins[1]) + 'px', top: (gridster.movingItem.row * gridster.curRowHeight + (gridster.outerMargin ? gridster.margins[0] : 0)) + 'px', left: (gridster.movingItem.col * gridster.curColWidth + (gridster.outerMargin ? gridster.margins[1] : 0)) + 'px' }; @@ -969,7 +969,7 @@ scope.$watch('gridster.gridHeight', updateHeight); scope.$watch('gridster.movingItem', function() { - gridster.updateHeight(gridster.movingItem ? gridster.movingItem.sizeY : 0); + gridster.updateHeight(gridster.movingItem ? gridster.movingItem.getSizeY() : 0); }); var prevWidth = $elem[0].offsetWidth || parseInt($elem.css('width'), 10); @@ -1092,6 +1092,12 @@ * @param {number} value The size amount */ this.setSize = function(key, value, preventMove) { + var auto = false; + if (value === 'auto' && key === 'Y') { + auto = true; + value = this.getSizeY(); + } + key = key.toUpperCase(); var camelCase = 'size' + key, titleCase = 'Size' + key; @@ -1128,6 +1134,10 @@ var changed = (this[camelCase] !== value || (this['old' + titleCase] && this['old' + titleCase] !== value)); this['old' + titleCase] = this[camelCase] = value; + if (auto) { + this.sizeY = 'auto'; // reset auto after calculations + } + if (!this.isMoving()) { this['setElement' + titleCase](); } @@ -1157,6 +1167,23 @@ return this.setSize('X', columns, preventMove); }; + /** + * Gets the items sizeY property + */ + this.getSizeY = function() { + if (this.sizeY === 'auto') { + return this.gridster.pixelsToRows((this.$element[0].offsetHeight + this.gridster.margins[0]), true); + } + return this.sizeY; + }; + + /** + * Gets the items sizeX property + */ + this.getSizeX = function() { + return this.sizeX; + }; + /** * Sets an elements position on the page * @@ -1186,10 +1213,10 @@ * Sets an elements height */ this.setElementSizeY = function() { - if (this.gridster.isMobile && !this.gridster.saveGridItemCalculatedHeightInMobile) { + if ((this.gridster.isMobile && !this.gridster.saveGridItemCalculatedHeightInMobile) || this.sizeY === 'auto') { this.$element.css('height', ''); } else { - this.$element.css('height', (this.sizeY * this.gridster.curRowHeight - this.gridster.margins[0]) + 'px'); + this.$element.css('height', (this.getSizeY() * this.gridster.curRowHeight - this.gridster.margins[0]) + 'px'); } }; @@ -1200,7 +1227,7 @@ if (this.gridster.isMobile) { this.$element.css('width', ''); } else { - this.$element.css('width', (this.sizeX * this.gridster.curColWidth - this.gridster.margins[1]) + 'px'); + this.$element.css('width', (this.getSizeX() * this.gridster.curColWidth - this.gridster.margins[1]) + 'px'); } }; @@ -1208,14 +1235,14 @@ * Gets an element's width */ this.getElementSizeX = function() { - return (this.sizeX * this.gridster.curColWidth - this.gridster.margins[1]); + return (this.getSizeX() * this.gridster.curColWidth - this.gridster.margins[1]); }; /** * Gets an element's height */ this.getElementSizeY = function() { - return (this.sizeY * this.gridster.curRowHeight - this.gridster.margins[0]); + return (this.getSizeY() * this.gridster.curRowHeight - this.gridster.margins[0]); }; }) @@ -1349,7 +1376,7 @@ $el.addClass('gridster-item-moving'); gridster.movingItem = item; - gridster.updateHeight(item.sizeY); + gridster.updateHeight(item.getSizeY()); scope.$apply(function() { if (gridster.draggable && gridster.draggable.start) { gridster.draggable.start(event, $el, itemOptions); @@ -1367,12 +1394,12 @@ var row = gridster.pixelsToRows(elmY); var col = gridster.pixelsToColumns(elmX); - var itemsInTheWay = gridster.getItems(row, col, item.sizeX, item.sizeY, item); + var itemsInTheWay = gridster.getItems(row, col, item.getSizeX(), item.getSizeY(), item); var hasItemsInTheWay = itemsInTheWay.length !== 0; if (gridster.swapping === true && hasItemsInTheWay) { var boundingBoxItem = gridster.getBoundingBox(itemsInTheWay); - var sameSize = boundingBoxItem.sizeX === item.sizeX && boundingBoxItem.sizeY === item.sizeY; + var sameSize = boundingBoxItem.getSizeX() === item.getSizeX() && boundingBoxItem.getSizeY() === item.getSizeY(); var sameRow = boundingBoxItem.row === row; var sameCol = boundingBoxItem.col === col; var samePosition = sameRow && sameCol; @@ -1384,9 +1411,9 @@ } else if (inline) { return; } - } else if (boundingBoxItem.sizeX <= item.sizeX && boundingBoxItem.sizeY <= item.sizeY && inline) { - var emptyRow = item.row <= row ? item.row : row + item.sizeY; - var emptyCol = item.col <= col ? item.col : col + item.sizeX; + } else if (boundingBoxItem.getSizeX() <= item.getSizeX() && boundingBoxItem.getSizeY() <= item.getSizeY() && inline) { + var emptyRow = item.row <= row ? item.row : row + item.getSizeY(); + var emptyCol = item.col <= col ? item.col : col + item.getSizeX(); var rowOffset = emptyRow - boundingBoxItem.row; var colOffset = emptyCol - boundingBoxItem.col; @@ -1396,8 +1423,8 @@ var itemsInFreeSpace = gridster.getItems( itemInTheWay.row + rowOffset, itemInTheWay.col + colOffset, - itemInTheWay.sizeX, - itemInTheWay.sizeY, + itemInTheWay.getSizeX(), + itemInTheWay.getSizeY(), item ); @@ -1438,7 +1465,7 @@ $el.removeClass('gridster-item-moving'); var row = gridster.pixelsToRows(elmY); var col = gridster.pixelsToColumns(elmX); - if (gridster.pushing !== false || gridster.getItems(row, col, item.sizeX, item.sizeY, item).length === 0) { + if (gridster.pushing !== false || gridster.getItems(row, col, item.getSizeX(), item.getSizeY(), item).length === 0) { item.row = row; item.col = col; } @@ -1565,8 +1592,8 @@ elmW = $el[0].offsetWidth; elmH = $el[0].offsetHeight; - originalWidth = item.sizeX; - originalHeight = item.sizeY; + originalWidth = item.getSizeX(); + originalHeight = item.getSizeY(); resizeStart(e); @@ -1684,8 +1711,8 @@ function resize(e) { var oldRow = item.row, oldCol = item.col, - oldSizeX = item.sizeX, - oldSizeY = item.sizeY, + oldSizeX = item.getSizeX(), + oldSizeY = item.getSizeY(), hasCallback = gridster.resizable && gridster.resizable.resize; var col = item.col; @@ -1700,13 +1727,13 @@ row = gridster.pixelsToRows(elmY, false); } - var sizeX = item.sizeX; + var sizeX = item.getSizeX(); // only change row if grabbing left or right edge if (['n', 's'].indexOf(handleClass) === -1) { sizeX = gridster.pixelsToColumns(elmW, true); } - var sizeY = item.sizeY; + var sizeY = item.getSizeY(); // only change row if grabbing top or bottom edge if (['e', 'w'].indexOf(handleClass) === -1) { sizeY = gridster.pixelsToRows(elmH, true); @@ -1718,7 +1745,7 @@ item.sizeX = sizeX; item.sizeY = sizeY; } - var isChanged = item.row !== oldRow || item.col !== oldCol || item.sizeX !== oldSizeX || item.sizeY !== oldSizeY; + var isChanged = item.row !== oldRow || item.col !== oldCol || item.getSizeX() !== oldSizeX || item.getSizeY() !== oldSizeY; if (hasCallback || isChanged) { scope.$apply(function() { @@ -1847,8 +1874,8 @@ options = { row: item.row, col: item.col, - sizeX: item.sizeX, - sizeY: item.sizeY, + sizeX: item.getSizeX(), + sizeY: item.getSizeY(), minSizeX: 0, minSizeY: 0, maxSizeX: null, @@ -1882,15 +1909,14 @@ // when the value changes externally, update the internal item object scope.$watch(key, function(newVal) { - newVal = parseInt(newVal, 10); - if (!isNaN(newVal)) { + if (typeof newVal === 'number' || newVal === 'auto') { item[aspect] = newVal; } }); // initial set var val = $getters[aspect](scope); - if (typeof val === 'number') { + if (typeof val === 'number' || val === 'auto') { item[aspect] = val; } }; @@ -1899,7 +1925,7 @@ aspectFn(aspects[i]); } - scope.$broadcast('gridster-item-initialized', [item.sizeY, item.sizeX, item.getElementSizeY(), item.getElementSizeX()]); + scope.$broadcast('gridster-item-initialized', [item.getSizeY(), item.getSizeX(), item.getElementSizeY(), item.getElementSizeX()]); function positionChanged() { // call setPosition so the element and gridster controller are updated @@ -1933,7 +1959,7 @@ } } scope.$watch(function() { - return item.sizeY + ',' + item.sizeX + '|' + item.minSizeX + ',' + item.maxSizeX + ',' + item.minSizeY + ',' + item.maxSizeY; + return item.sizeY + ',' + item.getSizeY() + ',' + item.getSizeX() + '|' + item.minSizeX + ',' + item.maxSizeX + ',' + item.minSizeY + ',' + item.maxSizeY; }, sizeChanged); var draggable = new GridsterDraggable($el, scope, gridster, item, options); diff --git a/test/e2e/gridster.js b/test/e2e/gridster.js index 69013ac4..bc60ea4d 100644 --- a/test/e2e/gridster.js +++ b/test/e2e/gridster.js @@ -22,7 +22,7 @@ describe('Controller: GridsterCtrl', function() { expect(items.length).toEqual(11); }); - browser.findElement(by.css('h2:first-child')).then(function(el) { + element(by.css('h2:first-child')).then(function(el) { return el.getText().then(function(text) { expect(text).toBe('Standard Items'); }); @@ -36,7 +36,7 @@ describe('Controller: GridsterCtrl', function() { expect(size.width).toBeGreaterThan(0); width = size.width; }).then(function() { - return firstItem.findElement(by.model('item.sizeX')); + return firstItem.element(by.model('item.sizeX')); }).then(function(input) { return input.sendKeys('2').then(function() { input.sendKeys(protractor.Key.TAB); diff --git a/test/spec/gridster.js b/test/spec/gridster.js index fa6412d5..f07a63e1 100644 --- a/test/spec/gridster.js +++ b/test/spec/gridster.js @@ -16,21 +16,45 @@ describe('GridsterCtrl', function() { item1x1 = { sizeX: 1, sizeY: 1, + getSizeX: function() { + return this.sizeX; + }, + getSizeY: function() { + return this.sizeY; + }, id: '1x1' }; item2x1 = { sizeX: 2, sizeY: 1, + getSizeX: function() { + return this.sizeX; + }, + getSizeY: function() { + return this.sizeY; + }, id: '2x1' }; item2x2 = { sizeX: 2, sizeY: 2, + getSizeX: function() { + return this.sizeX; + }, + getSizeY: function() { + return this.sizeY; + }, id: '2x2' }; item1x2 = { sizeX: 1, sizeY: 2, + getSizeX: function() { + return this.sizeX; + }, + getSizeY: function() { + return this.sizeY; + }, id: '1x2' }; From 42e922be5b6a7e1be4dc22b930deda1240b346d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Wagner?= Date: Wed, 18 Feb 2015 00:09:17 +0100 Subject: [PATCH 2/2] fixed init value for standardItems approach --- demo/main/script.js | 4 ++-- src/angular-gridster.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/demo/main/script.js b/demo/main/script.js index f742853e..2d905b65 100644 --- a/demo/main/script.js +++ b/demo/main/script.js @@ -41,7 +41,7 @@ angular.module('app') col: 0 }, { sizeX: 2, - sizeY: 2, + sizeY: 'auto', row: 0, col: 2, lines: 3 @@ -180,6 +180,6 @@ angular.module('app') }; $scope.getList = function(num) { - return new Array(parseInt(num, 10)); + return new Array(parseInt(num, 10) || 0); } }); diff --git a/src/angular-gridster.js b/src/angular-gridster.js index 8794ec28..46b38009 100644 --- a/src/angular-gridster.js +++ b/src/angular-gridster.js @@ -1896,7 +1896,7 @@ var aspectFn = function(aspect) { var key; - if (typeof options[aspect] === 'string') { + if (typeof options[aspect] === 'string' && options[aspect] !== 'auto') { key = options[aspect]; } else if (typeof options[aspect.toLowerCase()] === 'string') { key = options[aspect.toLowerCase()];