gridstack
HTML
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta/css/bootstrap.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/gridstack.js/0.3.0/gridstack.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.0/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gridstack.js/0.3.0/gridstack.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gridstack.js/0.3.0/gridstack.jQueryUI.min.js"></script>
<body>
<div class="repeating-grid">
<div class="container-fluid">
<div class="grid-stack">
<a class="btn btn-default" id="add-new-widget" href="#">Add Widget</a>
</div>
</div>
</div>
</body>
SCSS
$charcoal: #343837;
$col-number: 24;
$col-size: 1/$col-number;
$col-padding: 0;
@for $i from 1 through $col-number {
.grid-stack-item[data-gs-width="#{$i}"] {
width: percentage($col-size*$i) !important;
}
.grid-stack-item[data-gs-x="#{$i}"] {
left: percentage($col-size*$i) !important;
}
}
body {
background-color: $charcoal;
}
$minor-grid-size: 0px;
$minor-grid-color: rgba(120,120,120,0.22);
$minor-grid-weight: 1px;
$major-grid-size: $minor-grid-size * 4;
$major-grid-color: rgba(120,120,120,120.44);
$major-grid-weight: 2px;
.repeating-grid {
position: absolute;
top: 0; bottom: 0;
left: 0; right: 0;
background-size: $major-grid-size $major-grid-size;
background-image:
repeating-linear-gradient(0deg, $major-grid-color, $major-grid-color $major-grid-weight, transparent $major-grid-weight, transparent $major-grid-size),
repeating-linear-gradient(-90deg, $major-grid-color, $major-grid-color $major-grid-weight, transparent $major-grid-weight, transparent $major-grid-size),
repeating-linear-gradient(0deg, $minor-grid-color, $minor-grid-color $minor-grid-weight, transparent $minor-grid-weight, transparent $minor-grid-size),
repeating-linear-gradient(-90deg, $minor-grid-color, $minor-grid-color $minor-grid-weight, transparent $minor-grid-weight, transparent $minor-grid-size);
}
.grid-stack-item-content {
color: #2c3e50;
border-radius: 7px !important;
border-style: solid;
border-width: 1px;
border-color: black;
text-align: center;
background-color: #252525;
}
.grid-stack .grid-stack-placeholder > .placeholder-content {
left: $col-padding;
right: $col-padding;
}
.grid-stack > .grid-stack-item > .grid-stack-item-content {
left: $col-padding;
right: $col-padding;
}
JavaScript
$(function () {
// Initialize gridstack.js
var options = {
float: true,
animate: true,
width: 24,
cellHeight: null,
verticalMargin: 0,
alwaysShowResizeHandle: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
};
$('.grid-stack').gridstack(options);
(function () {
this.grid = $('.grid-stack').data('gridstack');
this.addNewWidget = function () {
this.grid.addWidget($('<div><div class="grid-stack-item-content" /><div/>'),
0, 0, 1, 1, true);
return false;
}.bind(this);
$('#add-new-widget').click(this.addNewWidget);
})();
function generateRepeatingGridBackgroundImageCSS(majorGridSize, minorGridSize) {
var minorGridColor = "rgba(120,120,120,0.22)";
var minorGridWeight = "1px";
var majorGridColor = "rgba(120,120,120,120.44)";
var minorGridWeight = "2px";
return `repeating-linear-gradient(0deg, ${minorGridColor}, ${minorGridColor} ${minorGridWeight}, transparent ${minorGridWeight}, transparent ${majorGridSize}),
repeating-linear-gradient(-90deg, ${minorGridColor}, ${minorGridColor} ${minorGridWeight}, transparent ${minorGridWeight}, transparent ${majorGridSize}),
repeating-linear-gradient(0deg, ${minorGridColor}, ${minorGridColor} ${minorGridWeight}, transparent ${minorGridWeight}, transparent ${minorGridSize}),
repeating-linear-gradient(-90deg, ${minorGridColor}, ${minorGridColor} ${minorGridWeight}, transparent ${minorGridWeight}, transparent ${minorGridSize})`;
}
function updateGridSize() {
var $grid = $('.grid-stack').data('gridstack');
$grid.cellHeight($grid.cellWidth());
var majorGridSize = ($grid.cellWidth()*4).toString().concat("px");
var minorGridSize = ($grid.cellWidth()).toString().concat("px");
$('.repeating-grid').css("background-size", `${majorGridSize} ${majorGridSize}`);
...