Merge commit '9d80ede0b90840f5ad3b06a30f9f0d2cc66a2891'

This commit is contained in:
d 2016-02-22 08:57:58 -05:00
commit d1c90cf3d7
19 changed files with 354 additions and 30 deletions

View file

@ -14,5 +14,6 @@
"validateLineBreaks": false,
"requireTrailingComma": false,
"disallowTrailingWhitespace": true,
"requireCapitalizedComments": false,
"excludeFiles": ["dist/*.js", "demo/*"]
}

View file

@ -33,6 +33,7 @@ Join gridstack.js on Slack: https://gridstackjs.troolee.com
- [Override resizable/draggable options](#override-resizabledraggable-options)
- [IE8 support](#ie8-support)
- [Nested grids](#nested-grids)
- [Resizing active grid](#resizing-active-grid)
- [Changes](#changes)
- [v0.2.5-dev (Development version)](#v025-dev-development-version)
- [v0.2.4 (2016-02-15)](#v024-2016-02-15)
@ -426,6 +427,12 @@ during initialization.
See example: [Nested grid demo](http://troolee.github.io/gridstack.js/demo/nested.html)
## Resizing active grid
Resizing on-the-fly is possible, though experimental. This may be used to make gridstack responsive. gridstack will change the total number of columns and will attempt to update the width and x values of each widget to be more logical.
See example: [Responsive grid demo](http://troolee.github.io/gridstack.js/demo/responsive.html)
Changes
=======
@ -444,6 +451,7 @@ Changes
- fix `setStatic` method
- add `setAnimation` method to API
- add `setGridWidth` method ([#227](https://github.com/troolee/gridstack.js/issues/227))
- add `removable`/`removeTimeout`
#### v0.2.4 (2016-02-15)

View file

@ -11,7 +11,6 @@
<title>Float grid demo</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="../dist/gridstack.css"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

18
demo/index.html Normal file
View file

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
</head>
<body>
<ul>
<li><a href="float.html">Float grid demo</a></li>
<li><a href="knockout.js">Knockout.js demo</a></li>
<li><a href="knockout2.js">Knockout.js demo (2)</a></li>
<li><a href="nested.html">Nested grids demo</a></li>
<li><a href="rtl.html">RTL demo</a></li>
<li><a href="serialization.html">Serialization demo</a></li>
<li><a href="two.html">Two grids demo</a></li>
</ul>
</body>
</html>

View file

@ -11,7 +11,6 @@
<title>Knockout.js demo</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="../dist/gridstack.css"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

View file

@ -11,7 +11,6 @@
<title>Knockout.js demo</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="../dist/gridstack.css"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

View file

@ -11,7 +11,6 @@
<title>Nested grids demo</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="../dist/gridstack.css"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

122
demo/responsive.html Normal file
View file

@ -0,0 +1,122 @@
<!DOCTYPE html>
<html lang="en">
<head>
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Responsive grid demo</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="../dist/gridstack.css"/>
<link rel="stylesheet" href="../dist/gridstack-extra.css"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.min.js"></script>
<script src="../dist/gridstack.js"></script>
<style type="text/css">
.grid-stack {
background: lightgoldenrodyellow;
}
.grid-stack-item-content {
color: #2c3e50;
text-align: center;
background-color: #18bc9c;
}
</style>
</head>
<body>
<div class="device-xs visible-xs"></div>
<div class="device-sm visible-sm"></div>
<div class="device-md visible-md"></div>
<div class="device-lg visible-lg"></div>
<div class="device-xl visible-xl"></div>
<div class="container-fluid">
<h1>Responsive grid demo</h1>
<div>
<span>Number of Columns:</span> <span id="grid-size"></span>
</div>
<br/>
<div class="grid-stack">
</div>
</div>
<script type="text/javascript">
$(function () {
// thanks to http://stackoverflow.com/a/22885503
var waitForFinalEvent=function(){var b={};return function(c,d,a){a||(a="I am a banana!");b[a]&&clearTimeout(b[a]);b[a]=setTimeout(c,d)}}();
var fullDateString = new Date();
function isBreakpoint(alias) {
return $('.device-' + alias).is(':visible');
}
var options = {
float: false
};
$('.grid-stack').gridstack(options);
function resizeGrid() {
var grid = $('.grid-stack').data('gridstack');
if (isBreakpoint('xs')) {
$('#grid-size').text('One column mode');
} else if (isBreakpoint('sm')) {
grid.setGridWidth(3);
$('#grid-size').text(3);
} else if (isBreakpoint('md')) {
grid.setGridWidth(6);
$('#grid-size').text(6);
} else if (isBreakpoint('lg')) {
grid.setGridWidth(12);
$('#grid-size').text(12);
}
};
$(window).resize(function () {
waitForFinalEvent(function() {
resizeGrid();
}, 300, fullDateString.getTime());
});
new function () {
this.serializedData = [
{x: 0, y: 0, width: 4, height: 2},
{x: 3, y: 1, width: 4, height: 2},
{x: 4, y: 1, width: 4, height: 1},
{x: 2, y: 3, width: 8, height: 1},
{x: 0, y: 4, width: 4, height: 1},
{x: 0, y: 3, width: 4, height: 1},
{x: 2, y: 4, width: 4, height: 1},
{x: 2, y: 5, width: 4, height: 1},
{x: 0, y: 6, width: 12, height: 1}
];
this.grid = $('.grid-stack').data('gridstack');
this.loadGrid = function () {
this.grid.removeAll();
var items = GridStackUI.Utils.sort(this.serializedData);
_.each(items, function (node, i) {
this.grid.addWidget($('<div><div class="grid-stack-item-content">' + i + '</div></div>'),
node.x, node.y, node.width, node.height);
}, this);
return false;
}.bind(this);
this.loadGrid();
resizeGrid();
};
});
</script>
</script>
</body>
</html>

View file

@ -11,7 +11,6 @@
<title>RTL demo</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="../dist/gridstack.css"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

View file

@ -11,7 +11,6 @@
<title>Serialization demo</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="../dist/gridstack.css"/>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

View file

@ -11,7 +11,6 @@
<title>Two grids demo</title>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.2.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="../dist/gridstack.css"/>
<link rel="stylesheet" href="../dist/gridstack-extra.css"/>
@ -35,6 +34,14 @@
text-align: center;
background-color: #18bc9c;
}
#grid2 .grid-stack-item-content {
background-color: #9caabc;
}
.grid-stack-item-removing {
opacity: 0.5;
}
</style>
</head>
<body>
@ -58,7 +65,8 @@
$(function () {
var options = {
width: 6,
float: true
float: true,
removable: true
};
$('#grid1').gridstack(options);
$('#grid2').gridstack(options);

5
dist/gridstack.css vendored
View file

@ -83,7 +83,6 @@
}
.grid-stack > .grid-stack-item > .ui-resizable-se {
display: inline-block;
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
@ -155,6 +154,10 @@
bottom: 15px;
}
.grid-stack > .grid-stack-item.ui-draggable-dragging > .ui-resizable-handle {
display: none !important;
}
.grid-stack > .grid-stack-item[data-gs-width='1'] {
width: 8.3333333333%;
}

97
dist/gridstack.js vendored
View file

@ -534,7 +534,9 @@
}),
disableDrag: opts.disableDrag || false,
disableResize: opts.disableResize || false,
rtl: 'auto'
rtl: 'auto',
removable: false,
removeTimeout: 2000
});
if (this.opts.rtl === 'auto') {
@ -805,17 +807,73 @@
var cellWidth;
var cellHeight;
var removeTimeout;
var setupRemovingTimeout = function() {
if (removeTimeout || !self.opts.removable) {
return;
}
removeTimeout = setTimeout(function() {
el.addClass('grid-stack-item-removing');
node._isAboutToRemove = true;
}, self.opts.removeTimeout);
};
var clearRemovingTimeout = function() {
if (!removeTimeout) {
return;
}
clearTimeout(removeTimeout);
removeTimeout = null;
el.removeClass('grid-stack-item-removing');
node._isAboutToRemove = false;
};
var dragOrResize = function(event, ui) {
var x = Math.round(ui.position.left / cellWidth);
var y = Math.floor((ui.position.top + cellHeight / 2) / cellHeight);
var width;
var height;
if (event.type != 'drag') {
width = Math.round(ui.size.width / cellWidth);
height = Math.round(ui.size.height / cellHeight);
}
if (event.type == 'drag') {
if (x < 0 || x >= self.grid.width || y < 0) {
setupRemovingTimeout();
x = node._beforeDragX;
y = node._beforeDragY;
self.placeholder.detach();
self.placeholder.hide();
self.grid.removeNode(node);
self._updateContainerHeight();
node._temporaryRemoved = true;
} else {
clearRemovingTimeout();
if (node._temporaryRemoved) {
self.grid.addNode(node);
self.placeholder
.attr('data-gs-x', x)
.attr('data-gs-y', y)
.attr('data-gs-width', width)
.attr('data-gs-height', height)
.show();
self.container.append(self.placeholder);
node.el = self.placeholder;
node._temporaryRemoved = false;
}
}
} else if (event.type == 'resize') {
if (x < 0) {
return;
}
}
if (!self.grid.canMoveNode(node, x, y, width, height)) {
return;
}
@ -838,6 +896,8 @@
.attr('data-gs-height', o.attr('data-gs-height'))
.show();
node.el = self.placeholder;
node._beforeDragX = node.x;
node._beforeDragY = node.y;
el.resizable('option', 'minWidth', cellWidth * (node.minWidth || 1));
el.resizable('option', 'minHeight', strictCellHeight * (node.minHeight || 1));
@ -848,18 +908,39 @@
};
var onEndMoving = function(event, ui) {
var forceNotify = false;
self.placeholder.detach();
var o = $(this);
node.el = o;
self.placeholder.hide();
o
.attr('data-gs-x', node.x)
.attr('data-gs-y', node.y)
.attr('data-gs-width', node.width)
.attr('data-gs-height', node.height)
.removeAttr('style');
if (node._isAboutToRemove) {
forceNotify = true;
el.removeData('_gridstack_node');
el.remove();
} else {
clearRemovingTimeout();
if (!node._temporaryRemoved) {
o
.attr('data-gs-x', node.x)
.attr('data-gs-y', node.y)
.attr('data-gs-width', node.width)
.attr('data-gs-height', node.height)
.removeAttr('style');
} else {
o
.attr('data-gs-x', node._beforeDragX)
.attr('data-gs-y', node._beforeDragY)
.attr('data-gs-width', node.width)
.attr('data-gs-height', node.height)
.removeAttr('style');
node.x = node._beforeDragX;
node.y = node._beforeDragY;
self.grid.addNode(node);
}
}
self._updateContainerHeight();
self._triggerChangeEvent();
self._triggerChangeEvent(forceNotify);
self.grid.endUpdate();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -75,6 +75,8 @@ gridstack.js API
- `placeholderClass` - class for placeholder (default: `'grid-stack-placeholder'`)
- `placeholderText` - placeholder default content (default: `''`)
- `resizable` - allows to override jQuery UI resizable options. (default: `{autoHide: true, handles: 'se'}`)
- `removable` - if `true` widgets could be removed by dragging outside of the grid (default: `false`)
- `removeTimeout` - time in milliseconds before widget is being removed while dragging outside of the grid. (default: `2000`)
- `rtl` - if `true` turns grid to RTL. Possible values are `true`, `false`, `'auto'` (default: `'auto'`) See [example](http://troolee.github.io/gridstack.js/demo/rtl.html)
- `staticGrid` - makes grid static (default `false`). If true widgets are not movable/resizable. You don't even need jQueryUI draggable/resizable. A CSS class `grid-stack-static` is also added to the container.
- `verticalMargin` - vertical gap size (default: `20`). Can be:

View file

@ -534,7 +534,9 @@
}),
disableDrag: opts.disableDrag || false,
disableResize: opts.disableResize || false,
rtl: 'auto'
rtl: 'auto',
removable: false,
removeTimeout: 2000
});
if (this.opts.rtl === 'auto') {
@ -805,17 +807,73 @@
var cellWidth;
var cellHeight;
var removeTimeout;
var setupRemovingTimeout = function() {
if (removeTimeout || !self.opts.removable) {
return;
}
removeTimeout = setTimeout(function() {
el.addClass('grid-stack-item-removing');
node._isAboutToRemove = true;
}, self.opts.removeTimeout);
};
var clearRemovingTimeout = function() {
if (!removeTimeout) {
return;
}
clearTimeout(removeTimeout);
removeTimeout = null;
el.removeClass('grid-stack-item-removing');
node._isAboutToRemove = false;
};
var dragOrResize = function(event, ui) {
var x = Math.round(ui.position.left / cellWidth);
var y = Math.floor((ui.position.top + cellHeight / 2) / cellHeight);
var width;
var height;
if (event.type != 'drag') {
width = Math.round(ui.size.width / cellWidth);
height = Math.round(ui.size.height / cellHeight);
}
if (event.type == 'drag') {
if (x < 0 || x >= self.grid.width || y < 0) {
setupRemovingTimeout();
x = node._beforeDragX;
y = node._beforeDragY;
self.placeholder.detach();
self.placeholder.hide();
self.grid.removeNode(node);
self._updateContainerHeight();
node._temporaryRemoved = true;
} else {
clearRemovingTimeout();
if (node._temporaryRemoved) {
self.grid.addNode(node);
self.placeholder
.attr('data-gs-x', x)
.attr('data-gs-y', y)
.attr('data-gs-width', width)
.attr('data-gs-height', height)
.show();
self.container.append(self.placeholder);
node.el = self.placeholder;
node._temporaryRemoved = false;
}
}
} else if (event.type == 'resize') {
if (x < 0) {
return;
}
}
if (!self.grid.canMoveNode(node, x, y, width, height)) {
return;
}
@ -838,6 +896,8 @@
.attr('data-gs-height', o.attr('data-gs-height'))
.show();
node.el = self.placeholder;
node._beforeDragX = node.x;
node._beforeDragY = node.y;
el.resizable('option', 'minWidth', cellWidth * (node.minWidth || 1));
el.resizable('option', 'minHeight', strictCellHeight * (node.minHeight || 1));
@ -848,18 +908,39 @@
};
var onEndMoving = function(event, ui) {
var forceNotify = false;
self.placeholder.detach();
var o = $(this);
node.el = o;
self.placeholder.hide();
o
.attr('data-gs-x', node.x)
.attr('data-gs-y', node.y)
.attr('data-gs-width', node.width)
.attr('data-gs-height', node.height)
.removeAttr('style');
if (node._isAboutToRemove) {
forceNotify = true;
el.removeData('_gridstack_node');
el.remove();
} else {
clearRemovingTimeout();
if (!node._temporaryRemoved) {
o
.attr('data-gs-x', node.x)
.attr('data-gs-y', node.y)
.attr('data-gs-width', node.width)
.attr('data-gs-height', node.height)
.removeAttr('style');
} else {
o
.attr('data-gs-x', node._beforeDragX)
.attr('data-gs-y', node._beforeDragY)
.attr('data-gs-width', node.width)
.attr('data-gs-height', node.height)
.removeAttr('style');
node.x = node._beforeDragX;
node.y = node._beforeDragY;
self.grid.addNode(node);
}
}
self._updateContainerHeight();
self._triggerChangeEvent();
self._triggerChangeEvent(forceNotify);
self.grid.endUpdate();

View file

@ -86,10 +86,10 @@ $animation_speed: .3s !default;
}
> .ui-resizable-se {
display: inline-block;
@include vendor(transform, rotate(-45deg));
}
> .ui-resizable-nw { cursor: nw-resize; width: 20px; height: 20px; left: 10px; top: 0; }
> .ui-resizable-n { cursor: n-resize; height: 10px; top: 0; left: 25px; right: 25px; }
> .ui-resizable-ne { cursor: ne-resize; width: 20px; height: 20px; right: 10px; top: 0; }
@ -99,6 +99,12 @@ $animation_speed: .3s !default;
> .ui-resizable-sw { cursor: sw-resize; width: 20px; height: 20px; left: 10px; bottom: 0; }
> .ui-resizable-w { cursor: w-resize; width: 10px; left: $horizontal_padding / 2; top: 15px; bottom: 15px; }
&.ui-draggable-dragging {
&> .ui-resizable-handle {
display: none !important;
}
}
@for $i from 1 through $gridstack-columns {
&[data-gs-width='#{$i}'] { width: (100% / $gridstack-columns) * $i; }
&[data-gs-x='#{$i}'] { left: (100% / $gridstack-columns) * $i; }