diff --git a/demo/main/script.js b/demo/main/script.js
index e97ff89f..2d905b65 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);
});
}
@@ -38,9 +41,10 @@ angular.module('app')
col: 0
}, {
sizeX: 2,
- sizeY: 2,
+ sizeY: 'auto',
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) || 0);
+ }
});
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..46b38009 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,
@@ -1869,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()];
@@ -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'
};