gridstrap.js is a jQuery plugin designed to take Bootstrap's responsive grid system and turn it into a managed draggable and resizeable grid while truely maintaining its responsive behaviour. It will also work with any kind of CSS-driven layout.
+
gridstrap.js is a jQuery plugin designed to take Bootstrap's responsive grid system and turn it into a managed draggable and resizeable grid while truely maintaining its responsive behaviour. It will also work with any kind of CSS-driven layout.
+
I made this plugin to fill a gap that existed for easily creating Bootstrap-based drag 'n' drop grid interfaces.
+
Both gridster.js and gridstack.js inspired this plugin.
Demo
@@ -144,7 +145,7 @@
Demo
resizeHandleSelector: '.resize'
});
// The above is all you need to do to enable resizing.
- // The below shows how we can maintain Bootstrap's
+ // However, the below shows how we can maintain Bootstrap's
// grid functionality.
var gs = $('#resize-grid').data('gridstrap');
$('#resize-grid').on('cellresize', function (e) {
@@ -303,9 +304,11 @@
gridstrap.js is a jQuery plugin designed to take Bootstrap's responsive grid system and turn it into a managed draggable and resizeable grid while truely maintaining its responsive behaviour. It will also work with any kind of CSS-driven layout.
+
gridstrap.js is a jQuery plugin designed to take Bootstrap's responsive grid system and turn it into a managed draggable and resizeable grid while truely maintaining its responsive behaviour. It will also work with any kind of CSS-driven layout.
+
I made this plugin to fill a gap that existed for easily creating Bootstrap-based drag 'n' drop grid interfaces.
+
Both gridster.js and gridstack.js inspired this plugin.
Demo
@@ -85,7 +86,7 @@
Demo
-
+
+
-
-
-
+
diff --git a/docs/indexstyle.css b/docs/indexstyle.css
index e42e57d..ec94ac8 100644
--- a/docs/indexstyle.css
+++ b/docs/indexstyle.css
@@ -262,7 +262,7 @@ body { padding: 0; margin: 0; font-family: "Open Sans", "Helvetica Neue", Helvet
a { color: #1e6bb8; text-decoration: none; }
a:hover { text-decoration: underline; }
-.btn-top { display: inline-block; margin-bottom: 1rem; color: rgba(255, 255, 255, 0.7); background-color: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.2); border-style: solid; border-width: 1px; border-radius: 0.3rem; transition: color 0.2s, background-color 0.2s, border-color 0.2s; }
+.btn-top { display: inline-block; color: rgba(255, 255, 255, 0.7); background-color: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.2); border-style: solid; border-width: 1px; border-radius: 0.3rem; transition: color 0.2s, background-color 0.2s, border-color 0.2s; }
.btn-top:hover { color: rgba(255, 255, 255, 0.8); text-decoration: none; background-color: rgba(255, 255, 255, 0.2); border-color: rgba(255, 255, 255, 0.3); }
.btn-top + .btn-top { margin-left: 1rem; }
@media screen and (min-width: 64em) { .btn-top { padding: 0.75rem 1rem; } }
@@ -270,7 +270,7 @@ a:hover { text-decoration: underline; }
@media screen and (max-width: 42em) { .btn-top { display: block; width: 100%; padding: 0.75rem; font-size: 0.9rem; }
.btn-top + .btn-top { margin-top: 1rem; margin-left: 0; } }
-.page-header {
+.header-bg {
color: #cdbfe3;
@@ -327,7 +327,12 @@ margin:0px;
.main-content dl dd { padding: 0; margin-bottom: 1rem; }
.main-content hr { height: 2px; padding: 0; margin: 1rem 0; background-color: #eff0f1; border: 0; }
-.site-footer { padding-top: 2rem; margin-top: 2rem; border-top: solid 1px #eff0f1; }
+.site-footer { padding-top: 2rem; margin-top: 2rem; border-top: solid 1px #eff0f1;
+
+ color: #99979c;
+ text-align: center;
+ background-color: #2a2730;
+ }
@media screen and (min-width: 64em) { .site-footer { font-size: 1rem; } }
@media screen and (min-width: 42em) and (max-width: 64em) { .site-footer { font-size: 1rem; } }
@media screen and (max-width: 42em) { .site-footer { font-size: 0.9rem; } }
diff --git a/docs/jquery.gridstrap.css b/docs/jquery.gridstrap.css
index e2bb77e..d560875 100644
--- a/docs/jquery.gridstrap.css
+++ b/docs/jquery.gridstrap.css
@@ -1,6 +1,7 @@
/*
* jquery.gridstrap - v{{ include-version }}
- * gridstrap.js https://www.npmjs.com/package/jquery.gridstrap
+ * gridstrap.js
+ * Use https://www.npmjs.com/package/jquery.gridstrap for version information, semantically-released.
* https://rosspi.github.io/gridstrap.js/
*
* Made by Ross P
diff --git a/docs/jquery.gridstrap.js b/docs/jquery.gridstrap.js
index e5f6b46..134a96b 100644
--- a/docs/jquery.gridstrap.js
+++ b/docs/jquery.gridstrap.js
@@ -1,14 +1,7 @@
/*
* jquery.gridstrap - v{{ include-version }}
- * gridstrap.js https://www.npmjs.com/package/jquery.gridstrap
- * https://rosspi.github.io/gridstrap.js/
- *
- * Made by Ross P
- * Under MIT License
- */
-/*
- * jquery.gridstrap - v{{ include-version }}
- * gridstrap.js https://www.npmjs.com/package/jquery.gridstrap
+ * gridstrap.js
+ * Use https://www.npmjs.com/package/jquery.gridstrap for version information, semantically-released.
* https://rosspi.github.io/gridstrap.js/
*
* Made by Ross P
@@ -268,7 +261,8 @@ var Handlers = (function () {
_this.internal.MoveCell($draggedCell, $cell, gridstrapContext);
// reset dragged object to mouse pos, not pos of hidden cells.
- _this.internal.MoveDraggedCell(mouseEvent, $draggedCell);
+ // do not trigger overlapping now.
+ _this.internal.MoveDraggedCell(mouseEvent, $draggedCell, true);
}
}, options.dragMouseoverThrottle);
}
@@ -554,7 +548,7 @@ var Internal = (function () {
return element;
};
- Internal.prototype.MoveDraggedCell = function MoveDraggedCell(mouseEvent, $cell) {
+ Internal.prototype.MoveDraggedCell = function MoveDraggedCell(mouseEvent, $cell, dontLookForOverlappedCell /*optional*/) {
var $ = this.setup.jQuery;
var context = this.setup.Context;
var options = this.setup.Options;
@@ -579,6 +573,10 @@ var Internal = (function () {
$cell.css('left', absoluteOffset.left);
$cell.css('top', absoluteOffset.top);
+ if (dontLookForOverlappedCell) {
+ return;
+ }
+
var triggerMouseOverEvent = function triggerMouseOverEvent($element) {
$element.trigger($.Event(_constants2['default'].EVENT_MOUSEOVER, {
pageX: mouseEvent.pageX,
@@ -1022,6 +1020,8 @@ var Methods = (function () {
var context = this.setup.Context;
var options = this.setup.Options;
+ var $draggedCell = this.internal.$GetDraggingCell();
+
for (var i = 0; i < this.internal.CellsArray.length; i++) {
var $this = this.internal.CellsArray[i];
@@ -1031,15 +1031,16 @@ var Methods = (function () {
this.setCellAbsolutePositionAndSize($this, positionNSizeOfHiddenClone);
}
+
// need to also update the first child gristrap - one that might exist within this one - it is then obviously recursive.
for (var i = 0; i < this.internal.CellsArray.length; i++) {
var $nestedGridstrap = this.internal.CellsArray[i].find('*').filter(function () {
return !!$(this).data(_constants2['default'].DATA_GRIDSTRAP);
});
- if ($nestedGridstrap.length) {
- $nestedGridstrap.first().data(_constants2['default'].DATA_GRIDSTRAP).updateVisibleCellCoordinates();
- }
+ $nestedGridstrap.each(function () {
+ $(this).data(_constants2['default'].DATA_GRIDSTRAP).updateVisibleCellCoordinates();
+ });
}
};
diff --git a/docs/responsive.html b/docs/responsive.html
index 321b0f7..67b34b4 100644
--- a/docs/responsive.html
+++ b/docs/responsive.html
@@ -24,10 +24,7 @@
-
+
diff --git a/docs/responsiveLocal.html b/docs/responsiveLocal.html
index d744639..fbaff22 100644
--- a/docs/responsiveLocal.html
+++ b/docs/responsiveLocal.html
@@ -24,10 +24,7 @@
-
+
diff --git a/karma.conf.js b/karma.conf.js
index 3db5932..bc33562 100644
--- a/karma.conf.js
+++ b/karma.conf.js
@@ -2,10 +2,42 @@ module.exports = function( config ) {
config.set( {
files: [
- "node_modules/jquery/dist/jquery.js",
- "dist/jquery.gridstrap.min.js",
- "test/setup.js",
- "test/compiled/*"
+ {
+ pattern: "node_modules/jquery/dist/jquery.js",
+ served: true,
+ included: true,
+ watched: true
+ },
+ {
+ pattern: "dist/jquery.gridstrap.min.js",
+ served: true,
+ included: true,
+ watched: true
+ },
+ {
+ pattern: "test/setup.js",
+ served: true,
+ included: true,
+ watched: true
+ },
+ {
+ pattern: "test/compiled/*",
+ served: true,
+ included: true,
+ watched: true
+ },
+ {
+ pattern: "src/*.js",
+ served: false,
+ included: false,
+ watched: true
+ },
+ {
+ pattern: "test/spec/*",
+ served: false,
+ included: false,
+ watched: true
+ }
],
frameworks: [ "qunit" ],
autoWatch: true
diff --git a/package.json b/package.json
index fbdd4bb..5eca8e4 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,8 @@
{
"name": "jquery.gridstrap",
"version": "0.0.0-semantically-released",
- "description": "gridstrap.js https://www.npmjs.com/package/jquery.gridstrap",
+ "description": "gridstrap.js",
+ "message": "Use https://www.npmjs.com/package/jquery.gridstrap for version information, semantically-released.",
"keywords": [
"gridster",
"gridstrap",
@@ -10,9 +11,12 @@
"jquery-plugin",
"jquery",
"jquery plugin",
- "plugins"
+ "plugins",
+ "drag",
+ "drop",
+ "draggable"
],
- "main": "dist/jquery-gridstrap.js",
+ "main": "dist/jquery.gridstrap.js",
"repository": {
"type": "git",
"url": "https://github.com/rosspi/gridstrap.js.git"
@@ -35,7 +39,7 @@
],
"license": "MIT",
"dependencies": {
- "jquery": ">=1.5.1"
+ "jquery": ">=1.9.1 < 4.0.0"
},
"devDependencies": {
"babel-core": "^6.24.1",
@@ -59,7 +63,8 @@
"karma-qunit": "^1.2.1",
"phantomjs": "^1.9.18",
"qunitjs": "^1.19.0",
- "semantic-release": "^6.3.6"
+ "semantic-release": "^6.3.6",
+ "jquery": ">=1.9.1 < 4.0.0"
},
"scripts": {
"commit": "git-cz",
diff --git a/src/handlers.js b/src/handlers.js
index 6391a0f..fd7072d 100644
--- a/src/handlers.js
+++ b/src/handlers.js
@@ -92,7 +92,8 @@ export class Handlers {
this.internal.MoveCell($draggedCell, $cell, gridstrapContext);
// reset dragged object to mouse pos, not pos of hidden cells.
- this.internal.MoveDraggedCell(mouseEvent, $draggedCell);
+ // do not trigger overlapping now.
+ this.internal.MoveDraggedCell(mouseEvent, $draggedCell, true);
}
}, options.dragMouseoverThrottle);
}
diff --git a/src/internal.js b/src/internal.js
index b7af105..36d27e6 100644
--- a/src/internal.js
+++ b/src/internal.js
@@ -183,7 +183,7 @@ export class Internal {
return element;
}
- MoveDraggedCell (mouseEvent, $cell) {
+ MoveDraggedCell (mouseEvent, $cell, dontLookForOverlappedCell /*optional*/) {
let $ = this.setup.jQuery;
let context = this.setup.Context;
let options = this.setup.Options;
@@ -208,6 +208,10 @@ export class Internal {
$cell.css('left', absoluteOffset.left);
$cell.css('top', absoluteOffset.top);
+ if (dontLookForOverlappedCell){
+ return;
+ }
+
let triggerMouseOverEvent = function ($element) {
$element.trigger(
$.Event(Constants.EVENT_MOUSEOVER, {
diff --git a/src/methods.js b/src/methods.js
index f7ad02d..9611e4b 100644
--- a/src/methods.js
+++ b/src/methods.js
@@ -55,27 +55,30 @@ export class Methods {
let context = this.setup.Context;
let options = this.setup.Options;
+
+ let $draggedCell = this.internal.$GetDraggingCell();
+
for (var i = 0; i < this.internal.CellsArray.length; i++) {
- let $this = this.internal.CellsArray[i];
+ let $this = this.internal.CellsArray[i];
let $hiddenClone = $this.data(Constants.DATA_HIDDEN_CELL);
let positionNSizeOfHiddenClone = Utils.GetPositionAndSizeOfCell($hiddenClone);
- this.setCellAbsolutePositionAndSize($this, positionNSizeOfHiddenClone);
+ this.setCellAbsolutePositionAndSize($this, positionNSizeOfHiddenClone);
}
+
// need to also update the first child gristrap - one that might exist within this one - it is then obviously recursive.
for (var i = 0; i < this.internal.CellsArray.length; i++) {
var $nestedGridstrap = this.internal.CellsArray[i].find('*').filter(function () {
return !!$(this).data(Constants.DATA_GRIDSTRAP);
});
- if ($nestedGridstrap.length) {
- $nestedGridstrap.first().data(Constants.DATA_GRIDSTRAP).updateVisibleCellCoordinates();
- }
+ $nestedGridstrap.each(function(){
+ $(this).data(Constants.DATA_GRIDSTRAP).updateVisibleCellCoordinates();
+ });
}
- }
-
+ }
// returns jquery object of new cell.
// index is optional.
diff --git a/src/setup.js b/src/setup.js
index 7eb2476..b519432 100644
--- a/src/setup.js
+++ b/src/setup.js
@@ -12,7 +12,7 @@ export class Setup {
let wrapperGeneratedId = 'gridstrap-' + this.idPrefix;
this.visibleCellContainerSelector = '#' + wrapperGeneratedId;
- // drag selector must be within wrapper div. Turn class name/list into selector.
+ // drag selector must be within wrapper div. Turn class name/list into selector.
this.dragCellSelector = this.visibleCellContainerSelector + ' ' + Utils.ConvertCssClassToJQuerySelector(options.dragCellClass) + ':first';
this.resizeCellSelector = this.visibleCellContainerSelector + ' ' + Utils.ConvertCssClassToJQuerySelector(options.resizeCellClass) + ':first';
// visibleCellContainerClassSelector just contains a .class selector, dont prfix with id. Important. Refactor this.
diff --git a/test/compiled/jquery.gridstrap.spec.js b/test/compiled/jquery.gridstrap.spec.js
index 6a47500..a21f7fe 100644
--- a/test/compiled/jquery.gridstrap.spec.js
+++ b/test/compiled/jquery.gridstrap.spec.js
@@ -209,9 +209,9 @@ var Utils = (function () {
exports.Utils = Utils;
},{"./constants":1}],3:[function(require,module,exports){
-"use strict";
+'use strict';
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _srcUtils = require('../../src/utils');
@@ -221,22 +221,22 @@ var _srcUtils2 = _interopRequireDefault(_srcUtils);
"use strict";
- var $testCanvas = $("#testCanvas");
- var $fixture = null;
+ var $fixture = undefined;
var pluginName = 'gridstrap';
var pluginDataName = 'gridstrap';
+ var pluginOptionsName = 'Gridstrap';
QUnit.module("jQuery Gridstrap", {
beforeEach: function beforeEach() {
// fixture is the element where your jQuery plugin will act
- $fixture = $("");
-
- $testCanvas.append($fixture);
+ $fixture = $("#testGrid");
},
afterEach: function afterEach() {
// we remove the element to reset our plugin job :)
+ },
+ after: function after() {
$fixture.remove();
}
});
@@ -252,9 +252,16 @@ var _srcUtils2 = _interopRequireDefault(_srcUtils);
QUnit.test("caches plugin instance", function (assert) {
$fixture[pluginName]();
+
assert.ok($fixture.data(pluginDataName), "has cached it into a jQuery data");
});
+ QUnit.test('expected defaultOptions', function (assert) {
+ var defaultOptions = $[pluginOptionsName].defaultOptions;
+
+ assert.equal(JSON.stringify(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","dragCellHandleSelector":"*","draggable":true,"rearrangeOnDrag":true,"resizeHandleSelector":null,"resizeOnDrag":true,"swapMode":false,"nonContiguousCellHtml":null,"autoPadNonContiguousCells":true,"updateCoordinatesOnWindowResize":true,"debug":false,"dragMouseoverThrottle":150,"windowResizeDebounce":50,"mousemoveDebounce":0}', "default options has changed, breaking change");
+ });
+
// QUnit.test( "enable custom config", function( assert ) {
// $fixture[pluginName]( {
// foo: "bar"
diff --git a/test/setup.js b/test/setup.js
index 67a5529..2485af4 100644
--- a/test/setup.js
+++ b/test/setup.js
@@ -2,10 +2,15 @@
"use strict";
- // create an element to run tests inside
- var $testCanvas = $( "" );
+ var cellCount = 5*12;
- $( "body" ).prepend( $testCanvas );
+ // create an element to run tests inside
+ var $testGrid = $('');
+
+ for (var i = 0 ; i < cellCount; i++){
+ $testGrid.append('');
+ }
+ $( "body" ).prepend( $testGrid );
}( jQuery ) );
diff --git a/test/spec/jquery.gridstrap.spec.js b/test/spec/jquery.gridstrap.spec.js
index 30206da..13e306f 100644
--- a/test/spec/jquery.gridstrap.spec.js
+++ b/test/spec/jquery.gridstrap.spec.js
@@ -4,23 +4,23 @@ import Utils from '../../src/utils';
( function( $, QUnit ) {
"use strict";
-
- var $testCanvas = $( "#testCanvas" );
- var $fixture = null;
+
+ let $fixture;
let pluginName = 'gridstrap';
let pluginDataName = 'gridstrap';
+ let pluginOptionsName = 'Gridstrap';
QUnit.module( "jQuery Gridstrap", {
beforeEach: function() {
// fixture is the element where your jQuery plugin will act
- $fixture = $( "" );
-
- $testCanvas.append( $fixture );
+ $fixture = $( "#testGrid" );
},
afterEach: function() {
// we remove the element to reset our plugin job :)
+ },
+ after: function(){
$fixture.remove();
}
} );
@@ -39,11 +39,23 @@ import Utils from '../../src/utils';
QUnit.test( "caches plugin instance", function( assert ) {
$fixture[pluginName]();
+
assert.ok(
$fixture.data( pluginDataName ),
"has cached it into a jQuery data"
);
- } );
+ });
+
+ QUnit.test('expected defaultOptions', function( assert ) {
+ var defaultOptions = $[pluginOptionsName].defaultOptions;
+
+ assert.equal(
+ JSON.stringify(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","dragCellHandleSelector":"*","draggable":true,"rearrangeOnDrag":true,"resizeHandleSelector":null,"resizeOnDrag":true,"swapMode":false,"nonContiguousCellHtml":null,"autoPadNonContiguousCells":true,"updateCoordinatesOnWindowResize":true,"debug":false,"dragMouseoverThrottle":150,"windowResizeDebounce":50,"mousemoveDebounce":0}',
+
+ "default options has changed, breaking change"
+ );
+ });
// QUnit.test( "enable custom config", function( assert ) {
// $fixture[pluginName]( {