diff --git a/README.md b/README.md index df286612..517da2dd 100644 --- a/README.md +++ b/README.md @@ -130,6 +130,8 @@ Simply pass your desired options to the gridster directive ```JavaScript $scope.gridsterOpts = { columns: 6, // the width of the grid, in columns + dynamicColumns: false, // whether to place into the grid the maximum suitable columns with a minimum width of minWidthToAddANewColumn + minWidthToAddANewColumn: 140, // minimum width within gridster to add a new column when dynamicColumns is true. The predefined margin in between columns and outerMargin (if true) are added to this number in the calculation. pushing: true, // whether to push other items out of the way on move or resize floating: true, // whether to automatically float items up so they stack (you can temporarily disable if you are adding unsorted items with ng-repeat) swapping: false, // whether or not to have items of the same size switch places instead of pushing down if they are the same size @@ -221,6 +223,14 @@ scope.$on('gridster-resizable-changed', function(gridster) { }) ``` +#### gridster-columns-changed +When the number of columns changes, a 'gridster-columns-changed' event is broadcast on rootScope: + +```js +scope.$on('gridster-columns-changed', function(gridster) { +}) +``` + #### gridster-resized When the gridster element's size changes, a 'gridster-resized' event is broadcast on rootScope: diff --git a/demo/common/style.css b/demo/common/style.css index 52edef3d..fbe36ccb 100644 --- a/demo/common/style.css +++ b/demo/common/style.css @@ -18,4 +18,7 @@ input { font-weight: bold; float: right; padding: 10px; -} \ No newline at end of file +} +.controls { + margin-bottom: 5px; +} diff --git a/demo/dashboard/style.css b/demo/dashboard/style.css index 9db106b9..69aa9da9 100644 --- a/demo/dashboard/style.css +++ b/demo/dashboard/style.css @@ -1,7 +1,4 @@ -.controls { - margin-bottom: 20px; -} .page-header { margin-top: 20px; } @@ -41,4 +38,4 @@ form { } .gridster { border: 1px solid #ccc; -} \ No newline at end of file +} diff --git a/demo/main/view.html b/demo/main/view.html index 98e20025..d38f9fef 100644 --- a/demo/main/view.html +++ b/demo/main/view.html @@ -1,15 +1,21 @@

Standard Items

- - - - - - Margins: - - x - +
+ + + + + + +
+ +

+ Margins: + + x + +

Each item provides its own dimensions and position using the standard fields: { row: row, col: col, sizeX: sizeX, sizeY: sizeY }. @@ -85,4 +91,4 @@

No Configuration or Binding

  • - \ No newline at end of file + diff --git a/dist/angular-gridster.min.js b/dist/angular-gridster.min.js index 07d7c878..09649d1b 100644 --- a/dist/angular-gridster.min.js +++ b/dist/angular-gridster.min.js @@ -5,4 +5,4 @@ * @version: 0.13.14 * @license: MIT */ -!function(a,b){"use strict";"function"==typeof define&&define.amd?define(["angular"],b):"object"==typeof exports?module.exports=b(require("angular")):b(a.angular)}(this,function(a){"use strict";return a.module("gridster",[]).constant("gridsterConfig",{columns:6,pushing:!0,floating:!0,swapping:!1,width:"auto",colWidth:"auto",rowHeight:"match",margins:[10,10],outerMargin:!0,sparse:!1,isMobile:!1,mobileBreakPoint:600,mobileModeEnabled:!0,minColumns:1,minRows:1,maxRows:100,defaultSizeX:2,defaultSizeY:1,minSizeX:1,maxSizeX:null,minSizeY:1,maxSizeY:null,saveGridItemCalculatedHeightInMobile:!1,resizable:{enabled:!0,handles:["s","e","n","w","se","ne","sw","nw"]},draggable:{enabled:!0,scrollSensitivity:20,scrollSpeed:15}}).controller("GridsterCtrl",["gridsterConfig","$timeout",function(b,c){var d=this;a.extend(this,b),this.resizable=a.extend({},b.resizable||{}),this.draggable=a.extend({},b.draggable||{});var e=!1;this.layoutChanged=function(){e||(e=!0,c(function(){e=!1,d.loaded&&d.floatItemsUp(),d.updateHeight(d.movingItem?d.movingItem.sizeY:0)},30))},this.grid=[],this.allItems=[],this.destroy=function(){this.grid&&(this.grid=[]),this.$element=null,this.allItems&&(this.allItems.length=0,this.allItems=null)},this.setOptions=function(b){if(b)if(b=a.extend({},b),b.draggable&&(a.extend(this.draggable,b.draggable),delete b.draggable),b.resizable&&(a.extend(this.resizable,b.resizable),delete b.resizable),a.extend(this,b),this.margins&&2===this.margins.length)for(var c=0,d=this.margins.length;c-1&&c>-1&&a.sizeX+c<=this.columns&&a.sizeY+b<=this.maxRows},this.autoSetItemPosition=function(a){for(var b=0;b=a.col&&d<=a.row+a.sizeY-1&&e>=a.row},this.removeItem=function(a){for(var b,c=0,d=this.grid.length;c-1;){for(var e=1,f=b;f>-1;){var g=this.grid[a];if(g){var h=g[f];if(h&&(!c||c.indexOf(h)===-1)&&h.sizeX>=e&&h.sizeY>=d)return h}++e,--f}--a,++d}return null},this.putItems=function(a){for(var b=0,c=a.length;b=b)){for(;a.row-1;){var h=this.getItems(g,b,d,c,a);if(0!==h.length)break;e=g,f=b,--g}null!==e&&this.putItem(a,e,f)}},this.updateHeight=function(a){var b=this.minRows;a=a||0;for(var c=this.grid.length;c>=0;--c){var d=this.grid[c];if(d)for(var e=0,f=d.length;e0?Math.min(this.maxRows,b):Math.max(this.maxRows,b)},this.pixelsToRows=function(a,b){return this.outerMargin||(a+=this.margins[0]/2),b===!0?Math.ceil(a/this.curRowHeight):b===!1?Math.floor(a/this.curRowHeight):Math.round(a/this.curRowHeight)},this.pixelsToColumns=function(a,b){return this.outerMargin||(a+=this.margins[1]/2),b===!0?Math.ceil(a/this.curColWidth):b===!1?Math.floor(a/this.curColWidth):Math.round(a/this.curColWidth)}}]).directive("gridsterPreview",function(){return{replace:!0,scope:!0,require:"^gridster",template:'
    ',link:function(a,b,c,d){a.previewStyle=function(){return d.movingItem?{display:"block",height:d.movingItem.sizeY*d.curRowHeight-d.margins[0]+"px",width:d.movingItem.sizeX*d.curColWidth-d.margins[1]+"px",top:d.movingItem.row*d.curRowHeight+(d.outerMargin?d.margins[0]:0)+"px",left:d.movingItem.col*d.curColWidth+(d.outerMargin?d.margins[1]:0)+"px"}:{display:"none"}}}}}).directive("gridster",["$timeout","$window","$rootScope","gridsterDebounce",function(b,c,d,e){return{scope:!0,restrict:"EAC",controller:"GridsterCtrl",controllerAs:"gridster",compile:function(f){return f.prepend('
    '),function(f,g,h,i){function j(){g.css("height",i.gridHeight*i.curRowHeight+(i.outerMargin?i.margins[0]:-i.margins[0])+"px")}function k(a){if(i.setOptions(a),l(g[0])){"auto"===i.width?i.curWidth=g[0].offsetWidth||parseInt(g.css("width"),10):i.curWidth=i.width,"auto"===i.colWidth?i.curColWidth=(i.curWidth+(i.outerMargin?-i.margins[1]:i.margins[1]))/i.columns:i.curColWidth=i.colWidth,i.curRowHeight=i.rowHeight,"string"==typeof i.rowHeight&&("match"===i.rowHeight?i.curRowHeight=Math.round(i.curColWidth):i.rowHeight.indexOf("*")!==-1?i.curRowHeight=Math.round(i.curColWidth*i.rowHeight.replace("*","").replace(" ","")):i.rowHeight.indexOf("/")!==-1&&(i.curRowHeight=Math.round(i.curColWidth/i.rowHeight.replace("/","").replace(" ","")))),i.isMobile=i.mobileModeEnabled&&i.curWidth<=i.mobileBreakPoint;for(var b=0,c=i.grid.length;bb&&(d=b-p-r,z=h-d),q+ic&&(f=c-q-s,A=i-f),p+=d,q+=f,e.css({top:q+"px",left:p+"px"}),k(a),!0}function o(a){return!(!e.hasClass("gridster-item-moving")||e.hasClass("gridster-item-resizing"))&&(z=A=0,l(a),!0)}var p,q,r,s,t,u,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=b[0],E=["select","option","input","textarea","button"],F=null,G=null;this.enable=function(){if(F!==!0){if(F=!0,G)return void G.enable();G=new d(e[0],m,n,o),G.enable()}},this.disable=function(){F!==!1&&(F=!1,G&&G.disable())},this.toggle=function(a){a?this.enable():this.disable()},this.destroy=function(){this.disable()}}return e}]).factory("GridsterResizable",["GridsterTouch",function(b){function c(c,d,e,f,g){function h(h){function i(a){c.addClass("gridster-item-moving"),c.addClass("gridster-item-resizing"),e.movingItem=f,f.setElementSizeX(),f.setElementSizeY(),f.setElementPosition(),e.updateHeight(1),d.$apply(function(){e.resizable&&e.resizable.start&&e.resizable.start(a,c,g,f)})}function j(a){var b=f.row,i=f.col,j=f.sizeX,k=f.sizeY,l=e.resizable&&e.resizable.resize,m=f.col;["w","nw","sw"].indexOf(h)!==-1&&(m=e.pixelsToColumns(o,!1));var n=f.row;["n","ne","nw"].indexOf(h)!==-1&&(n=e.pixelsToRows(p,!1));var s=f.sizeX;["n","s"].indexOf(h)===-1&&(s=e.pixelsToColumns(q,!0));var t=f.sizeY;["e","w"].indexOf(h)===-1&&(t=e.pixelsToRows(r,!0));var u=n>-1&&m>-1&&s+m<=e.columns&&t+n<=e.maxRows;!u||e.pushing===!1&&0!==e.getItems(n,m,s,t,f).length||(f.row=n,f.col=m,f.sizeX=s,f.sizeY=t);var v=f.row!==b||f.col!==i||f.sizeX!==j||f.sizeY!==k;(l||v)&&d.$apply(function(){l&&e.resizable.resize(a,c,g,f)})}function k(a){c.removeClass("gridster-item-moving"),c.removeClass("gridster-item-resizing"),e.movingItem=null,f.setPosition(f.row,f.col),f.setSizeY(f.sizeY),f.setSizeX(f.sizeX),d.$apply(function(){e.resizable&&e.resizable.stop&&e.resizable.stop(a,c,g,f)})}function l(a){switch(a.which){case 1:break;case 2:case 3:return}return u=e.draggable.enabled,u&&(e.draggable.enabled=!1,d.$broadcast("gridster-draggable-changed",e)),z=a.pageX,A=a.pageY,o=parseInt(c.css("left"),10),p=parseInt(c.css("top"),10),q=c[0].offsetWidth,r=c[0].offsetHeight,s=f.sizeX,t=f.sizeY,i(a),!0}function m(a){var b=e.curWidth-1;x=a.pageX,y=a.pageY;var d=x-z+B,f=y-A+C;B=C=0,z=x,A=y;var g=f,h=d;return w.indexOf("n")>=0&&(r-g=0&&(r+gE&&(f=E-p-r,C=g-f),r+=f),w.indexOf("w")>=0&&(q-h=0&&(q+hb&&(d=b-o-q,B=h-d),q+=d),c.css({top:p+"px",left:o+"px",width:q+"px",height:r+"px"}),j(a),!0}function n(a){return e.draggable.enabled!==u&&(e.draggable.enabled=u,d.$broadcast("gridster-draggable-changed",e)),B=C=0,k(a),!0}var o,p,q,r,s,t,u,v,w=h,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=9999,F=0,G=function(){return(f.minSizeY?f.minSizeY:1)*e.curRowHeight-e.margins[0]},H=function(){return(f.minSizeX?f.minSizeX:1)*e.curColWidth-e.margins[1]},I=null;this.enable=function(){I||(I=a.element('
    '),c.append(I)),v=new b(I[0],l,m,n),v.enable()},this.disable=function(){I&&(I.remove(),I=null),v.disable(),v=void 0},this.destroy=function(){this.disable()}}var i=[],j=e.resizable.handles;"string"==typeof j&&(j=e.resizable.handles.split(","));for(var k=!1,l=0,m=j.length;l-1&&c>-1&&a.sizeX+c<=this.columns&&a.sizeY+b<=this.maxRows},this.autoSetItemPosition=function(a){for(var b=0;b=a.col&&d<=a.row+a.sizeY-1&&e>=a.row},this.removeItem=function(a){for(var b,c=0,d=this.grid.length;c-1;){for(var e=1,f=b;f>-1;){var g=this.grid[a];if(g){var h=g[f];if(h&&(!c||c.indexOf(h)===-1)&&h.sizeX>=e&&h.sizeY>=d)return h}++e,--f}--a,++d}return null},this.putItems=function(a){for(var b=0,c=a.length;b=b)){for(;a.row-1;){var h=this.getItems(g,b,d,c,a);if(0!==h.length)break;e=g,f=b,--g}null!==e&&this.putItem(a,e,f)}},this.updateHeight=function(a){var b=this.minRows;a=a||0;for(var c=this.grid.length;c>=0;--c){var d=this.grid[c];if(d)for(var e=0,f=d.length;e0?Math.min(this.maxRows,b):Math.max(this.maxRows,b)},this.updateColumnLayout=function(){for(var a=[],b=0,c=d.grid.length;bd.columns?(h.preferredX=h.sizeX,h.preferredY=h.sizeY,h.sizeX=d.columns,h.sizeY=Math.round(h.sizeX*h.sizeY/h.preferredX),h.sizeY=h.sizeY>0?h.sizeY:1,a.push(h)):h.col+h.sizeX>d.columns?a.push(h):d.autoSetItemPosition(h)}}for(var i=0,j=a.length;i',link:function(a,b,c,d){a.previewStyle=function(){return d.movingItem?{display:"block",height:d.movingItem.sizeY*d.curRowHeight-d.margins[0]+"px",width:d.movingItem.sizeX*d.curColWidth-d.margins[1]+"px",top:d.movingItem.row*d.curRowHeight+(d.outerMargin?d.margins[0]:0)+"px",left:d.movingItem.col*d.curColWidth+(d.outerMargin?d.margins[1]:0)+"px"}:{display:"none"}}}}}).directive("gridster",["$timeout","$window","$rootScope","gridsterDebounce",function(b,c,d,e){return{scope:!0,restrict:"EAC",controller:"GridsterCtrl",controllerAs:"gridster",compile:function(f){return f.prepend('
    '),function(f,g,h,i){function j(){g.css("height",i.gridHeight*i.curRowHeight+(i.outerMargin?i.margins[0]:-i.margins[0])+"px")}function k(){if(i.dynamicColumns){var a=g[0].offsetWidth||parseInt(g.css("width"),10);if(!a)return;var b=i.outerMargin?2:1,c=b*i.margins[1]+parseInt(i.minWidthToAddANewColumn,10),d=Math.floor(a/c);db&&(d=b-p-r,z=h-d),q+ic&&(f=c-q-s,A=i-f),p+=d,q+=f,e.css({top:q+"px",left:p+"px"}),k(a),!0}function o(a){return!(!e.hasClass("gridster-item-moving")||e.hasClass("gridster-item-resizing"))&&(z=A=0,l(a),!0)}var p,q,r,s,t,u,v=0,w=0,x=0,y=0,z=0,A=0,B=0,C=0,D=b[0],E=["select","option","input","textarea","button"],F=null,G=null;this.enable=function(){if(F!==!0){if(F=!0,G)return void G.enable();G=new d(e[0],m,n,o),G.enable()}},this.disable=function(){F!==!1&&(F=!1,G&&G.disable())},this.toggle=function(a){a?this.enable():this.disable()},this.destroy=function(){this.disable()}}return e}]).factory("GridsterResizable",["GridsterTouch",function(b){function c(c,d,e,f,g){function h(h){function i(a){c.addClass("gridster-item-moving"),c.addClass("gridster-item-resizing"),e.movingItem=f,f.setElementSizeX(),f.setElementSizeY(),f.setElementPosition(),e.updateHeight(1),d.$apply(function(){e.resizable&&e.resizable.start&&e.resizable.start(a,c,g,f)})}function j(a){var b=f.row,i=f.col,j=f.sizeX,k=f.sizeY,l=e.resizable&&e.resizable.resize,m=f.col;["w","nw","sw"].indexOf(h)!==-1&&(m=e.pixelsToColumns(o,!1));var n=f.row;["n","ne","nw"].indexOf(h)!==-1&&(n=e.pixelsToRows(p,!1));var s=f.sizeX;["n","s"].indexOf(h)===-1&&(s=e.pixelsToColumns(q,!0));var t=f.sizeY;["e","w"].indexOf(h)===-1&&(t=e.pixelsToRows(r,!0));var u=n>-1&&m>-1&&s+m<=e.columns&&t+n<=e.maxRows;!u||e.pushing===!1&&0!==e.getItems(n,m,s,t,f).length||(f.row=n,f.col=m,f.sizeX=s,f.sizeY=t);var v=f.row!==b||f.col!==i||f.sizeX!==j||f.sizeY!==k;(l||v)&&d.$apply(function(){l&&e.resizable.resize(a,c,g,f)})}function k(a){c.removeClass("gridster-item-moving"),c.removeClass("gridster-item-resizing"),e.movingItem=null,f.setPosition(f.row,f.col),f.setSizeY(f.sizeY),f.setSizeX(f.sizeX),d.$apply(function(){e.resizable&&e.resizable.stop&&e.resizable.stop(a,c,g,f)})}function l(a){switch(a.which){case 1:break;case 2:case 3:return}return u=e.draggable.enabled,u&&(e.draggable.enabled=!1,d.$broadcast("gridster-draggable-changed",e)),z=a.pageX,A=a.pageY,o=parseInt(c.css("left"),10),p=parseInt(c.css("top"),10),q=c[0].offsetWidth,r=c[0].offsetHeight,s=f.sizeX,t=f.sizeY,i(a),!0}function m(a){var b=e.curWidth-1;x=a.pageX,y=a.pageY;var d=x-z+B,f=y-A+C;B=C=0,z=x,A=y;var g=f,h=d;return w.indexOf("n")>=0&&(r-g=0&&(r+gE&&(f=E-p-r,C=g-f),r+=f),w.indexOf("w")>=0&&(q-h=0&&(q+hb&&(d=b-o-q,B=h-d),q+=d),c.css({top:p+"px",left:o+"px",width:q+"px",height:r+"px"}),j(a),!0}function n(a){return e.draggable.enabled!==u&&(e.draggable.enabled=u,d.$broadcast("gridster-draggable-changed",e)),B=C=0,k(a),!0}var o,p,q,r,s,t,u,v,w=h,x=0,y=0,z=0,A=0,B=0,C=0,D=0,E=9999,F=0,G=function(){return(f.minSizeY?f.minSizeY:1)*e.curRowHeight-e.margins[0]},H=function(){return(f.minSizeX?f.minSizeX:1)*e.curColWidth-e.margins[1]},I=null;this.enable=function(){I||(I=a.element('
    '),c.append(I)),v=new b(I[0],l,m,n),v.enable()},this.disable=function(){I&&(I.remove(),I=null),v.disable(),v=void 0},this.destroy=function(){this.disable()}}var i=[],j=e.resizable.handles;"string"==typeof j&&(j=e.resizable.handles.split(","));for(var k=!1,l=0,m=j.length;l 0 ? Math.min(this.maxRows, maxHeight) : Math.max(this.maxRows, maxHeight); }; + /** + * Sets all the items in the first suitable position after a change in the number of columns available. + * + */ + this.updateColumnLayout = function() { + var didntFitItems = []; + + for (var rowIndex = 0, l = gridster.grid.length; rowIndex < l; ++rowIndex) { + var columns = gridster.grid[rowIndex]; + if (!columns) { + continue; + } + + for (var colIndex = 0, len = columns.length; colIndex < len; ++colIndex) { + if (columns[colIndex]) { + var item = columns[colIndex]; + + // If an item was resized it regains its original size to check if it fits now with its original size + if (item.preferredX !== undefined) { + item.sizeX = item.preferredX; + item.sizeY = item.preferredY; + } + if (item.sizeX > gridster.columns) { + // doesn't fit, we store its original size for a later reassignation if possible + item.preferredX = item.sizeX; + item.preferredY = item.sizeY; + + item.sizeX = gridster.columns; + item.sizeY = Math.round((item.sizeX * item.sizeY) / item.preferredX); // to mantain original proportion + item.sizeY = item.sizeY > 0 ? item.sizeY : 1; + + didntFitItems.push(item); + } else if (item.col + item.sizeX > gridster.columns) { + didntFitItems.push(item); + } else { + gridster.autoSetItemPosition(item); + } + } + } + } + + for (var itemlIndex = 0, length = didntFitItems.length; itemlIndex < length; ++itemlIndex) { + gridster.autoSetItemPosition(didntFitItems[itemlIndex]); + } + + didntFitItems.length = 0; + }; + /** * Returns the number of rows that will fit in given amount of pixels * @@ -696,6 +746,28 @@ gridster.updateHeight(gridster.movingItem ? gridster.movingItem.sizeY : 0); }); + function calculateColumns() { + if (gridster.dynamicColumns) { + var width = $elem[0].offsetWidth || parseInt($elem.css('width'), 10); + + if (!width) { + return; + } + + var numberOfMargins = gridster.outerMargin ? 2 : 1; + var minColWidth = (numberOfMargins * gridster.margins[1]) + parseInt(gridster.minWidthToAddANewColumn, 10); + var columns = Math.floor(width / minColWidth); + + if (columns < gridster.minColumns) { + columns = gridster.minColumns; + } + + if (columns !== gridster.columns) { + gridster.columns = columns; + } + } + } + function refresh(config) { gridster.setOptions(config); @@ -792,6 +864,26 @@ $rootScope.$broadcast('gridster-resizable-changed', gridster); }, true); + scope.$watch(function() { + return gridster.columns; + }, function() { + $rootScope.$broadcast('gridster-columns-changed', gridster); + }); + + scope.$watch(function() { + return gridster.dynamicColumns; + }, function() { + calculateColumns(); + refresh(); + }); + + scope.$watch(function() { + return gridster.minWidthToAddANewColumn; + }, function() { + calculateColumns(); + refresh(); + }); + var prevWidth = $elem[0].offsetWidth || parseInt($elem.css('width'), 10); var resize = function() { @@ -802,6 +894,8 @@ } prevWidth = width; + calculateColumns(); + if (gridster.loaded) { $elem.removeClass('gridster-loaded'); } @@ -2173,6 +2267,12 @@ }; updateDraggable(); + var updateColumnLayout = function() { + if (gridster.dynamicColumns) { + gridster.updateColumnLayout(); + } + }; + scope.$on('gridster-draggable-changed', updateDraggable); scope.$on('gridster-resizable-changed', updateResizable); scope.$on('gridster-resized', updateResizable); @@ -2180,6 +2280,7 @@ updateResizable(); updateDraggable(); }); + scope.$on('gridster-columns-changed', updateColumnLayout); function whichTransitionEvent() { var el = document.createElement('div'); diff --git a/test/spec/gridster-directive.js b/test/spec/gridster-directive.js index d3bf9e71..28e83069 100644 --- a/test/spec/gridster-directive.js +++ b/test/spec/gridster-directive.js @@ -143,4 +143,33 @@ describe('gridster directive', function() { })); }); + it('should broadcast "gridster-columns-changed" on columns change', function() { + // arrange + broadcastOnRootScope.calls.reset(); + + // act + GridsterCtrl.columns = 10; + + $scope.$digest(); + + // assert + expect(broadcastOnRootScope).toHaveBeenCalledWith('gridster-columns-changed', jasmine.objectContaining({ + columns: 10 + })); + }); + + it('number of columns should be different when enabling dynamicColumns and setting minWidthToAddANewColumn to a lower value', function() { + //precondition + expect(GridsterCtrl.columns).toBe(6); + + // act + GridsterCtrl.dynamicColumns = true; + GridsterCtrl.minWidthToAddANewColumn = 50; + + $scope.$digest(); + + // assert + expect(GridsterCtrl.columns).not.toBe(6); + }); + }); diff --git a/test/spec/gridster.js b/test/spec/gridster.js index fa6412d5..93988762 100644 --- a/test/spec/gridster.js +++ b/test/spec/gridster.js @@ -60,6 +60,7 @@ describe('GridsterCtrl', function() { expect(GridsterCtrl.mobileBreakPoint).toBe(600); expect(GridsterCtrl.resizable.enabled).toBe(true); expect(GridsterCtrl.draggable.enabled).toBe(true); + expect(GridsterCtrl.dynamicColumns).toBe(false); }); // todo: move these to e2e test