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
<div id="basic-grid" class="row">
<div class="col-xs-4 col-sm-2 col-md-1"></div>
<div class="col-xs-4 col-sm-2 col-md-1"></div>
...
</div>
<script>
$('#basic-grid').gridstrap();
</script>
<script>
// The above grid is within an iframe to demonstrate its responsive behaviour.
// It is otherwise the same as the basic demo.
$('#responsive-grid').gridstrap();
</script>
<div id="nested-grid" class="row">
<div class="col-xs-4 col-sm-2 col-md-1"></div>
<div class="col-xs-4 col-sm-2 col-md-1"></div>
<div class="col-xs-4 col-sm-2 col-md-1">
<div class="nested-inner-grid">
<div class="col-xs-4 col-sm-2 col-md-1"></div>
<div class="col-xs-4 col-sm-2 col-md-1"></div>
....
</div>
</div>
<div class="col-xs-4 col-sm-2 col-md-1"></div>
...
</div>
<script>
// Init outer grid first.
$('#nested-grid').gridstrap();
// Inner grid is identifiable via a class rather than an id.
// This is necessary because gridstrap creates a copy of all internal html elements
// and you cannot have two elements with the same id.
// By default the visible cells within the grid will have a 'gridstrap-cell-visible' class.
$('.gridstrap-cell-visible .nested-inner-grid').gridstrap();
</script>
<div id="resize-grid" class="row">
<div class="col-xs-2 cell"><div class="inner"><div class="resize"></div></div></div>
<div class="col-xs-2 cell"><div class="inner"><div class="resize"></div></div></div>
...
</div>
<script>
$('#resize-grid').gridstrap({
resizeHandleSelector: '.resize'
});
// The above is all you need to do to enable resizing.
// However, the below shows how we can maintain Bootstrap's
// grid functionality.
var gs = $('#resize-grid').data('gridstrap');
$('#resize-grid').on('cellresize', function (e) {
e.preventDefault();
var index = gs.getCellIndexOfElement(e.target);
gs.modifyCell(index, function ($getVisibleCell, $getHiddenCell) {
var $hiddenCell = $getHiddenCell();
// Remove Bootstrap's column classes, then add ones appropriate
// to the cell's outer width.
for (var i = 1; i <= 12; i++) {
$hiddenCell.removeClass('col-xs-' + i);
}
$hiddenCell.addClass('col-xs-1');
var oneWidth = $hiddenCell.outerWidth();
for (var i = 2; i <= 12; i++) {
if ($hiddenCell.outerWidth() + oneWidth / 2 <= e.width) {
$hiddenCell.removeClass('col-xs-' + (i - 1));
$hiddenCell.addClass('col-xs-' + i);
} else {
$hiddenCell.removeClass('col-xs-' + i);
}
}
});
});
</script>
<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>
<div id="dual1-grid" class="row">
<div class="col-xs-2 cell"><div class="inner"></div></div>
<div class="col-xs-2 cell"><div class="inner"></div></div>
...
</div>
<div id="dual2-grid" class="row">
<div class="col-xs-2 cell"><div class="inner"></div></div>
<div class="col-xs-2 cell"><div class="inner"></div></div>
...
</div>
<script>
$('#dual1-grid').gridstrap();
$('#dual2-grid').gridstrap();
$('#dual1-grid').data('gridstrap').setAdditionalGridstrapDragTarget('#dual2-grid');
$('#dual2-grid').data('gridstrap').setAdditionalGridstrapDragTarget('#dual1-grid');
</script>
<!-- Gridstrap can work without a Bootstrap grid -->
<div id="custom-grid">
<div style="width: 47.9063px; height: 75px; background-color: rgb(150, 224, 183); left: 478.891px; top: 625.516px;"></div>
<div style="width: 17px; height: 75px; background-color: rgb(50, 214, 11); left: 448px; top: 635.516px;"></div>
...
</div>
<script>
$('#custom-grid').gridstrap();
</script>