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>