diff --git a/README.md b/README.md index f0eec26..c39da0c 100644 --- a/README.md +++ b/README.md @@ -81,12 +81,8 @@ $.Gridstrap.defaultOptions = { resizeHandleSelector: null, // jQuery selector relative to cell for resize handling. Null disables. resizeOnDrag: true, // toggle mouse resizing. swapMode: false, // toggle swap or insert mode when rearranging cells. - nonContiguousOptions: { // TODO// TODO// TODO// TODO - selector: null, - getHtml: function () { - return null; - } - }, + nonContiguousCellHtml: null, // html to use for non-contiguous placeholder cells. + autoPadNonContiguousCells: true, // toggle adding non-contiguous cells automatically on drag or as otherwise needed. updateCoordinatesOnWindowResize: true, // enable window resize event handler. debug: false, // toggle console output. dragMouseoverThrottle: 500, // throttle cell mouseover events for rearranging. @@ -254,6 +250,19 @@ Move a cell within the grid. Nothing. +#### [.padWithNonContiguousCells](src/methods.js) + +Explicitly append non-contiguous cells to set of current cells. These cells are added automatically as required if the `autoPadNonContiguousCells` option is enabled, but for performance and behaviour reasons it may be better to setup a grid using this method. + +**Params** + +* `callback` **{Function}**: Provide a function with two Number parameters, `cellCount` and `nonContiguousCellCount`. Return `true` to append a new non-contiguous cell to the grid. The function will be continuously be called until `false` is returned. + +**Returns** + +Nothing. + + #### [.removeCell](src/methods.js) Detach an existing cell from the grid and then removes it from the DOM. @@ -352,16 +361,7 @@ Triggered when a visible cell is being resized. Can be prevented. * `width` **{Number}**: Width of cell. * `height` **{Number}**: Height of cell. -* `target` **{Element}**: Visible cell being resized. - -#### [noncontiguouschange](src/constants.js) - -Triggered when the quantity of non-contiguous placeholder elements change. Can be prevented. - -**Event data** -TODO - - +* `target` **{Element}**: Visible cell being resized. diff --git a/dist/jquery.gridstrap.css b/dist/jquery.gridstrap.css index d78a140..9f967dc 100644 --- a/dist/jquery.gridstrap.css +++ b/dist/jquery.gridstrap.css @@ -23,5 +23,5 @@ z-index: 10000; } .gridstack-noncontiguous{ - opacity: 0.02; + opacity: 0; } \ No newline at end of file diff --git a/dist/jquery.gridstrap.js b/dist/jquery.gridstrap.js index 888b753..ccb1dbe 100644 --- a/dist/jquery.gridstrap.js +++ b/dist/jquery.gridstrap.js @@ -26,9 +26,9 @@ exports['default'] = { EVENT_CELL_RESIZE: 'cellresize', EVENT_CELL_DRAG: 'celldrag', EVENT_CELL_REDRAW: 'cellredraw', - EVENT_NONCONTIGUOUS_CONTAINER_CHANGE: 'noncontiguouschange', - ERROR_MISSING_JQUERY: 'Requires jQuery v?', - ERROR_INVALID_ATTACH_ELEMENT: 'Cannot attach element that is not a child of gridstrap parent' + ERROR_MISSING_JQUERY: 'Requires jQuery v?', //TODO + ERROR_INVALID_ATTACH_ELEMENT: 'Cannot attach element that is not a child of gridstrap parent.', + ERROR_NONCONTIGUOUS_HTML_UNDEFINED: 'nonContiguousCellHtml option cannot be null.' }; module.exports = exports['default']; @@ -136,7 +136,8 @@ var _methods = require('./methods'); resizeHandleSelector: null, // jQuery selector relative to cell for resize handling. Null disables. resizeOnDrag: true, // toggle mouse resizing. swapMode: false, // toggle swap or insert mode when rearranging cells. - nonContiguousCellHtml: null, // enable non-contiguous mode using this html for a placeholder cell. + nonContiguousCellHtml: null, // html to use for non-contiguous placeholder cells. + autoPadNonContiguousCells: true, // toggle adding non-contiguous cells automatically on drag or as needed. updateCoordinatesOnWindowResize: true, // enable window resize event handler. debug: false, // toggle console output. dragMouseoverThrottle: 500, // throttle cell mouseover events for rearranging. @@ -286,7 +287,7 @@ var Handlers = (function () { this.internal.MoveDraggedCell(mouseEvent, $draggedCell); - if (options.nonContiguousCellHtml && options.rearrangeOnDrag) { + if (options.nonContiguousCellHtml && options.rearrangeOnDrag && options.autoPadNonContiguousCells) { this.internal.UpdateNonContiguousCellsForDrag($draggedCell, mouseEvent); } } @@ -324,7 +325,8 @@ var Handlers = (function () { var $draggedCell = this.internal.$GetDraggingCell(); if ($draggedCell.length > 0) { - if (options.nonContiguousCellHtml && !options.rearrangeOnDrag) { + if (options.nonContiguousCellHtml && !options.rearrangeOnDrag && options.autoPadNonContiguousCells) { + this.internal.UpdateNonContiguousCellsForDrag($draggedCell, mouseEvent); // mouse event may be over a new placeholder cell now. @@ -800,21 +802,38 @@ var Internal = (function () { }; Internal.prototype.UpdateNonContiguousCellsForDrag = function UpdateNonContiguousCellsForDrag($draggedCell, mouseEvent) { - var draggedCellPositionAndSize = _utils.Utils.GetPositionAndSizeOfCell($draggedCell); + var $ = this.setup.jQuery; + var options = this.setup.Options; + + var furthestVisibleCellPositionAndSize = _utils.Utils.GetPositionAndSizeOfCell($draggedCell); + + var compare = function compare(positionAndSize) { + return positionAndSize.left + positionAndSize.width + (positionAndSize.top + positionAndSize.height) * 100000; + }; + var $hiddenCells = this.$GetHiddenCellsInElementOrder(); + $hiddenCells.each(function (i, e) { + if (!$(e).data(_constants2['default'].DATA_VISIBLE_CELL).hasClass(options.nonContiguousPlaceholderCellClass)) { + var positionAndSize = _utils.Utils.GetPositionAndSizeOfCell($(e)); + + if (compare(positionAndSize) > compare(furthestVisibleCellPositionAndSize)) { + furthestVisibleCellPositionAndSize = positionAndSize; + } + } + }); var changed = this.AppendOrRemoveNonContiguousCellsWhile(function ($hiddenCells, appending) { var lastHiddenCellPositionAndSize = _utils.Utils.GetPositionAndSizeOfCell($hiddenCells.last()); + // A whole row of extra cells should exist. if (appending) { - // if making new placeholder cells, then a whole row of extra cells should exist. - return lastHiddenCellPositionAndSize.top - draggedCellPositionAndSize.top < draggedCellPositionAndSize.height * 2; + // need at least 2* cell height worht of space at bottom of grid. + return lastHiddenCellPositionAndSize.top - furthestVisibleCellPositionAndSize.top < furthestVisibleCellPositionAndSize.height * 2; } else { - return lastHiddenCellPositionAndSize.top - draggedCellPositionAndSize.top > draggedCellPositionAndSize.height * 2; + return lastHiddenCellPositionAndSize.top - furthestVisibleCellPositionAndSize.top > furthestVisibleCellPositionAndSize.height * 2; } }); if (changed) { - // insert/remove triggers a repositioning, so have to set dragged cell to mousepos again. this.MoveDraggedCell(mouseEvent, $draggedCell); } }; @@ -824,18 +843,9 @@ var Internal = (function () { var options = this.setup.Options; var context = this.setup.Context; - var $hiddenCells = this.$GetHiddenCellsInElementOrder(); var changed = false; - // remove cells at end when we have too much. - var $lastHiddenCell = $hiddenCells.last(); - var $bottomRowHiddenCells = null; - var $getBottomRowHiddenCells = function $getBottomRowHiddenCells() { - $bottomRowHiddenCells = $bottomRowHiddenCells || $hiddenCells.filter(function (i, e) { - return _utils.Utils.GetPositionAndSizeOfCell($(e)).top === _utils.Utils.GetPositionAndSizeOfCell($lastHiddenCell).top; - }); - return $bottomRowHiddenCells; - }; + var $hiddenCells = this.$GetHiddenCellsInElementOrder(); while (appendWhilePredicate($hiddenCells, true)) { // if mouse beyond or getting near end of static hidden element, then make some placeholder ones. @@ -849,9 +859,21 @@ var Internal = (function () { changed = true; } + // remove cells at end when we have too much. + var $lastHiddenCell = $hiddenCells.last(); + var $bottomRowHiddenCells = null; + var $getBottomRowHiddenCells = function $getBottomRowHiddenCells() { + $bottomRowHiddenCells = $bottomRowHiddenCells || $hiddenCells.filter(function (i, e) { + return _utils.Utils.GetPositionAndSizeOfCell($(e)).top === _utils.Utils.GetPositionAndSizeOfCell($lastHiddenCell).top; + }); + return $bottomRowHiddenCells; + }; + + // remove all non-contiguous bottom row cells. while (appendWhilePredicate($hiddenCells, false) && $getBottomRowHiddenCells().filter(function (i, e) { return $(e).data(_constants2['default'].DATA_VISIBLE_CELL).hasClass(options.nonContiguousPlaceholderCellClass); - }).length === $getBottomRowHiddenCells().length) { + }).length === $getBottomRowHiddenCells().length && $getBottomRowHiddenCells().length > 0) { + // while all bottom row cells are placeholders. context.removeCell($lastHiddenCell.data(_constants2['default'].DATA_VISIBLE_CELL)); $hiddenCells = $hiddenCells.not($lastHiddenCell); @@ -991,6 +1013,7 @@ var Methods = (function () { Methods.prototype.insertCell = function insertCell(cellHtml, index) { var $ = this.setup.jQuery; + var options = this.setup.Options; var $element = this.setup.$Element; var $existingHiddenCells = this.internal.$GetHiddenCellsInElementOrder(); @@ -998,6 +1021,22 @@ var Methods = (function () { index = $existingHiddenCells.length; // insert at end. } + if (index > $existingHiddenCells.length && options.nonContiguousCellHtml && options.autoPadNonContiguousCells) { + + this.internal.AppendOrRemoveNonContiguousCellsWhile(function ($hiddenCells, appending) { + + if (!appending) { + // do not remove when trying to remove. + return false; + } + // insert placeholders until quantity of cells is index -1. + return $hiddenCells.length < index; + }); + + // update these. + $existingHiddenCells = this.internal.$GetHiddenCellsInElementOrder(); + } + var $insertedCell; if (index === $existingHiddenCells.length) { if ($existingHiddenCells.length === 0) { @@ -1070,12 +1109,29 @@ var Methods = (function () { Methods.prototype.moveCell = function moveCell(element, toIndex, targetGridstrap) { // targetGridstrap optional.. + var options = this.setup.Options; var context = this.setup.Context; - var cellNIndex = this.internal.GetCellAndInternalIndex(element); - var $existingVisibleCells = this.$getCells(); + if (toIndex > $existingVisibleCells.length && options.nonContiguousCellHtml && options.autoPadNonContiguousCells) { + + this.internal.AppendOrRemoveNonContiguousCellsWhile(function ($hiddenCells, appending) { + + if (!appending) { + // do not remove when trying to remove. + return false; + } + // insert placeholders until quantity of cells is index -1. + return $hiddenCells.length <= toIndex; + }); + + // update these. + $existingVisibleCells = this.$getCells(); + } + + var cellNIndex = this.internal.GetCellAndInternalIndex(element); + this.internal.MoveCell(cellNIndex.$cell, $existingVisibleCells.eq(toIndex), targetGridstrap || context); }; @@ -1198,12 +1254,25 @@ var Methods = (function () { var $ = this.setup.jQuery; var options = this.setup.Options; + if (!options.nonContiguousCellHtml) { + throw new Error(_constants2['default'].ERROR_NONCONTIGUOUS_HTML_UNDEFINED); + } + var $attachedHiddenCells = this.internal.$GetHiddenCellsInElementOrder(); this.internal.AppendOrRemoveNonContiguousCellsWhile(function ($hiddenCells, appending) { - return callback($hiddenCells.length, $hiddenCells.filter(function (i, e) { + + if (!appending) { + // do not remove, when trying to remove. + // only append/pad. + return false; + } + var cellCount = $hiddenCells.length; + var placeHolderCount = $hiddenCells.filter(function (i, e) { return $(e).data(_constants2['default'].DATA_VISIBLE_CELL).hasClass(options.nonContiguousPlaceholderCellClass); - }).length, appending); + }).length; + + return callback(cellCount, placeHolderCount); }); }; diff --git a/dist/jquery.gridstrap.min.js b/dist/jquery.gridstrap.min.js index b8d1765..67bec3a 100644 --- a/dist/jquery.gridstrap.min.js +++ b/dist/jquery.gridstrap.min.js @@ -7,5 +7,5 @@ * Under MIT License */ -!function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c||a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g=p.length)break;s=p[r++]}else{if(r=p.next(),r.done)break;s=r.value}var t=s,u=o[t];u instanceof Function&&u!==j.Methods&&(k[t]=u.bind(o))}m.InitOriginalCells(),m.InitEventHandlers(n),k.options.debug&&console.log("Gridstrap initialised for element: "+k.el.nodeName)},a.Gridstrap.defaultOptions={gridCellSelector:">*",hiddenCellClass:"gridstrap-cell-hidden",visibleCellClass:"gridstrap-cell-visible",nonContiguousPlaceholderCellClass:"gridstack-noncontiguous",dragCellClass:"gridstrap-cell-drag",resizeCellClass:"gridstrap-cell-resize",mouseMoveSelector:"body",visibleCellContainerParentSelector:null,visibleCellContainerClass:"gridstrap-container",getHtmlOfSourceCell:function(a){return a[0].outerHTML},dragCellHandleSelector:"*",draggable:!0,rearrangeOnDrag:!0,resizeHandleSelector:null,resizeOnDrag:!0,swapMode:!1,nonContiguousCellHtml:null,updateCoordinatesOnWindowResize:!0,debug:!1,dragMouseoverThrottle:500,windowResizeDebounce:50,mousemoveDebounce:0},a.fn.gridstrap=function(b){return this.each(function(){new a.Gridstrap(this,b)})}}(jQuery,window,document)},{"./constants":1,"./handlers":3,"./internal":4,"./methods":5,"./setup":6,"./utils":7}],3:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{default:a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}c.__esModule=!0;var f=a("./constants"),g=d(f),h=a("./utils"),i=function(){function a(b,c){e(this,a),this.setup=b,this.internal=c}return a.prototype.onDragstart=function(a,b,c){c===this.setup.Context&&a.preventDefault()},a.prototype.onMousedown=function(a,b,c){var d=this.setup.jQuery,e=this.setup.Context,f=this.setup.Options;if(c===e&&!b.hasClass(f.nonContiguousPlaceholderCellClass))return f.resizeHandleSelector&&d(a.target).closest(f.resizeHandleSelector).length?void(b.hasClass(f.resizeCellClass)||(b.addClass(f.resizeCellClass),this.internal.SetMouseDownData(a,b))):void(f.draggable&&!b.hasClass(f.dragCellClass)&&(this.internal.SetMouseDownData(a,b),b.addClass(f.dragCellClass),this.internal.MoveDraggedCell(a,b)))},a.prototype.onMouseover=function(a,b,c){var d=this.setup.jQuery,e=(this.setup.Context,this.setup.Options);if(this.internal.LastMouseOverCellTarget=null,c.options.draggable){var f=this.internal.$GetDraggingCell();f.length&&b.length&&!f.closest(b).length&&(this.internal.LastMouseOverCellTarget=b,h.Utils.IsElementThrottled(d,b,e.dragMouseoverThrottle)||c.options.rearrangeOnDrag&&(this.internal.MoveCell(f,b,c),this.internal.MoveDraggedCell(a,f)))}},a.prototype.onMousemove=function(a){var b=this.setup.jQuery,c=(this.setup.Context,this.setup.Options),d=b(this.setup.ResizeCellSelector);if(d.length){var e=d.data(g.default.DATA_MOUSEDOWN_POSITION_DIFF),f=d.data(g.default.DATA_MOUSEDOWN_SIZE),i=d.data(g.default.DATA_CELL_POSITION_AND_SIZE),j=h.Utils.GetAbsoluteOffsetForElementFromMouseEvent(d,a,e),k=f.width+j.left-i.left,l=f.height+j.top-i.top;d.css("width",k),d.css("height",l),c.resizeOnDrag&&this.internal.ResizeCell(d,k,l)}else{var m=this.internal.$GetDraggingCell();m.length&&(this.internal.MoveDraggedCell(a,m),c.nonContiguousCellHtml&&c.rearrangeOnDrag&&this.internal.UpdateNonContiguousCellsForDrag(m,a))}},a.prototype.onMouseup=function(a){var b=this.setup.jQuery,c=this.setup.Context,d=this.setup.Options;this.setup.$Element,this.setup.Document;if(d.draggable){var e=b(this.setup.ResizeCellSelector);if(d.resizeHandleSelector&&e.length){if(!d.resizeOnDrag){var f=(e.data(g.default.DATA_MOUSEDOWN_POSITION_DIFF),originalMouseDownCellPosition.w+a.pageX-originalMouseDownPagePosition.x),i=originalMouseDownCellPosition.h+a.pageY-originalMouseDownPagePosition.y;this.internal.ResizeCell(e,f,i)}return e.removeClass(d.resizeCellClass),void h.Utils.ClearMouseDownData(e)}var j=this.internal.$GetDraggingCell();if(j.length>0){if(d.nonContiguousCellHtml&&!d.rearrangeOnDrag){this.internal.UpdateNonContiguousCellsForDrag(j,a);var k=this.internal.$GetNonDraggedCellFromPoint(j,a);k.length?this.internal.LastMouseOverCellTarget=k:this.internal.LastMouseOverCellTarget=null}j.removeClass(d.dragCellClass),h.Utils.ClearMouseDownData(e);var l=j.data(g.default.DATA_CELL_POSITION_AND_SIZE);c.setCellAbsolutePositionAndSize(j,l),this.internal.LastMouseOverCellTarget&&!d.rearrangeOnDrag&&this.internal.MoveCell(j,this.internal.LastMouseOverCellTarget,c)}}},a}();c.Handlers=i},{"./constants":1,"./utils":7}],4:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{default:a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}c.__esModule=!0;var f=function(){function a(a,b){for(var c=0;c0){this.$GetClosestGridstrap(d).is(c.$el)&&(e={index:f,$cell:this.CellsArray[f]})}}return e},a.prototype.$GetClosestGridstrap=function(a){var b=this.setup.jQuery,c=function(a){return b(a).filter(function(){return!!b(this).data(h.default.DATA_GRIDSTRAP)})},d=c(a);return d.length?d.first():c(b(a).parents()).first()},a.prototype.$GetDraggingCell=function(){var a=this.setup.jQuery,b=this.setup.Context,c=(this.setup.Options,a(this.setup.DragCellSelector));return c.length&&this.$GetClosestGridstrap(c).is(b.$el)?c:a()},a.prototype.MoveCell=function(a,b,c){var d=this.setup.jQuery,e=this.setup.Context,f=this.setup.Options,g=a.data(h.default.DATA_HIDDEN_CELL),j=b.data(h.default.DATA_HIDDEN_CELL);if(!g.is(j))if(c!==e){if(this.AdditionalGridstrapDragTargetSelector){var k=d(this.AdditionalGridstrapDragTargetSelector).filter(function(){return d(this).data(h.default.DATA_GRIDSTRAP)===c}).first();if(k.length){if(f.swapMode){var l=i.Utils.GetPositionAndSizeOfCell(b),m=i.Utils.GetPositionAndSizeOfCell(a),n=c.detachCell(b),o=e.detachCell(a),p=o.hasClass(f.dragCellClass);p&&o.removeClass(f.dragCellClass),i.Utils.SwapJQueryElements(o,n);var q=c.attachCell(o),r=e.attachCell(n);i.Utils.ClearAbsoluteCSS(q),i.Utils.ClearAbsoluteCSS(r),c.setCellAbsolutePositionAndSize(q,m),e.setCellAbsolutePositionAndSize(r,l),c.setCellAbsolutePositionAndSize(q,l),e.setCellAbsolutePositionAndSize(r,m),p&&q.addClass(f.dragCellClass)}else{var m=i.Utils.GetPositionAndSizeOfCell(a),o=e.detachCell(a),p=o.hasClass(f.dragCellClass);p&&o.removeClass(f.dragCellClass),i.Utils.DetachAndInsertInPlaceJQueryElement(o,j);var q=c.attachCell(o);q.removeClass(f.visibleCellClass),c.setCellAbsolutePositionAndSize(q,m),q.addClass(f.visibleCellClass),p&&q.addClass(f.dragCellClass)}c.updateVisibleCellCoordinates(),e.updateVisibleCellCoordinates()}}}else f.swapMode?i.Utils.SwapJQueryElements(g,j):i.Utils.DetachAndInsertInPlaceJQueryElement(g,j),e.updateVisibleCellCoordinates()},a.prototype.ResizeCell=function(a,b,c){var d=this.setup.jQuery,e=this.setup.Context,f=this.setup.$Element,g=d.Event(h.default.EVENT_CELL_RESIZE,{width:b,height:c,target:a[0]});if(f.trigger(g),!g.isDefaultPrevented()){var i=a.data(h.default.DATA_HIDDEN_CELL);i.css("width",b),i.css("height",c),e.updateVisibleCellCoordinates()}},a.prototype.$GetHiddenCellsInElementOrder=function(){var a=this.setup.jQuery,b=(this.setup.Options,this.setup.$Element),c=this;return b.find(this.setup.HiddenCellSelector).filter(function(){var b=a(this).data(h.default.DATA_VISIBLE_CELL);if(!b||!b.length)return!1;for(var d=0;d2*c.height})&&this.MoveDraggedCell(b,a)},a.prototype.AppendOrRemoveNonContiguousCellsWhile=function(a){for(var b=this.setup.jQuery,c=this.setup.Options,d=this.setup.Context,e=this.$GetHiddenCellsInElementOrder(),f=!1,g=e.last(),j=null,k=function(){return j=j||e.filter(function(a,c){return i.Utils.GetPositionAndSizeOfCell(b(c)).top===i.Utils.GetPositionAndSizeOfCell(g).top})};a(e,!0);){var l=d.insertCell(c.nonContiguousCellHtml,e.length);l.addClass(c.nonContiguousPlaceholderCellClass);var m=l.data(h.default.DATA_HIDDEN_CELL);e=e.add(m),f=!0}for(;a(e,!1)&&k().filter(function(a,d){return b(d).data(h.default.DATA_VISIBLE_CELL).hasClass(c.nonContiguousPlaceholderCellClass)}).length===k().length;)d.removeCell(g.data(h.default.DATA_VISIBLE_CELL)),e=e.not(g),g=e.last(),j=null,f=!0;return f},f(a,[{key:"AdditionalGridstrapDragTargetSelector",get:function(){return this.additionalGridstrapDragTargetSelector},set:function(a){this.additionalGridstrapDragTargetSelector=a}},{key:"LastMouseOverCellTarget",get:function(){return this.lastMouseOverCellTarget},set:function(a){this.lastMouseOverCellTarget=a}},{key:"CellsArray",get:function(){return this.cellsArray}}]),a}();c.Internal=j},{"./constants":1,"./utils":7}],5:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{default:a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}c.__esModule=!0;var f=a("./constants"),g=d(f),h=a("./utils"),i=function(){function a(b,c,d){e(this,a),this.setup=b,this.internal=c,this.handlers=d}return a.prototype.$getCellOfElement=function(a){var b=this.setup.jQuery,c=(this.setup.Context,this.setup.Options,this.internal.GetCellAndInternalIndex(a));return c?c.$cell:b()},a.prototype.setCellAbsolutePositionAndSize=function(a,b){var c=this.setup.jQuery,d=(this.setup.Context,this.setup.Options,this.setup.$Element),e=c.Event(g.default.EVENT_CELL_REDRAW,{left:b.left,top:b.top,width:b.width,height:b.height,target:a[0]});d.trigger(e),e.isDefaultPrevented()||(a.data(g.default.DATA_CELL_POSITION_AND_SIZE,b),a.css("left",b.left),a.css("top",b.top),a.css("width",b.width),a.css("height",b.height))},a.prototype.updateVisibleCellCoordinates=function(){for(var a=this.setup.jQuery,b=(this.setup.Context,this.setup.Options,0);b'),this.window=c,this.document=e,this.$=b,this.$el=g,this.context=h}return e(a,[{key:"Window",get:function(){return this.window}},{key:"Document",get:function(){return this.document}},{key:"jQuery",get:function(){return this.$}},{key:"Options",get:function(){return this.context.options},set:function(a){this.context.options=a}},{key:"$Element",get:function(){return this.$el}},{key:"Context",get:function(){return this.context}},{key:"$OriginalCells",get:function(){return this.$originalCells}},{key:"IdPrefix",get:function(){return this.idPrefix}},{key:"VisibleCellContainerSelector",get:function(){return this.visibleCellContainerSelector}},{key:"DragCellSelector",get:function(){return this.dragCellSelector}},{key:"ResizeCellSelector",get:function(){return this.resizeCellSelector}},{key:"VisibleCellContainerClassSelector",get:function(){return this.visibleCellContainerClassSelector}},{key:"HiddenCellSelector",get:function(){return this.hiddenCellSelector}}]),a}();c.Setup=g},{"./utils":7}],7:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{default:a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}c.__esModule=!0;var f=a("./constants"),g=d(f),h=function(){function a(){e(this,a)}return a.GenerateRandomId=function(){return Math.random().toString(36).substr(2,5)+Math.round(1e3*Math.random()).toString()},a.ConvertCssClassToJQuerySelector=function(a){return a.replace(/(^ *| +)/g,".")},a.Debounce=function(a,b,c){var d=void 0;return function(){var e=this,f=arguments,g=c||!b,h=function(){d=null,g||a.apply(e,f)};clearTimeout(d),d=setTimeout(h,b),g&&a.apply(e,f)}},a.IsElementThrottled=function(b,c,d){a.recentDragMouseOvers=a.recentDragMouseOvers||[];for(var e=new Date,f=e.getTime(),g=0;g0&&!e.is(d)?function(a){e.before(a)}:f.length>0&&!f.is(d)?function(a){f.after(a)}:e.length>0&&e.is(d)?function(a){g.prepend(a)}:function(a){g.append(a)}},d=c(a),e=c(b),f=a.detach(),g=b.detach();e(f),d(g)},a.DetachAndInsertInPlaceJQueryElement=function(a,b){var c=b.index(),d=a.index(),e=a.detach();c=p.length)break;s=p[r++]}else{if(r=p.next(),r.done)break;s=r.value}var t=s,u=o[t];u instanceof Function&&u!==j.Methods&&(k[t]=u.bind(o))}m.InitOriginalCells(),m.InitEventHandlers(n),k.options.debug&&console.log("Gridstrap initialised for element: "+k.el.nodeName)},a.Gridstrap.defaultOptions={gridCellSelector:">*",hiddenCellClass:"gridstrap-cell-hidden",visibleCellClass:"gridstrap-cell-visible",nonContiguousPlaceholderCellClass:"gridstack-noncontiguous",dragCellClass:"gridstrap-cell-drag",resizeCellClass:"gridstrap-cell-resize",mouseMoveSelector:"body",visibleCellContainerParentSelector:null,visibleCellContainerClass:"gridstrap-container",getHtmlOfSourceCell:function(a){return a[0].outerHTML},dragCellHandleSelector:"*",draggable:!0,rearrangeOnDrag:!0,resizeHandleSelector:null,resizeOnDrag:!0,swapMode:!1,nonContiguousCellHtml:null,autoPadNonContiguousCells:!0,updateCoordinatesOnWindowResize:!0,debug:!1,dragMouseoverThrottle:500,windowResizeDebounce:50,mousemoveDebounce:0},a.fn.gridstrap=function(b){return this.each(function(){new a.Gridstrap(this,b)})}}(jQuery,window,document)},{"./constants":1,"./handlers":3,"./internal":4,"./methods":5,"./setup":6,"./utils":7}],3:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{default:a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}c.__esModule=!0;var f=a("./constants"),g=d(f),h=a("./utils"),i=function(){function a(b,c){e(this,a),this.setup=b,this.internal=c}return a.prototype.onDragstart=function(a,b,c){c===this.setup.Context&&a.preventDefault()},a.prototype.onMousedown=function(a,b,c){var d=this.setup.jQuery,e=this.setup.Context,f=this.setup.Options;if(c===e&&!b.hasClass(f.nonContiguousPlaceholderCellClass))return f.resizeHandleSelector&&d(a.target).closest(f.resizeHandleSelector).length?void(b.hasClass(f.resizeCellClass)||(b.addClass(f.resizeCellClass),this.internal.SetMouseDownData(a,b))):void(f.draggable&&!b.hasClass(f.dragCellClass)&&(this.internal.SetMouseDownData(a,b),b.addClass(f.dragCellClass),this.internal.MoveDraggedCell(a,b)))},a.prototype.onMouseover=function(a,b,c){var d=this.setup.jQuery,e=(this.setup.Context,this.setup.Options);if(this.internal.LastMouseOverCellTarget=null,c.options.draggable){var f=this.internal.$GetDraggingCell();f.length&&b.length&&!f.closest(b).length&&(this.internal.LastMouseOverCellTarget=b,h.Utils.IsElementThrottled(d,b,e.dragMouseoverThrottle)||c.options.rearrangeOnDrag&&(this.internal.MoveCell(f,b,c),this.internal.MoveDraggedCell(a,f)))}},a.prototype.onMousemove=function(a){var b=this.setup.jQuery,c=(this.setup.Context,this.setup.Options),d=b(this.setup.ResizeCellSelector);if(d.length){var e=d.data(g.default.DATA_MOUSEDOWN_POSITION_DIFF),f=d.data(g.default.DATA_MOUSEDOWN_SIZE),i=d.data(g.default.DATA_CELL_POSITION_AND_SIZE),j=h.Utils.GetAbsoluteOffsetForElementFromMouseEvent(d,a,e),k=f.width+j.left-i.left,l=f.height+j.top-i.top;d.css("width",k),d.css("height",l),c.resizeOnDrag&&this.internal.ResizeCell(d,k,l)}else{var m=this.internal.$GetDraggingCell();m.length&&(this.internal.MoveDraggedCell(a,m),c.nonContiguousCellHtml&&c.rearrangeOnDrag&&c.autoPadNonContiguousCells&&this.internal.UpdateNonContiguousCellsForDrag(m,a))}},a.prototype.onMouseup=function(a){var b=this.setup.jQuery,c=this.setup.Context,d=this.setup.Options;this.setup.$Element,this.setup.Document;if(d.draggable){var e=b(this.setup.ResizeCellSelector);if(d.resizeHandleSelector&&e.length){if(!d.resizeOnDrag){var f=(e.data(g.default.DATA_MOUSEDOWN_POSITION_DIFF),originalMouseDownCellPosition.w+a.pageX-originalMouseDownPagePosition.x),i=originalMouseDownCellPosition.h+a.pageY-originalMouseDownPagePosition.y;this.internal.ResizeCell(e,f,i)}return e.removeClass(d.resizeCellClass),void h.Utils.ClearMouseDownData(e)}var j=this.internal.$GetDraggingCell();if(j.length>0){if(d.nonContiguousCellHtml&&!d.rearrangeOnDrag&&d.autoPadNonContiguousCells){this.internal.UpdateNonContiguousCellsForDrag(j,a);var k=this.internal.$GetNonDraggedCellFromPoint(j,a);k.length?this.internal.LastMouseOverCellTarget=k:this.internal.LastMouseOverCellTarget=null}j.removeClass(d.dragCellClass),h.Utils.ClearMouseDownData(e);var l=j.data(g.default.DATA_CELL_POSITION_AND_SIZE);c.setCellAbsolutePositionAndSize(j,l),this.internal.LastMouseOverCellTarget&&!d.rearrangeOnDrag&&this.internal.MoveCell(j,this.internal.LastMouseOverCellTarget,c)}}},a}();c.Handlers=i},{"./constants":1,"./utils":7}],4:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{default:a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}c.__esModule=!0;var f=function(){function a(a,b){for(var c=0;c0){this.$GetClosestGridstrap(d).is(c.$el)&&(e={index:f,$cell:this.CellsArray[f]})}}return e},a.prototype.$GetClosestGridstrap=function(a){var b=this.setup.jQuery,c=function(a){return b(a).filter(function(){return!!b(this).data(h.default.DATA_GRIDSTRAP)})},d=c(a);return d.length?d.first():c(b(a).parents()).first()},a.prototype.$GetDraggingCell=function(){var a=this.setup.jQuery,b=this.setup.Context,c=(this.setup.Options,a(this.setup.DragCellSelector));return c.length&&this.$GetClosestGridstrap(c).is(b.$el)?c:a()},a.prototype.MoveCell=function(a,b,c){var d=this.setup.jQuery,e=this.setup.Context,f=this.setup.Options,g=a.data(h.default.DATA_HIDDEN_CELL),j=b.data(h.default.DATA_HIDDEN_CELL);if(!g.is(j))if(c!==e){if(this.AdditionalGridstrapDragTargetSelector){var k=d(this.AdditionalGridstrapDragTargetSelector).filter(function(){return d(this).data(h.default.DATA_GRIDSTRAP)===c}).first();if(k.length){if(f.swapMode){var l=i.Utils.GetPositionAndSizeOfCell(b),m=i.Utils.GetPositionAndSizeOfCell(a),n=c.detachCell(b),o=e.detachCell(a),p=o.hasClass(f.dragCellClass);p&&o.removeClass(f.dragCellClass),i.Utils.SwapJQueryElements(o,n);var q=c.attachCell(o),r=e.attachCell(n);i.Utils.ClearAbsoluteCSS(q),i.Utils.ClearAbsoluteCSS(r),c.setCellAbsolutePositionAndSize(q,m),e.setCellAbsolutePositionAndSize(r,l),c.setCellAbsolutePositionAndSize(q,l),e.setCellAbsolutePositionAndSize(r,m),p&&q.addClass(f.dragCellClass)}else{var m=i.Utils.GetPositionAndSizeOfCell(a),o=e.detachCell(a),p=o.hasClass(f.dragCellClass);p&&o.removeClass(f.dragCellClass),i.Utils.DetachAndInsertInPlaceJQueryElement(o,j);var q=c.attachCell(o);q.removeClass(f.visibleCellClass),c.setCellAbsolutePositionAndSize(q,m),q.addClass(f.visibleCellClass),p&&q.addClass(f.dragCellClass)}c.updateVisibleCellCoordinates(),e.updateVisibleCellCoordinates()}}}else f.swapMode?i.Utils.SwapJQueryElements(g,j):i.Utils.DetachAndInsertInPlaceJQueryElement(g,j),e.updateVisibleCellCoordinates()},a.prototype.ResizeCell=function(a,b,c){var d=this.setup.jQuery,e=this.setup.Context,f=this.setup.$Element,g=d.Event(h.default.EVENT_CELL_RESIZE,{width:b,height:c,target:a[0]});if(f.trigger(g),!g.isDefaultPrevented()){var i=a.data(h.default.DATA_HIDDEN_CELL);i.css("width",b),i.css("height",c),e.updateVisibleCellCoordinates()}},a.prototype.$GetHiddenCellsInElementOrder=function(){var a=this.setup.jQuery,b=(this.setup.Options,this.setup.$Element),c=this;return b.find(this.setup.HiddenCellSelector).filter(function(){var b=a(this).data(h.default.DATA_VISIBLE_CELL);if(!b||!b.length)return!1;for(var d=0;df(e)&&(e=g)}}),this.AppendOrRemoveNonContiguousCellsWhile(function(a,b){var c=i.Utils.GetPositionAndSizeOfCell(a.last());return b?c.top-e.top<2*e.height:c.top-e.top>2*e.height})&&this.MoveDraggedCell(b,a)},a.prototype.AppendOrRemoveNonContiguousCellsWhile=function(a){for(var b=this.setup.jQuery,c=this.setup.Options,d=this.setup.Context,e=!1,f=this.$GetHiddenCellsInElementOrder();a(f,!0);){var g=d.insertCell(c.nonContiguousCellHtml,f.length);g.addClass(c.nonContiguousPlaceholderCellClass);var j=g.data(h.default.DATA_HIDDEN_CELL);f=f.add(j),e=!0}for(var k=f.last(),l=null,m=function(){return l=l||f.filter(function(a,c){return i.Utils.GetPositionAndSizeOfCell(b(c)).top===i.Utils.GetPositionAndSizeOfCell(k).top})};a(f,!1)&&m().filter(function(a,d){return b(d).data(h.default.DATA_VISIBLE_CELL).hasClass(c.nonContiguousPlaceholderCellClass)}).length===m().length&&m().length>0;)d.removeCell(k.data(h.default.DATA_VISIBLE_CELL)),f=f.not(k),k=f.last(),l=null,e=!0;return e},f(a,[{key:"AdditionalGridstrapDragTargetSelector",get:function(){return this.additionalGridstrapDragTargetSelector},set:function(a){this.additionalGridstrapDragTargetSelector=a}},{key:"LastMouseOverCellTarget",get:function(){return this.lastMouseOverCellTarget},set:function(a){this.lastMouseOverCellTarget=a}},{key:"CellsArray",get:function(){return this.cellsArray}}]),a}();c.Internal=j},{"./constants":1,"./utils":7}],5:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{default:a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}c.__esModule=!0;var f=a("./constants"),g=d(f),h=a("./utils"),i=function(){function a(b,c,d){e(this,a),this.setup=b,this.internal=c,this.handlers=d}return a.prototype.$getCellOfElement=function(a){var b=this.setup.jQuery,c=(this.setup.Context,this.setup.Options,this.internal.GetCellAndInternalIndex(a));return c?c.$cell:b()},a.prototype.setCellAbsolutePositionAndSize=function(a,b){var c=this.setup.jQuery,d=(this.setup.Context,this.setup.Options,this.setup.$Element),e=c.Event(g.default.EVENT_CELL_REDRAW,{left:b.left,top:b.top,width:b.width,height:b.height,target:a[0]});d.trigger(e),e.isDefaultPrevented()||(a.data(g.default.DATA_CELL_POSITION_AND_SIZE,b),a.css("left",b.left),a.css("top",b.top),a.css("width",b.width),a.css("height",b.height))},a.prototype.updateVisibleCellCoordinates=function(){for(var a=this.setup.jQuery,b=(this.setup.Context,this.setup.Options,0);bf.length&&d.nonContiguousCellHtml&&d.autoPadNonContiguousCells&&(this.internal.AppendOrRemoveNonContiguousCellsWhile(function(a,c){return!!c&&a.lengthf.length&&d.nonContiguousCellHtml&&d.autoPadNonContiguousCells&&(this.internal.AppendOrRemoveNonContiguousCellsWhile(function(a,c){return!!c&&a.length<=b}),f=this.$getCells());var g=this.internal.GetCellAndInternalIndex(a);this.internal.MoveCell(g.$cell,f.eq(b),c||e)},a.prototype.$getCellFromCoordinates=function(a,b){var c=this.setup.Document,d=this.setup.jQuery,e=c.elementFromPoint(a,b),f=this.internal.GetCellAndInternalIndex(e);return f?f.$cell:d()},a.prototype.getCellIndexFromCoordinates=function(a,b){var c=this.setup.Document,d=(this.setup.jQuery,c.elementFromPoint(a,b)),e=this.internal.GetCellAndInternalIndex(d);return e?this.$getCells().index(e.$cell):-1},a.prototype.$getCells=function(){var a=this.setup.jQuery,b=this.internal.$GetHiddenCellsInElementOrder(),c=b.map(function(){return a(this).data(g.default.DATA_VISIBLE_CELL)[0]});return a(c)},a.prototype.$getHiddenCells=function(){return this.internal.$GetHiddenCellsInElementOrder()},a.prototype.$getCellContainer=function(){return(0,this.setup.jQuery)(this.setup.VisibleCellContainerSelector)},a.prototype.updateOptions=function(a){var b=this.setup.jQuery,c=this.setup.Options;this.setup.Options=b.extend({},c,a)},a.prototype.getCellIndexOfElement=function(a){var b=this.$getCellOfElement(a);return this.$getCells().index(b)},a.prototype.setAdditionalGridstrapDragTarget=function(a){var b=this.setup.jQuery,c=this.handlers,d=this,e=g.default.EVENT_MOUSEOVER+".gridstrap-additional-"+this.setup.IdPrefix;d.internal.AdditionalGridstrapDragTargetSelector&&b(d.internal.AdditionalGridstrapDragTargetSelector).each(function(){b(b(this).data(g.default.DATA_GRIDSTRAP).options.visibleCellContainerParentSelector).off(e)}),d.internal.AdditionalGridstrapDragTargetSelector=a,d.internal.AdditionalGridstrapDragTargetSelector&&b(d.internal.AdditionalGridstrapDragTargetSelector).each(function(){d.internal.HandleCellMouseEvent(b(this).data(g.default.DATA_GRIDSTRAP),e,!1,c.onMouseover.bind(c))})},a.prototype.modifyCell=function(a,b){var c=this.setup.Context,d=this.$getCells().eq(a),e=d.data(g.default.DATA_HIDDEN_CELL),f=!1,h=!1;b.call(c,function(){return f=!0,d},function(){return h=!0,e}),f&&e.html(d.html()),this.updateVisibleCellCoordinates()},a.prototype.padWithNonContiguousCells=function(a){var b=this.setup.jQuery,c=this.setup.Options;if(!c.nonContiguousCellHtml)throw new Error(g.default.ERROR_NONCONTIGUOUS_HTML_UNDEFINED);this.internal.$GetHiddenCellsInElementOrder();this.internal.AppendOrRemoveNonContiguousCellsWhile(function(d,e){if(!e)return!1;var f=d.length,h=d.filter(function(a,d){return b(d).data(g.default.DATA_VISIBLE_CELL).hasClass(c.nonContiguousPlaceholderCellClass)}).length;return a(f,h)})},a}();c.Methods=i},{"./constants":1,"./utils":7}],6:[function(a,b,c){"use strict";function d(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}c.__esModule=!0;var e=function(){function a(a,b){for(var c=0;c'),this.window=c,this.document=e,this.$=b,this.$el=g,this.context=h}return e(a,[{key:"Window",get:function(){return this.window}},{key:"Document",get:function(){return this.document}},{key:"jQuery",get:function(){return this.$}},{key:"Options",get:function(){return this.context.options},set:function(a){this.context.options=a}},{key:"$Element",get:function(){return this.$el}},{key:"Context",get:function(){return this.context}},{key:"$OriginalCells",get:function(){return this.$originalCells}},{key:"IdPrefix",get:function(){return this.idPrefix}},{key:"VisibleCellContainerSelector",get:function(){return this.visibleCellContainerSelector}},{key:"DragCellSelector",get:function(){return this.dragCellSelector}},{key:"ResizeCellSelector",get:function(){return this.resizeCellSelector}},{key:"VisibleCellContainerClassSelector",get:function(){return this.visibleCellContainerClassSelector}},{key:"HiddenCellSelector",get:function(){return this.hiddenCellSelector}}]),a}();c.Setup=g},{"./utils":7}],7:[function(a,b,c){"use strict";function d(a){return a&&a.__esModule?a:{default:a}}function e(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")}c.__esModule=!0;var f=a("./constants"),g=d(f),h=function(){function a(){e(this,a)}return a.GenerateRandomId=function(){return Math.random().toString(36).substr(2,5)+Math.round(1e3*Math.random()).toString()},a.ConvertCssClassToJQuerySelector=function(a){return a.replace(/(^ *| +)/g,".")},a.Debounce=function(a,b,c){var d=void 0;return function(){var e=this,f=arguments,g=c||!b,h=function(){d=null,g||a.apply(e,f)};clearTimeout(d),d=setTimeout(h,b),g&&a.apply(e,f)}},a.IsElementThrottled=function(b,c,d){a.recentDragMouseOvers=a.recentDragMouseOvers||[];for(var e=new Date,f=e.getTime(),g=0;g0&&!e.is(d)?function(a){e.before(a)}:f.length>0&&!f.is(d)?function(a){f.after(a)}:e.length>0&&e.is(d)?function(a){g.prepend(a)}:function(a){g.append(a)}},d=c(a),e=c(b),f=a.detach(),g=b.detach();e(f),d(g)},a.DetachAndInsertInPlaceJQueryElement=function(a,b){var c=b.index(),d=a.index(),e=a.detach();cDemo
+
+
+
<div id="noncontiguous-grid">
+  <div class="col-xs-4 col-sm-2 col-md-1 cell"><div class="inner"></div></div>
+  <div class="col-xs-4 col-sm-2 col-md-1 cell"><div class="inner"></div></div> 
+  ...
+</div> 
+
+<script>
+  $('#noncontiguous-grid').gridstrap({
+    nonContiguousCellHtml: '<div class="col-xs-4 col-sm-2 col-md-1 cell"><div class="inner"></div></div>',
+    swapMode: true,
+    rearrangeOnDrag: false,
+    autoPadNonContiguousCells: false // We will explicitly init non-contiguous cells below.
+  });
+
+  var ncg = $('#noncontiguous-grid').data('gridstrap');
+  var $cells = ncg.$getCells(); 
+  var finalCellCount = 5 * 12; // 5 rows
+
+  // Create non-contiguous cells until the condition is met.
+  ncg.padWithNonContiguousCells(function(cellCount, nonContiguousCellCount) {
+    return cellCount < finalCellCount;
+  });
+
+  var moveRandomCell = function(){
+    var $cellToMove = $cells.eq(Math.floor(Math.random() * $cells.length));
+    var moveToIndex = Math.floor(Math.random() * finalCellCount);
+
+    ncg.moveCell($cellToMove, moveToIndex);
+  };
+
+  // Move some cells around to demonstrate effect.
+  moveRandomCell();
+  moveRandomCell();
+  moveRandomCell();
+  moveRandomCell();
+  moveRandomCell();
+</script>
+
+
diff --git a/docs/indexLocal.html b/docs/indexLocal.html index b4a9566..a6e8e17 100644 --- a/docs/indexLocal.html +++ b/docs/indexLocal.html @@ -181,6 +181,47 @@

Demo

+
+
+
<div id="noncontiguous-grid">
+  <div class="col-xs-4 col-sm-2 col-md-1 cell"><div class="inner"></div></div>
+  <div class="col-xs-4 col-sm-2 col-md-1 cell"><div class="inner"></div></div> 
+  ...
+</div> 
+
+<script>
+  $('#noncontiguous-grid').gridstrap({
+    nonContiguousCellHtml: '<div class="col-xs-4 col-sm-2 col-md-1 cell"><div class="inner"></div></div>',
+    swapMode: true,
+    rearrangeOnDrag: false,
+    autoPadNonContiguousCells: false // We will explicitly init non-contiguous cells below.
+  });
+
+  var ncg = $('#noncontiguous-grid').data('gridstrap');
+  var $cells = ncg.$getCells(); 
+  var finalCellCount = 5 * 12; // 5 rows
+
+  // Create non-contiguous cells until the condition is met.
+  ncg.padWithNonContiguousCells(function(cellCount, nonContiguousCellCount) {
+    return cellCount < finalCellCount;
+  });
+
+  var moveRandomCell = function(){
+    var $cellToMove = $cells.eq(Math.floor(Math.random() * $cells.length));
+    var moveToIndex = Math.floor(Math.random() * finalCellCount);
+
+    ncg.moveCell($cellToMove, moveToIndex);
+  };
+
+  // Move some cells around to demonstrate effect.
+  moveRandomCell();
+  moveRandomCell();
+  moveRandomCell();
+  moveRandomCell();
+  moveRandomCell();
+</script>
+
+
diff --git a/docs/indexscript.js b/docs/indexscript.js index 93dd3e8..276e917 100644 --- a/docs/indexscript.js +++ b/docs/indexscript.js @@ -80,21 +80,33 @@ $(function () { $('a[href="#noncontiguous-demo"]').on('shown.bs.tab', function () { $('#noncontiguous-grid').gridstrap({ - // nonContiguousOptions: { - // selector: '#gwgwe', - // getHtml: function () { - // return '
'; - // } - // }, nonContiguousCellHtml: '
', swapMode: true, - rearrangeOnDrag: false + rearrangeOnDrag: false, + autoPadNonContiguousCells: false // mousemoveDebounce: 10 }); - $('#noncontiguous-grid').data('gridstrap').padWithNonContiguousCells(function(cellCount, nonContiguousCellCount, appending) { - return appending && nonContiguousCellCount < 30; + var ncg = $('#noncontiguous-grid').data('gridstrap'); + var $cells = ncg.$getCells(); + var finalCellCount = 5 * 12; + + ncg.padWithNonContiguousCells(function(cellCount, nonContiguousCellCount) { + return cellCount < finalCellCount; }); + + var moveRandomCell = function(){ + var $cellToMove = $cells.eq(Math.floor(Math.random() * $cells.length)); + var moveToIndex = Math.floor(Math.random() * finalCellCount); + + ncg.moveCell($cellToMove, moveToIndex); + }; + + moveRandomCell(); + moveRandomCell(); + moveRandomCell(); + moveRandomCell(); + moveRandomCell(); }); $('a[href="#dual-demo"]').on('shown.bs.tab', function () { diff --git a/docs/indexstyle.css b/docs/indexstyle.css index b2664b6..e42e57d 100644 --- a/docs/indexstyle.css +++ b/docs/indexstyle.css @@ -336,9 +336,8 @@ margin:0px; .site-footer-credits { color: #819198; } -#basic-grid{ - margin-top:15px; - margin-bottom:15px; +.tab-content>.tab-pane{ + padding-top:15px; } .cell{ @@ -391,13 +390,7 @@ margin:0px; iframe{ border: none; height:500px; -} - -#noncontiguous-grid{ - height:400px; - pointer-events: all; - background-color: orange; -} +} #custom-grid>div{ float:left; diff --git a/docs/jquery.gridstrap.css b/docs/jquery.gridstrap.css index d78a140..9f967dc 100644 --- a/docs/jquery.gridstrap.css +++ b/docs/jquery.gridstrap.css @@ -23,5 +23,5 @@ z-index: 10000; } .gridstack-noncontiguous{ - opacity: 0.02; + opacity: 0; } \ No newline at end of file diff --git a/docs/jquery.gridstrap.js b/docs/jquery.gridstrap.js index 6914833..207dbdf 100644 --- a/docs/jquery.gridstrap.js +++ b/docs/jquery.gridstrap.js @@ -34,9 +34,9 @@ exports['default'] = { EVENT_CELL_RESIZE: 'cellresize', EVENT_CELL_DRAG: 'celldrag', EVENT_CELL_REDRAW: 'cellredraw', - EVENT_NONCONTIGUOUS_CONTAINER_CHANGE: 'noncontiguouschange', - ERROR_MISSING_JQUERY: 'Requires jQuery v?', - ERROR_INVALID_ATTACH_ELEMENT: 'Cannot attach element that is not a child of gridstrap parent' + ERROR_MISSING_JQUERY: 'Requires jQuery v?', //TODO + ERROR_INVALID_ATTACH_ELEMENT: 'Cannot attach element that is not a child of gridstrap parent.', + ERROR_NONCONTIGUOUS_HTML_UNDEFINED: 'nonContiguousCellHtml option cannot be null.' }; module.exports = exports['default']; @@ -144,7 +144,8 @@ var _methods = require('./methods'); resizeHandleSelector: null, // jQuery selector relative to cell for resize handling. Null disables. resizeOnDrag: true, // toggle mouse resizing. swapMode: false, // toggle swap or insert mode when rearranging cells. - nonContiguousCellHtml: null, // enable non-contiguous mode using this html for a placeholder cell. + nonContiguousCellHtml: null, // html to use for non-contiguous placeholder cells. + autoPadNonContiguousCells: true, // toggle adding non-contiguous cells automatically on drag or as needed. updateCoordinatesOnWindowResize: true, // enable window resize event handler. debug: false, // toggle console output. dragMouseoverThrottle: 500, // throttle cell mouseover events for rearranging. @@ -294,7 +295,7 @@ var Handlers = (function () { this.internal.MoveDraggedCell(mouseEvent, $draggedCell); - if (options.nonContiguousCellHtml && options.rearrangeOnDrag) { + if (options.nonContiguousCellHtml && options.rearrangeOnDrag && options.autoPadNonContiguousCells) { this.internal.UpdateNonContiguousCellsForDrag($draggedCell, mouseEvent); } } @@ -332,7 +333,8 @@ var Handlers = (function () { var $draggedCell = this.internal.$GetDraggingCell(); if ($draggedCell.length > 0) { - if (options.nonContiguousCellHtml && !options.rearrangeOnDrag) { + if (options.nonContiguousCellHtml && !options.rearrangeOnDrag && options.autoPadNonContiguousCells) { + this.internal.UpdateNonContiguousCellsForDrag($draggedCell, mouseEvent); // mouse event may be over a new placeholder cell now. @@ -808,21 +810,38 @@ var Internal = (function () { }; Internal.prototype.UpdateNonContiguousCellsForDrag = function UpdateNonContiguousCellsForDrag($draggedCell, mouseEvent) { - var draggedCellPositionAndSize = _utils.Utils.GetPositionAndSizeOfCell($draggedCell); + var $ = this.setup.jQuery; + var options = this.setup.Options; + + var furthestVisibleCellPositionAndSize = _utils.Utils.GetPositionAndSizeOfCell($draggedCell); + + var compare = function compare(positionAndSize) { + return positionAndSize.left + positionAndSize.width + (positionAndSize.top + positionAndSize.height) * 100000; + }; + var $hiddenCells = this.$GetHiddenCellsInElementOrder(); + $hiddenCells.each(function (i, e) { + if (!$(e).data(_constants2['default'].DATA_VISIBLE_CELL).hasClass(options.nonContiguousPlaceholderCellClass)) { + var positionAndSize = _utils.Utils.GetPositionAndSizeOfCell($(e)); + + if (compare(positionAndSize) > compare(furthestVisibleCellPositionAndSize)) { + furthestVisibleCellPositionAndSize = positionAndSize; + } + } + }); var changed = this.AppendOrRemoveNonContiguousCellsWhile(function ($hiddenCells, appending) { var lastHiddenCellPositionAndSize = _utils.Utils.GetPositionAndSizeOfCell($hiddenCells.last()); + // A whole row of extra cells should exist. if (appending) { - // if making new placeholder cells, then a whole row of extra cells should exist. - return lastHiddenCellPositionAndSize.top - draggedCellPositionAndSize.top < draggedCellPositionAndSize.height * 2; + // need at least 2* cell height worht of space at bottom of grid. + return lastHiddenCellPositionAndSize.top - furthestVisibleCellPositionAndSize.top < furthestVisibleCellPositionAndSize.height * 2; } else { - return lastHiddenCellPositionAndSize.top - draggedCellPositionAndSize.top > draggedCellPositionAndSize.height * 2; + return lastHiddenCellPositionAndSize.top - furthestVisibleCellPositionAndSize.top > furthestVisibleCellPositionAndSize.height * 2; } }); if (changed) { - // insert/remove triggers a repositioning, so have to set dragged cell to mousepos again. this.MoveDraggedCell(mouseEvent, $draggedCell); } }; @@ -832,18 +851,9 @@ var Internal = (function () { var options = this.setup.Options; var context = this.setup.Context; - var $hiddenCells = this.$GetHiddenCellsInElementOrder(); var changed = false; - // remove cells at end when we have too much. - var $lastHiddenCell = $hiddenCells.last(); - var $bottomRowHiddenCells = null; - var $getBottomRowHiddenCells = function $getBottomRowHiddenCells() { - $bottomRowHiddenCells = $bottomRowHiddenCells || $hiddenCells.filter(function (i, e) { - return _utils.Utils.GetPositionAndSizeOfCell($(e)).top === _utils.Utils.GetPositionAndSizeOfCell($lastHiddenCell).top; - }); - return $bottomRowHiddenCells; - }; + var $hiddenCells = this.$GetHiddenCellsInElementOrder(); while (appendWhilePredicate($hiddenCells, true)) { // if mouse beyond or getting near end of static hidden element, then make some placeholder ones. @@ -857,9 +867,21 @@ var Internal = (function () { changed = true; } + // remove cells at end when we have too much. + var $lastHiddenCell = $hiddenCells.last(); + var $bottomRowHiddenCells = null; + var $getBottomRowHiddenCells = function $getBottomRowHiddenCells() { + $bottomRowHiddenCells = $bottomRowHiddenCells || $hiddenCells.filter(function (i, e) { + return _utils.Utils.GetPositionAndSizeOfCell($(e)).top === _utils.Utils.GetPositionAndSizeOfCell($lastHiddenCell).top; + }); + return $bottomRowHiddenCells; + }; + + // remove all non-contiguous bottom row cells. while (appendWhilePredicate($hiddenCells, false) && $getBottomRowHiddenCells().filter(function (i, e) { return $(e).data(_constants2['default'].DATA_VISIBLE_CELL).hasClass(options.nonContiguousPlaceholderCellClass); - }).length === $getBottomRowHiddenCells().length) { + }).length === $getBottomRowHiddenCells().length && $getBottomRowHiddenCells().length > 0) { + // while all bottom row cells are placeholders. context.removeCell($lastHiddenCell.data(_constants2['default'].DATA_VISIBLE_CELL)); $hiddenCells = $hiddenCells.not($lastHiddenCell); @@ -999,6 +1021,7 @@ var Methods = (function () { Methods.prototype.insertCell = function insertCell(cellHtml, index) { var $ = this.setup.jQuery; + var options = this.setup.Options; var $element = this.setup.$Element; var $existingHiddenCells = this.internal.$GetHiddenCellsInElementOrder(); @@ -1006,6 +1029,22 @@ var Methods = (function () { index = $existingHiddenCells.length; // insert at end. } + if (index > $existingHiddenCells.length && options.nonContiguousCellHtml && options.autoPadNonContiguousCells) { + + this.internal.AppendOrRemoveNonContiguousCellsWhile(function ($hiddenCells, appending) { + + if (!appending) { + // do not remove when trying to remove. + return false; + } + // insert placeholders until quantity of cells is index -1. + return $hiddenCells.length < index; + }); + + // update these. + $existingHiddenCells = this.internal.$GetHiddenCellsInElementOrder(); + } + var $insertedCell; if (index === $existingHiddenCells.length) { if ($existingHiddenCells.length === 0) { @@ -1078,12 +1117,29 @@ var Methods = (function () { Methods.prototype.moveCell = function moveCell(element, toIndex, targetGridstrap) { // targetGridstrap optional.. + var options = this.setup.Options; var context = this.setup.Context; - var cellNIndex = this.internal.GetCellAndInternalIndex(element); - var $existingVisibleCells = this.$getCells(); + if (toIndex > $existingVisibleCells.length && options.nonContiguousCellHtml && options.autoPadNonContiguousCells) { + + this.internal.AppendOrRemoveNonContiguousCellsWhile(function ($hiddenCells, appending) { + + if (!appending) { + // do not remove when trying to remove. + return false; + } + // insert placeholders until quantity of cells is index -1. + return $hiddenCells.length <= toIndex; + }); + + // update these. + $existingVisibleCells = this.$getCells(); + } + + var cellNIndex = this.internal.GetCellAndInternalIndex(element); + this.internal.MoveCell(cellNIndex.$cell, $existingVisibleCells.eq(toIndex), targetGridstrap || context); }; @@ -1206,12 +1262,25 @@ var Methods = (function () { var $ = this.setup.jQuery; var options = this.setup.Options; + if (!options.nonContiguousCellHtml) { + throw new Error(_constants2['default'].ERROR_NONCONTIGUOUS_HTML_UNDEFINED); + } + var $attachedHiddenCells = this.internal.$GetHiddenCellsInElementOrder(); this.internal.AppendOrRemoveNonContiguousCellsWhile(function ($hiddenCells, appending) { - return callback($hiddenCells.length, $hiddenCells.filter(function (i, e) { + + if (!appending) { + // do not remove, when trying to remove. + // only append/pad. + return false; + } + var cellCount = $hiddenCells.length; + var placeHolderCount = $hiddenCells.filter(function (i, e) { return $(e).data(_constants2['default'].DATA_VISIBLE_CELL).hasClass(options.nonContiguousPlaceholderCellClass); - }).length, appending); + }).length; + + return callback(cellCount, placeHolderCount); }); }; diff --git a/src/constants.js b/src/constants.js index efb991e..3742d65 100644 --- a/src/constants.js +++ b/src/constants.js @@ -14,7 +14,7 @@ EVENT_CELL_RESIZE : 'cellresize', EVENT_CELL_DRAG: 'celldrag', EVENT_CELL_REDRAW: 'cellredraw', - EVENT_NONCONTIGUOUS_CONTAINER_CHANGE: 'noncontiguouschange', - ERROR_MISSING_JQUERY: 'Requires jQuery v?', - ERROR_INVALID_ATTACH_ELEMENT : 'Cannot attach element that is not a child of gridstrap parent' + ERROR_MISSING_JQUERY: 'Requires jQuery v?', //TODO + ERROR_INVALID_ATTACH_ELEMENT : 'Cannot attach element that is not a child of gridstrap parent.', + ERROR_NONCONTIGUOUS_HTML_UNDEFINED : 'nonContiguousCellHtml option cannot be null.' }; diff --git a/src/handlers.js b/src/handlers.js index f7aebee..73aace4 100644 --- a/src/handlers.js +++ b/src/handlers.js @@ -164,6 +164,7 @@ export class Handlers { if (options.nonContiguousCellHtml && !options.rearrangeOnDrag && options.autoPadNonContiguousCells){ + this.internal.UpdateNonContiguousCellsForDrag($draggedCell, mouseEvent); // mouse event may be over a new placeholder cell now. diff --git a/src/internal.js b/src/internal.js index 06153b0..339dc0b 100644 --- a/src/internal.js +++ b/src/internal.js @@ -449,24 +449,41 @@ export class Internal { } UpdateNonContiguousCellsForDrag($draggedCell, mouseEvent){ - let draggedCellPositionAndSize = Utils.GetPositionAndSizeOfCell($draggedCell); + let $ = this.setup.jQuery; + let options = this.setup.Options; + + let furthestVisibleCellPositionAndSize = Utils.GetPositionAndSizeOfCell($draggedCell); + + let compare = (positionAndSize) => { + return positionAndSize.left + positionAndSize.width + + (positionAndSize.top + positionAndSize.height) * 100000 + }; + let $hiddenCells = this.$GetHiddenCellsInElementOrder(); + $hiddenCells.each((i, e) => { + if (!$(e).data(Constants.DATA_VISIBLE_CELL).hasClass(options.nonContiguousPlaceholderCellClass)){ + let positionAndSize = Utils.GetPositionAndSizeOfCell($(e)); + + if (compare(positionAndSize) > compare(furthestVisibleCellPositionAndSize)){ + furthestVisibleCellPositionAndSize = positionAndSize; + } + } + }); let changed = this.AppendOrRemoveNonContiguousCellsWhile(($hiddenCells, appending) => { let lastHiddenCellPositionAndSize = Utils.GetPositionAndSizeOfCell( $hiddenCells.last()); + // A whole row of extra cells should exist. if (appending){ - // if making new placeholder cells, then a whole row of extra cells should exist. - return lastHiddenCellPositionAndSize.top - draggedCellPositionAndSize.top < draggedCellPositionAndSize.height * 2; + // need at least 2* cell height worht of space at bottom of grid. + return lastHiddenCellPositionAndSize.top - furthestVisibleCellPositionAndSize.top < furthestVisibleCellPositionAndSize.height * 2; } else { - return lastHiddenCellPositionAndSize.top - draggedCellPositionAndSize.top > draggedCellPositionAndSize.height * 2; - } - - }); + return lastHiddenCellPositionAndSize.top - furthestVisibleCellPositionAndSize.top > furthestVisibleCellPositionAndSize.height * 2; + } + }); if (changed){ - // insert/remove triggers a repositioning, so have to set dragged cell to mousepos again. - this.MoveDraggedCell(mouseEvent, $draggedCell); - } + this.MoveDraggedCell(mouseEvent, $draggedCell); + } } AppendOrRemoveNonContiguousCellsWhile(appendWhilePredicate){ @@ -474,18 +491,9 @@ export class Internal { let options = this.setup.Options; let context = this.setup.Context; - let $hiddenCells = this.$GetHiddenCellsInElementOrder(); let changed = false; - // remove cells at end when we have too much. - let $lastHiddenCell = $hiddenCells.last(); - let $bottomRowHiddenCells = null; - let $getBottomRowHiddenCells = () => { - $bottomRowHiddenCells = $bottomRowHiddenCells || $hiddenCells.filter((i,e) => { - return Utils.GetPositionAndSizeOfCell($(e)).top === Utils.GetPositionAndSizeOfCell($lastHiddenCell).top; - }); - return $bottomRowHiddenCells; - }; + let $hiddenCells = this.$GetHiddenCellsInElementOrder(); while (appendWhilePredicate($hiddenCells, true)) { // if mouse beyond or getting near end of static hidden element, then make some placeholder ones. @@ -497,13 +505,28 @@ export class Internal { $insertedCell.addClass(options.nonContiguousPlaceholderCellClass); let $insertedHiddenCell = $insertedCell.data(Constants.DATA_HIDDEN_CELL); - $hiddenCells = $hiddenCells.add($insertedHiddenCell); - + $hiddenCells = $hiddenCells.add($insertedHiddenCell); + changed = true; } + + // remove cells at end when we have too much. + let $lastHiddenCell = $hiddenCells.last(); + let $bottomRowHiddenCells = null; + let $getBottomRowHiddenCells = () => { + $bottomRowHiddenCells = $bottomRowHiddenCells || $hiddenCells.filter((i,e) => { + return Utils.GetPositionAndSizeOfCell($(e)).top === Utils.GetPositionAndSizeOfCell($lastHiddenCell).top; + }); + return $bottomRowHiddenCells; + }; + // remove all non-contiguous bottom row cells. while (appendWhilePredicate($hiddenCells, false) && - $getBottomRowHiddenCells().filter((i,e) => $(e).data(Constants.DATA_VISIBLE_CELL).hasClass(options.nonContiguousPlaceholderCellClass)).length === $getBottomRowHiddenCells().length) { + $getBottomRowHiddenCells().filter((i,e) => { + return $(e).data(Constants.DATA_VISIBLE_CELL).hasClass(options.nonContiguousPlaceholderCellClass); + }).length === $getBottomRowHiddenCells().length && + $getBottomRowHiddenCells().length > 0) { + // while all bottom row cells are placeholders. context.removeCell($lastHiddenCell.data(Constants.DATA_VISIBLE_CELL)); $hiddenCells = $hiddenCells.not($lastHiddenCell); @@ -511,10 +534,10 @@ export class Internal { // update new last hidden cell. $lastHiddenCell = $hiddenCells.last(); - $bottomRowHiddenCells = null; // force refilter. + $bottomRowHiddenCells = null; // force refilter. changed = true; - } + } return changed; } diff --git a/src/methods.js b/src/methods.js index 504ecd2..f7ad02d 100644 --- a/src/methods.js +++ b/src/methods.js @@ -81,13 +81,32 @@ export class Methods { // index is optional. insertCell (cellHtml, index) { let $ = this.setup.jQuery; - let $element = this.setup.$Element; + let options = this.setup.Options; + let $element = this.setup.$Element; var $existingHiddenCells = this.internal.$GetHiddenCellsInElementOrder(); if (typeof(index) === 'undefined') { index = $existingHiddenCells.length; // insert at end. } + if (index > $existingHiddenCells.length && + options.nonContiguousCellHtml && + options.autoPadNonContiguousCells) { + + this.internal.AppendOrRemoveNonContiguousCellsWhile(($hiddenCells, appending) => { + + if (!appending){ + // do not remove when trying to remove. + return false; + } + // insert placeholders until quantity of cells is index -1. + return $hiddenCells.length < index; + }); + + // update these. + $existingHiddenCells = this.internal.$GetHiddenCellsInElementOrder(); + } + var $insertedCell; if (index === $existingHiddenCells.length) { if ($existingHiddenCells.length === 0) { @@ -157,12 +176,31 @@ export class Methods { } moveCell(element, toIndex, targetGridstrap) { // targetGridstrap optional.. + let options = this.setup.Options; let context = this.setup.Context; - let cellNIndex = this.internal.GetCellAndInternalIndex(element); - let $existingVisibleCells = this.$getCells(); + if (toIndex > $existingVisibleCells.length && + options.nonContiguousCellHtml && + options.autoPadNonContiguousCells) { + + this.internal.AppendOrRemoveNonContiguousCellsWhile(($hiddenCells, appending) => { + + if (!appending){ + // do not remove when trying to remove. + return false; + } + // insert placeholders until quantity of cells is index -1. + return $hiddenCells.length <= toIndex; + }); + + // update these. + $existingVisibleCells = this.$getCells(); + } + + let cellNIndex = this.internal.GetCellAndInternalIndex(element); + this.internal.MoveCell(cellNIndex.$cell, $existingVisibleCells.eq(toIndex), targetGridstrap || context); } @@ -289,15 +327,25 @@ export class Methods { let $ = this.setup.jQuery; let options = this.setup.Options; + if (!options.nonContiguousCellHtml){ + throw new Error(Constants.ERROR_NONCONTIGUOUS_HTML_UNDEFINED); + } + let $attachedHiddenCells = this.internal.$GetHiddenCellsInElementOrder(); this.internal.AppendOrRemoveNonContiguousCellsWhile(($hiddenCells, appending) => { - return callback( - $hiddenCells.length, - $hiddenCells.filter((i, e) => { - return $(e).data(Constants.DATA_VISIBLE_CELL).hasClass(options.nonContiguousPlaceholderCellClass); - }).length, - appending); + + if (!appending){ + // do not remove, when trying to remove. + // only append/pad. + return false; + } + let cellCount = $hiddenCells.length; + let placeHolderCount = $hiddenCells.filter((i, e) => { + return $(e).data(Constants.DATA_VISIBLE_CELL).hasClass(options.nonContiguousPlaceholderCellClass); + }).length; + + return callback(cellCount, placeHolderCount); }); } diff --git a/src/style.css b/src/style.css index 76e927f..23fa091 100644 --- a/src/style.css +++ b/src/style.css @@ -15,5 +15,5 @@ z-index: 10000; } .gridstack-noncontiguous{ - opacity: 0.02; + opacity: 0; } \ No newline at end of file diff --git a/test/compiled/jquery.gridstrap.spec.js b/test/compiled/jquery.gridstrap.spec.js index 582650f..36f1d0f 100644 --- a/test/compiled/jquery.gridstrap.spec.js +++ b/test/compiled/jquery.gridstrap.spec.js @@ -18,9 +18,9 @@ exports['default'] = { EVENT_CELL_RESIZE: 'cellresize', EVENT_CELL_DRAG: 'celldrag', EVENT_CELL_REDRAW: 'cellredraw', - EVENT_NONCONTIGUOUS_CONTAINER_CHANGE: 'noncontiguouschange', - ERROR_MISSING_JQUERY: 'Requires jQuery v?', - ERROR_INVALID_ATTACH_ELEMENT: 'Cannot attach element that is not a child of gridstrap parent' + ERROR_MISSING_JQUERY: 'Requires jQuery v?', //TODO + ERROR_INVALID_ATTACH_ELEMENT: 'Cannot attach element that is not a child of gridstrap parent.', + ERROR_NONCONTIGUOUS_HTML_UNDEFINED: 'nonContiguousCellHtml option cannot be null.' }; module.exports = exports['default'];