From 8d8f3a9a60ba76b421fa814874e1dfb6e4584168 Mon Sep 17 00:00:00 2001 From: Pavel Reznikov Date: Wed, 19 Nov 2014 20:53:40 -0800 Subject: [PATCH] add float option --- dist/gridstack.min.js | 2 +- src/gridstack.js | 82 +++++++++++++++++++++++++++++++------------ 2 files changed, 61 insertions(+), 23 deletions(-) diff --git a/dist/gridstack.min.js b/dist/gridstack.min.js index 252a319..3410d73 100644 --- a/dist/gridstack.min.js +++ b/dist/gridstack.min.js @@ -1 +1 @@ -!function(a,b){var c={is_intercepted: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)}},d=0,e=function(a,b){this.width=a,this.nodes=[],this.onchange=b||function(){}};e.prototype._fix_collisions=function(a){for(this._sort_nodes(-1);;){var d=b.find(this.nodes,function(b){return b!=a&&c.is_intercepted(b,a)},this);if("undefined"==typeof d)return;this.move_node(d,d.x,a.y+a.height,d.width,d.height,!0)}},e.prototype._sort_nodes=function(a){a=-1!=a?1:-1,this.nodes=b.sortBy(this.nodes,function(b){return a*(b.x+b.y*this.width)},this)},e.prototype._pack_nodes=function(){this._sort_nodes(),b.each(this.nodes,function(a,d){for(;a.y>0;){var e=a.y-1,f=0==d;if(d>0){var g=b.chain(this.nodes).first(d).find(function(b){return c.is_intercepted({x:a.x,y:e,width:a.width,height:a.height},b)}).value();f="undefined"==typeof g}if(!f)break;a._dirty=a.y!=e,a.y=e}},this)},e.prototype._prepare_node=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.auto_position=a.auto_position||!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.x=this.width-a.width:a.width=this.width-a.x),a.y<0&&(a.y=0),a},e.prototype._notify=function(){var a=Array.prototype.slice.call(arguments,1).concat(this.get_dirty_nodes());a=a.concat(this.get_dirty_nodes()),this.onchange(a)},e.prototype.clean_nodes=function(){b.each(this.nodes,function(a){a._dirty=!1})},e.prototype.get_dirty_nodes=function(){return b.filter(this.nodes,function(a){return a._dirty})},e.prototype.add_node=function(a){if(a=this._prepare_node(a),"undefined"!=typeof a.max_width&&(a.width=Math.min(a.width,a.max_width)),"undefined"!=typeof a.max_height&&(a.height=Math.min(a.height,a.max_height)),"undefined"!=typeof a.min_width&&(a.width=Math.max(a.width,a.min_width)),"undefined"!=typeof a.min_height&&(a.height=Math.max(a.height,a.min_height)),a._id=++d,a._dirty=!0,a.auto_position){this._sort_nodes();for(var e=0;;++e){var f=e%this.width,g=Math.floor(e/this.width);if(!b.find(this.nodes,function(b){return c.is_intercepted({x:f,y:g,width:a.width,height:a.height},b)})){a.x=f,a.y=g;break}}}return this.nodes.push(a),this._fix_collisions(a),this._pack_nodes(),this._notify(),a},e.prototype.remove_node=function(a){a._id=null,this.nodes=b.without(this.nodes,a),this._pack_nodes(),this._notify(a)},e.prototype.move_node=function(a,b,c,d,e,f){if("undefined"==typeof b&&(b=a.x),"undefined"==typeof c&&(c=a.y),"undefined"==typeof d&&(d=a.width),"undefined"==typeof e&&(e=a.height),"undefined"!=typeof a.max_width&&(d=Math.min(d,a.max_width)),"undefined"!=typeof a.max_height&&(e=Math.min(e,a.max_height)),"undefined"!=typeof a.min_width&&(d=Math.max(d,a.min_width)),"undefined"!=typeof a.min_height&&(e=Math.max(e,a.min_height)),a.x==b&&a.y==c&&a.width==d&&a.height==e)return a;var g=a.x!=b;return a._dirty=!0,a.x=b,a.y=c,a.width=d,a.height=e,a=this._prepare_node(a,g),this._fix_collisions(a),f||(this._pack_nodes(),this._notify()),a},e.prototype.get_grid_height=function(){return b.reduce(this.nodes,function(a,b){return Math.max(a,b.y+b.height)},0)};var f=function(a,c){var f,d=this;this.container=$(a),this.opts=b.defaults(c||{},{width:12,item_class:"grid-stack-item",placeholder_class:"grid-stack-placeholder",handle:".grid-stack-item-content",cell_height:60,vertical_margin:20,auto:!0,min_width:768}),this.grid=new e(this.opts.width,function(a){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)})}),this.opts.auto&&this.container.find("."+this.opts.item_class).each(function(a,b){d._prepare_element(b)}),this.placeholder=$('
').hide(),this.container.append(this.placeholder),this.container.height(this.grid.get_grid_height()*(this.opts.cell_height+this.opts.vertical_margin)-this.opts.vertical_margin);var g=function(){if(d._is_one_column_mode()){if(f)return;f=!0,b.each(d.grid.nodes,function(a){a.el.draggable("disable"),a.el.attr("data-gs-no-resize")||a.el.resizable("disable")})}else{if(!f)return;f=!1,b.each(d.grid.nodes,function(a){a.el.draggable("enable"),a.el.attr("data-gs-no-resize")||a.el.resizable("enable")})}};$(window).resize(g),g()};f.prototype._update_container_height=function(){this.container.height(this.grid.get_grid_height()*(this.opts.cell_height+this.opts.vertical_margin)-this.opts.vertical_margin)},f.prototype._is_one_column_mode=function(){return $(window).width()<=this.opts.min_width},f.prototype._prepare_element=function(a){var c=this;a=$(a);var d=c.grid.add_node({x:a.attr("data-gs-x"),y:a.attr("data-gs-y"),width:a.attr("data-gs-width"),height:a.attr("data-gs-height"),max_width:a.attr("data-gs-max-width"),min_width:a.attr("data-gs-min-width"),max_height:a.attr("data-gs-max-height"),min_height:a.attr("data-gs-min-height"),auto_position:a.attr("data-gs-auto-position"),el:a});a.data("_gridstack_node",d);var e,f=this.opts.cell_height+this.opts.vertical_margin/2,g=function(){var f=$(this);c.grid.clean_nodes(),e=Math.ceil(f.outerWidth()/f.attr("data-gs-width")),c.placeholder.attr("data-gs-x",f.attr("data-gs-x")).attr("data-gs-y",f.attr("data-gs-y")).attr("data-gs-width",f.attr("data-gs-width")).attr("data-gs-height",f.attr("data-gs-height")).show(),d.el=c.placeholder},h=function(){var f=$(this);d.el=f,c.placeholder.hide(),f.attr("data-gs-x",d.x).attr("data-gs-y",d.y).attr("data-gs-width",d.width).attr("data-gs-height",d.height).removeAttr("style"),c._update_container_height(),c.container.trigger("change",[c.grid.get_dirty_nodes()]),c.grid._sort_nodes(),b.each(c.grid.nodes,function(a){a.el.detach(),c.container.append(a.el)})};a.draggable({handle:this.opts.handle,scroll:!0,appendTo:"body",start:g,stop:h,drag:function(a,b){var g=Math.round(b.position.left/e),h=Math.floor(b.position.top/f);c.grid.move_node(d,g,h),c._update_container_height()}}),this._is_one_column_mode()&&a.draggable("disable"),a.attr("data-gs-no-resize")||(a.resizable({autoHide:!0,handles:"se",minHeight:this.opts.cell_height-10,minWidth:70,start:g,stop:h,resize:function(a,b){var g=Math.round(b.size.width/e),h=Math.round(b.size.height/f);c.grid.move_node(d,d.x,d.y,g,h),c._update_container_height()}}),this._is_one_column_mode()&&a.resizable("disable"))},f.prototype.add_widget=function(a,b,c,d,e,f){a=$(a),"undefined"!=typeof b&&a.attr("data-gs-x",b),"undefined"!=typeof c&&a.attr("data-gs-y",c),"undefined"!=typeof d&&a.attr("data-gs-width",d),"undefined"!=typeof e&&a.attr("data-gs-height",e),"undefined"!=typeof f&&a.attr("data-gs-auto-position",f),this.container.append(a),this._prepare_element(a),this._update_container_height()},f.prototype.remove_widget=function(a){var b=$(a).data("_gridstack_node");this.grid.remove_node(b),a.remove(),this._update_container_height()},a.GridStackUI=f,$.fn.gridstack=function(a){return this.each(function(){$(this).data("gridstack")||$(this).data("gridstack",new f(this,a))})}}(window,_); \ No newline at end of file +!function(a,b){var c={is_intercepted: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)}},d=0,e=function(a,b,c){this.width=a,this.float=c||!1,this.nodes=[],this.onchange=b||function(){}};e.prototype._fix_collisions=function(a){for(this._sort_nodes(-1);;){var d=b.find(this.nodes,function(b){return b!=a&&c.is_intercepted(b,a)},this);if("undefined"==typeof d)return;this.move_node(d,d.x,a.y+a.height,d.width,d.height,!0)}},e.prototype._sort_nodes=function(a){a=-1!=a?1:-1,this.nodes=b.sortBy(this.nodes,function(b){return a*(b.x+b.y*this.width)},this)},e.prototype._pack_nodes=function(){this._sort_nodes(),this.float?b.each(this.nodes,function(a){if(!a._updating&&"undefined"!=typeof a._orig_y&&a.y!=a._orig_y){var e=b.chain(this.nodes).find(function(b){return a!=b&&c.is_intercepted({x:a.x,y:a._orig_y,width:a.width,height:a.height},b)}).value();e||(a._dirty=!0,a.y=a._orig_y)}},this):b.each(this.nodes,function(a,d){for(;a.y>0;){var e=a.y-1,f=0==d;if(d>0){var g=b.chain(this.nodes).first(d).find(function(b){return c.is_intercepted({x:a.x,y:e,width:a.width,height:a.height},b)}).value();f="undefined"==typeof g}if(!f)break;a._dirty=a.y!=e,a.y=e}},this)},e.prototype._prepare_node=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.auto_position=a.auto_position||!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.x=this.width-a.width:a.width=this.width-a.x),a.y<0&&(a.y=0),a},e.prototype._notify=function(){var a=Array.prototype.slice.call(arguments,1).concat(this.get_dirty_nodes());a=a.concat(this.get_dirty_nodes()),this.onchange(a)},e.prototype.clean_nodes=function(){b.each(this.nodes,function(a){a._dirty=!1})},e.prototype.get_dirty_nodes=function(){return b.filter(this.nodes,function(a){return a._dirty})},e.prototype.add_node=function(a){if(a=this._prepare_node(a),"undefined"!=typeof a.max_width&&(a.width=Math.min(a.width,a.max_width)),"undefined"!=typeof a.max_height&&(a.height=Math.min(a.height,a.max_height)),"undefined"!=typeof a.min_width&&(a.width=Math.max(a.width,a.min_width)),"undefined"!=typeof a.min_height&&(a.height=Math.max(a.height,a.min_height)),a._id=++d,a._dirty=!0,a.auto_position){this._sort_nodes();for(var e=0;;++e){var f=e%this.width,g=Math.floor(e/this.width);if(!b.find(this.nodes,function(b){return c.is_intercepted({x:f,y:g,width:a.width,height:a.height},b)})){a.x=f,a.y=g;break}}}return this.nodes.push(a),this._fix_collisions(a),this._pack_nodes(),this._notify(),a},e.prototype.remove_node=function(a){a._id=null,this.nodes=b.without(this.nodes,a),this._pack_nodes(),this._notify(a)},e.prototype.move_node=function(a,b,c,d,e,f){if("undefined"==typeof b&&(b=a.x),"undefined"==typeof c&&(c=a.y),"undefined"==typeof d&&(d=a.width),"undefined"==typeof e&&(e=a.height),"undefined"!=typeof a.max_width&&(d=Math.min(d,a.max_width)),"undefined"!=typeof a.max_height&&(e=Math.min(e,a.max_height)),"undefined"!=typeof a.min_width&&(d=Math.max(d,a.min_width)),"undefined"!=typeof a.min_height&&(e=Math.max(e,a.min_height)),a.x==b&&a.y==c&&a.width==d&&a.height==e)return a;var g=a.x!=b;return a._dirty=!0,a.x=b,a.y=c,a.width=d,a.height=e,a=this._prepare_node(a,g),this._fix_collisions(a),f||(this._pack_nodes(),this._notify()),a},e.prototype.get_grid_height=function(){return b.reduce(this.nodes,function(a,b){return Math.max(a,b.y+b.height)},0)},e.prototype.begin_update=function(a){b.each(this.nodes,function(a){a._orig_y=a.y}),a._updating=!0},e.prototype.end_update=function(){var a=b.find(this.nodes,function(a){return a._updating});a&&(a._updating=!1)};var f=function(a,c){var f,d=this;this.container=$(a),this.opts=b.defaults(c||{},{width:12,item_class:"grid-stack-item",placeholder_class:"grid-stack-placeholder",handle:".grid-stack-item-content",cell_height:60,vertical_margin:20,auto:!0,min_width:768,"float":!1}),this.grid=new e(this.opts.width,function(a){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)})},this.opts.float),this.opts.auto&&this.container.find("."+this.opts.item_class).each(function(a,b){d._prepare_element(b)}),this.placeholder=$('
').hide(),this.container.append(this.placeholder),this.container.height(this.grid.get_grid_height()*(this.opts.cell_height+this.opts.vertical_margin)-this.opts.vertical_margin);var g=function(){if(d._is_one_column_mode()){if(f)return;f=!0,b.each(d.grid.nodes,function(a){a.el.draggable("disable"),a.el.attr("data-gs-no-resize")||a.el.resizable("disable")})}else{if(!f)return;f=!1,b.each(d.grid.nodes,function(a){a.el.draggable("enable"),a.el.attr("data-gs-no-resize")||a.el.resizable("enable")})}};$(window).resize(g),g()};f.prototype._update_container_height=function(){this.container.height(this.grid.get_grid_height()*(this.opts.cell_height+this.opts.vertical_margin)-this.opts.vertical_margin)},f.prototype._is_one_column_mode=function(){return $(window).width()<=this.opts.min_width},f.prototype._prepare_element=function(a){var c=this;a=$(a);var d=c.grid.add_node({x:a.attr("data-gs-x"),y:a.attr("data-gs-y"),width:a.attr("data-gs-width"),height:a.attr("data-gs-height"),max_width:a.attr("data-gs-max-width"),min_width:a.attr("data-gs-min-width"),max_height:a.attr("data-gs-max-height"),min_height:a.attr("data-gs-min-height"),auto_position:a.attr("data-gs-auto-position"),el:a});a.data("_gridstack_node",d);var e,f=this.opts.cell_height+this.opts.vertical_margin/2,g=function(){var f=$(this);c.grid.clean_nodes(),c.grid.begin_update(d),e=Math.ceil(f.outerWidth()/f.attr("data-gs-width")),c.placeholder.attr("data-gs-x",f.attr("data-gs-x")).attr("data-gs-y",f.attr("data-gs-y")).attr("data-gs-width",f.attr("data-gs-width")).attr("data-gs-height",f.attr("data-gs-height")).show(),d.el=c.placeholder},h=function(){var f=$(this);d.el=f,c.placeholder.hide(),f.attr("data-gs-x",d.x).attr("data-gs-y",d.y).attr("data-gs-width",d.width).attr("data-gs-height",d.height).removeAttr("style"),c._update_container_height(),c.container.trigger("change",[c.grid.get_dirty_nodes()]),c.grid.end_update(),c.grid._sort_nodes(),b.each(c.grid.nodes,function(a){a.el.detach(),c.container.append(a.el)})};a.draggable({handle:this.opts.handle,scroll:!0,appendTo:"body",start:g,stop:h,drag:function(a,b){var g=Math.round(b.position.left/e),h=Math.floor(b.position.top/f);c.grid.move_node(d,g,h),c._update_container_height()}}),this._is_one_column_mode()&&a.draggable("disable"),a.attr("data-gs-no-resize")||(a.resizable({autoHide:!0,handles:"se",minHeight:this.opts.cell_height-10,minWidth:70,start:g,stop:h,resize:function(a,b){var g=Math.round(b.size.width/e),h=Math.round(b.size.height/f);c.grid.move_node(d,d.x,d.y,g,h),c._update_container_height()}}),this._is_one_column_mode()&&a.resizable("disable"))},f.prototype.add_widget=function(a,b,c,d,e,f){a=$(a),"undefined"!=typeof b&&a.attr("data-gs-x",b),"undefined"!=typeof c&&a.attr("data-gs-y",c),"undefined"!=typeof d&&a.attr("data-gs-width",d),"undefined"!=typeof e&&a.attr("data-gs-height",e),"undefined"!=typeof f&&a.attr("data-gs-auto-position",f),this.container.append(a),this._prepare_element(a),this._update_container_height()},f.prototype.remove_widget=function(a){var b=$(a).data("_gridstack_node");this.grid.remove_node(b),a.remove(),this._update_container_height()},a.GridStackUI=f,$.fn.gridstack=function(a){return this.each(function(){$(this).data("gridstack")||$(this).data("gridstack",new f(this,a))})}}(window,_); \ No newline at end of file diff --git a/src/gridstack.js b/src/gridstack.js index a56c0e8..b5267a6 100644 --- a/src/gridstack.js +++ b/src/gridstack.js @@ -8,8 +8,9 @@ var id_seq = 0; - var GridStackEngine = function (width, onchange) { + var GridStackEngine = function (width, onchange, float) { this.width = width; + this.float = float || false; this.nodes = []; this.onchange = onchange || function () {}; @@ -38,28 +39,47 @@ GridStackEngine.prototype._pack_nodes = function () { this._sort_nodes(); - _.each(this.nodes, function (n, i) { - while (n.y > 0) { - var new_y = n.y - 1; - var can_be_moved = i == 0; + if (this.float) { + _.each(this.nodes, function (n, i) { + if (n._updating || typeof n._orig_y == 'undefined' || n.y == n._orig_y) + return; - if (i > 0) { - var collision_node = _.chain(this.nodes) - .first(i) - .find(function (bn) { - return Utils.is_intercepted({x: n.x, y: new_y, width: n.width, height: n.height}, bn); - }) - .value(); - can_be_moved = typeof collision_node == 'undefined'; - } + var collision_node = _.chain(this.nodes) + .find(function (bn) { + return n != bn && Utils.is_intercepted({x: n.x, y: n._orig_y, width: n.width, height: n.height}, bn); + }) + .value(); - if (!can_be_moved) { - break; + if (!collision_node) { + n._dirty = true; + n.y = n._orig_y; } - n._dirty = n.y != new_y; - n.y = new_y; - } - }, this); + }, this); + } + else { + _.each(this.nodes, function (n, i) { + while (n.y > 0) { + var new_y = n.y - 1; + var can_be_moved = i == 0; + + if (i > 0) { + var collision_node = _.chain(this.nodes) + .first(i) + .find(function (bn) { + return Utils.is_intercepted({x: n.x, y: new_y, width: n.width, height: n.height}, bn); + }) + .value(); + can_be_moved = typeof collision_node == 'undefined'; + } + + if (!can_be_moved) { + break; + } + n._dirty = n.y != new_y; + n.y = new_y; + } + }, this); + } }; GridStackEngine.prototype._prepare_node = function (node, moving) { @@ -194,6 +214,20 @@ return _.reduce(this.nodes, function (memo, n) { return Math.max(memo, n.y + n.height); }, 0); }; + GridStackEngine.prototype.begin_update = function (node) { + _.each(this.nodes, function (n) { + n._orig_y = n.y; + }); + node._updating = true; + }; + + GridStackEngine.prototype.end_update = function () { + var n = _.find(this.nodes, function (n) { return n._updating; }); + if (n) { + n._updating = false; + } + }; + var GridStack = function (el, opts) { var self = this, one_column_mode; @@ -207,7 +241,8 @@ cell_height: 60, vertical_margin: 20, auto: true, - min_width: 768 + min_width: 768, + float: false }); this.grid = new GridStackEngine(this.opts.width, function (nodes) { @@ -223,7 +258,7 @@ .attr('data-gs-height', n.height); } }); - }); + }, this.opts.float); if (this.opts.auto) { this.container.find('.' + this.opts.item_class).each(function (index, el) { @@ -299,6 +334,7 @@ var on_start_moving = function (event, ui) { var o = $(this); self.grid.clean_nodes(); + self.grid.begin_update(node); cell_width = Math.ceil(o.outerWidth() / o.attr('data-gs-width')); self.placeholder .attr('data-gs-x', o.attr('data-gs-x')) @@ -322,6 +358,8 @@ self._update_container_height(); self.container.trigger('change', [self.grid.get_dirty_nodes()]); + self.grid.end_update(); + self.grid._sort_nodes(); _.each(self.grid.nodes, function (node) { node.el.detach();