Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Join us on Slack: https://gridstackjs.troolee.com
- [Touch devices support](#touch-devices-support)
- [Migrating to v0.6.x](#migrating-to-v06x)
- [Migrating to v1.0.0](#migrating-to-v100)
- [Migrating to v2.0.0](#migrating-to-v200)
- [Changes](#changes)
- [The Team](#the-team)

Expand Down Expand Up @@ -323,6 +324,20 @@ Recommend looking at the [many samples](./demo) for more code examples.

We're working on implementing HTML5 drag'n'drop through the plugin system. Right now it is still jquery-ui based. Because of that we are still bundling `jquery` (3.4.1) + `jquery-ui` (1.12.1 minimal drag|drop|resize) internally in `gridstack.all.js`. IFF your app needs to bring it's own version instead, you should **instead** include `gridstack-poly.min.js` (optional IE support) + `gridstack.min.js` + `gridstack.jQueryUI.min.js` + after you import your libs.

## Migrating to v2.0.0

make sure to read v1.0.0 migration first!

v2.x is a Typescript rewrite of 1.x, using classes and overall code cleanup. You code might not need change from 1.x

In general methods that used optional args as getting vs setting are not used in Typescript.
Also legacy methods that used to take tons of parameters will now take an object.

```
removed `addWidget(el, x, y, width, ...)` --> use the widget options version instead `addWidget(el, {x, y, with,...})`
`float()` to get value --> `getFloat()`
```

Changes
=====

Expand Down
2 changes: 1 addition & 1 deletion demo/anijs.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ <h4>Widget added</h4>
});

function addWidget() {
grid.addWidget('<div><div class="grid-stack-item-content"></div></div>', 0, 0, Math.floor(1 + 3 * Math.random()), Math.floor(1 + 3 * Math.random()), true);
grid.addWidget('<div><div class="grid-stack-item-content"></div></div>', {width: Math.floor(1 + 3 * Math.random()), height: Math.floor(1 + 3 * Math.random())});
};

var animationHelper = AniJS.getHelper();
Expand Down
4 changes: 2 additions & 2 deletions demo/float.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ <h1>Float grid demo</h1>
};

toggleFloat = function() {
grid.float(! grid.float());
document.querySelector('#float').innerHTML = 'float: ' + grid.float();
grid.float(! grid.getFloat());
document.querySelector('#float').innerHTML = 'float: ' + grid.getFloat();
};
addNewWidget();
</script>
Expand Down
4 changes: 2 additions & 2 deletions demo/two.html
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,8 @@ <h1>Two grids demo</h1>
});

function toggleFloat(button, i) {
grids[i].float(! grids[i].float());
button.innerHTML = 'float: ' + grids[i].float();
grids[i].float(! grids[i].getFloat());
button.innerHTML = 'float: ' + grids[i].getFloat();
}

function compact(i) {
Expand Down
1 change: 1 addition & 0 deletions doc/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Change log
- fix [1187](https://github.com/gridstack/gridstack.js/issues/1187) IE support for `CustomEvent` polyfill - thanks [@phil-blais](https://github.com/phil-blais)
- fix [1204](https://github.com/gridstack/gridstack.js/issues/1204) destroy drag&drop when removing node(s) instead of just disabling it.
- include SASS source files to npm package again [1193](https://github.com/gridstack/gridstack.js/pull/1193) - include SASS source files to npm package again [1193](https://github.com/gridstack/gridstack.js/pull/1193)
- fix [1217](https://github.com/gridstack/gridstack.js/issues/1217) If I set `cellHeight` to some `vh`, only first grid will take `vh`, rest will use `px`
- add `getGridItems()` to return list of HTML grid items

## 1.1.0 (2020-02-29)
Expand Down
25 changes: 6 additions & 19 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ gridstack.js API
- [gsresizestop(event, ui)](#gsresizestopevent-ui)
- [API](#api)
- [addWidget(el, [options])](#addwidgetel-options)
- [addWidget(el, [x, y, width, height, autoPosition, minWidth, maxWidth, minHeight, maxHeight, id])](#addwidgetel-x-y-width-height-autoposition-minwidth-maxwidth-minheight-maxheight-id)
- [batchUpdate()](#batchupdate)
- [compact()](#compact)
- [cellHeight()](#cellheight)
Expand Down Expand Up @@ -239,30 +238,19 @@ grid.on('gsresizestop', function(event, element) {

### addWidget(el, [options])

Creates new widget and returns it. Options is an object containing the fields x,y,width,height,etc... described below.

### addWidget(el, [x, y, width, height, autoPosition, minWidth, maxWidth, minHeight, maxHeight, id])

Creates new widget and returns it.
Creates new widget and returns it. Options is an object containing the fields x,y,width,height,etc...

Parameters:

- `el` - widget to add
- `x`, `y`, `width`, `height` - widget position/dimensions (optional)
- `autoPosition` - if `true` then `x`, `y` parameters will be ignored and widget will be places on the first available
position (optional)
- `minWidth` minimum width allowed during resize/creation (optional)
- `maxWidth` maximum width allowed during resize/creation (optional)
- `minHeight` minimum height allowed during resize/creation (optional)
- `maxHeight` maximum height allowed during resize/creation (optional)
- `id` value for `data-gs-id` (optional)
- `el` - html element or string definition to add
- `options` widget position/size options (optional) - see GridStackWidget

Widget will be always placed even if result height is more than actual grid height. You need to use `willItFit` method
before calling `addWidget` for additional check.

```js
var grid = GridStack.init();
grid.addWidget(el, 0, 0, 3, 2, true);
grid.addWidget('<div><div class="grid-stack-item-content">hello</div></div>', {width: 3});
```

### batchUpdate()
Expand Down Expand Up @@ -507,15 +495,14 @@ Returns `true` if the `height` of the grid will be less the vertical constraint.
have `height` constraint.

```js
if (grid.willItFit(newNode.x, newNode.y, newNode.width, newNode.height, true)) {
grid.addWidget(newNode.el, newNode.x, newNode.y, newNode.width, newNode.height, true);
if (grid.willItFit(newNode.x, newNode.y, newNode.width, newNode.height, newNode.autoPosition)) {
grid.addWidget(newNode.el, newNode);
}
else {
alert('Not enough free space to place the widget');
}
```


## Utils

### GridStack.Utils.sort(nodes[, dir[, width]])
Expand Down
25 changes: 13 additions & 12 deletions spec/gridstack-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,8 @@ describe('gridstack', function() {
});
it('should keep all widget options the same (autoPosition off', function() {
var grid = GridStack.init({float: true});;
var widget = grid.addWidget(widgetHTML, 6, 7, 2, 3, false, 1, 4, 2, 5, 'coolWidget');
var widget = grid.addWidget(widgetHTML, {x: 6, y:7, width:2, height:3, autoPosition:false,
mindWidth:1, maxWidth:4, mindHeight:2, maxHeight:5, id:'coolWidget'});
var $widget = $(widget);
expect(parseInt($widget.attr('data-gs-x'), 10)).toBe(6);
expect(parseInt($widget.attr('data-gs-y'), 10)).toBe(7);
Expand All @@ -767,9 +768,9 @@ describe('gridstack', function() {
expect($widget.attr('data-gs-id')).toBe('coolWidget');

// should move widget to top with float=false
expect(grid.float()).toBe(true);
expect(grid.getFloat()).toBe(true);
grid.float(false);
expect(grid.float()).toBe(false);
expect(grid.getFloat()).toBe(false);
expect(parseInt($widget.attr('data-gs-x'), 10)).toBe(6);
expect(parseInt($widget.attr('data-gs-y'), 10)).toBe(4); // <--- from 7 to 4 below second original widget
expect(parseInt($widget.attr('data-gs-width'), 10)).toBe(2);
Expand All @@ -783,7 +784,7 @@ describe('gridstack', function() {

// should not move again (no-op)
grid.float(true);
expect(grid.float()).toBe(true);
expect(grid.getFloat()).toBe(true);
expect(parseInt($widget.attr('data-gs-x'), 10)).toBe(6);
expect(parseInt($widget.attr('data-gs-y'), 10)).toBe(4);
expect(parseInt($widget.attr('data-gs-width'), 10)).toBe(2);
Expand All @@ -806,7 +807,7 @@ describe('gridstack', function() {
});
it('should change x, y coordinates for widgets.', function() {
var grid = GridStack.init({float: true});
var widget = grid.addWidget(widgetHTML, 9, 7, 2, 3, true);
var widget = grid.addWidget(widgetHTML, {x:9, y:7, width:2, height:3, autoPosition:true});
var $widget = $(widget);
expect(parseInt($widget.attr('data-gs-x'), 10)).not.toBe(9);
expect(parseInt($widget.attr('data-gs-y'), 10)).not.toBe(7);
Expand Down Expand Up @@ -925,14 +926,14 @@ describe('gridstack', function() {
it('should clear x position', function() {
var grid = GridStack.init({float: true});
var widgetHTML = '<div class="grid-stack-item" data-gs-x="9"><div class="grid-stack-item-content"></div></div>';
var widget = grid.addWidget(widgetHTML, null, null, undefined);
var widget = grid.addWidget(widgetHTML, {x:null, y:null, width:undefined});
var $widget = $(widget);
expect(parseInt($widget.attr('data-gs-x'), 10)).toBe(8);
expect(parseInt($widget.attr('data-gs-y'), 10)).toBe(0);
});
});

describe('method float()', function() {
describe('method getFloat()', function() {
beforeEach(function() {
document.body.insertAdjacentHTML('afterbegin', gridstackHTML);
});
Expand All @@ -941,15 +942,15 @@ describe('gridstack', function() {
});
it('should match true/false only', function() {
var grid = GridStack.init({float: true});
expect(grid.float()).toBe(true);
expect(grid.getFloat()).toBe(true);
grid.float(0);
expect(grid.float()).toBe(false);
expect(grid.getFloat()).toBe(false);
grid.float(null);
expect(grid.float()).toBe(false);
expect(grid.getFloat()).toBe(false);
grid.float(undefined);
expect(grid.float()).toBe(false);
expect(grid.getFloat()).toBe(false);
grid.float(false);
expect(grid.float()).toBe(false);
expect(grid.getFloat()).toBe(false);
});
});

Expand Down
24 changes: 0 additions & 24 deletions spec/gridstack-tests.ts

This file was deleted.

78 changes: 40 additions & 38 deletions src/gridstack-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,16 @@ export class GridStackEngine {
while (true) {
let collisionNode = this.nodes.find( n => n !== node && Utils.isIntercepted(n, nn), {node: node, nn: nn});
if (!collisionNode) { return; }
this.moveNode(collisionNode, collisionNode.x, node.y + node.height,
collisionNode.width, collisionNode.height, true);
let moved;
if (collisionNode.locked) {
// if colliding with a locked item, move ourself instead
moved = this.moveNode(node, node.x, collisionNode.y + collisionNode.height,
node.width, node.height, true);
} else {
moved = this.moveNode(collisionNode, collisionNode.x, node.y + node.height,
collisionNode.width, collisionNode.height, true);
}
if (!moved) { return; } // break inf loop if we couldn't move after all (ex: maxRow, fixed)
}
}

Expand Down Expand Up @@ -112,7 +120,7 @@ export class GridStackEngine {
}

/** float getter method */
public get float(): boolean { return this._float; }
public get float(): boolean { return this._float || false; }

private _sortNodes(dir?: -1 | 1) {
this.nodes = Utils.sort(this.nodes, dir, this.column);
Expand Down Expand Up @@ -180,13 +188,6 @@ export class GridStackEngine {
let defaults = {width: 1, height: 1, x: 0, y: 0};
node = Utils.defaults(node, defaults);

// convert any strings over
/* TODO: check
node.x = parseInt(node.x);
node.y = parseInt(node.y);
node.width = parseInt(node.width);
node.height = parseInt(node.height);
*/
node.autoPosition = node.autoPosition || false;
node.noResize = node.noResize || false;
node.noMove = node.noMove || false;
Expand All @@ -197,19 +198,29 @@ export class GridStackEngine {
if (Number.isNaN(node.width)) { node.width = defaults.width; }
if (Number.isNaN(node.height)) { node.height = defaults.height; }

if (node.maxWidth) { node.width = Math.min(node.width, node.maxWidth); }
if (node.maxHeight) { node.height = Math.min(node.height, node.maxHeight); }
if (node.minWidth) { node.width = Math.max(node.width, node.minWidth); }
if (node.minHeight) { node.height = Math.max(node.height, node.minHeight); }

if (node.width > this.column) {
node.width = this.column;
} else if (node.width < 1) {
node.width = 1;
}

if (node.height < 1) {
if (this.maxRow && node.height > this.maxRow) {
node.height = this.maxRow;
} else if (node.height < 1) {
node.height = 1;
}

if (node.x < 0) {
node.x = 0;
}
if (node.y < 0) {
node.y = 0;
}

if (node.x + node.width > this.column) {
if (resizing) {
Expand All @@ -218,9 +229,12 @@ export class GridStackEngine {
node.x = this.column - node.width;
}
}

if (node.y < 0) {
node.y = 0;
if (this.maxRow && node.y + node.height > this.maxRow) {
if (resizing) {
node.height = this.maxRow - node.y;
} else {
node.y = this.maxRow - node.height;
}
}

return node;
Expand Down Expand Up @@ -263,11 +277,6 @@ export class GridStackEngine {
public addNode(node: GridStackNode, triggerAddEvent?: boolean) {
node = this.prepareNode(node);

if (node.maxWidth) { node.width = Math.min(node.width, node.maxWidth); }
if (node.maxHeight) { node.height = Math.min(node.height, node.maxHeight); }
if (node.minWidth) { node.width = Math.max(node.width, node.minWidth); }
if (node.minHeight) { node.height = Math.max(node.height, node.minHeight); }

node._id = node._id || GridStackEngine._idSeq++;

if (node.autoPosition) {
Expand Down Expand Up @@ -393,34 +402,27 @@ export class GridStackEngine {
}

public moveNode(node: GridStackNode, x: number, y: number, width?: number, height?: number, noPack?: boolean): GridStackNode {
if (node.locked) { return null; }
if (typeof x !== 'number') { x = node.x; }
if (typeof y !== 'number') { y = node.y; }
if (typeof width !== 'number') { width = node.width; }
if (typeof height !== 'number') { height = node.height; }

if (node.maxWidth) { width = Math.min(width, node.maxWidth); }
if (node.maxHeight) { height = Math.min(height, node.maxHeight); }
if (node.minWidth) { width = Math.max(width, node.minWidth); }
if (node.minHeight) { height = Math.max(height, node.minHeight); }

if (node.x === x && node.y === y && node.width === width && node.height === height) {
return node;
// constrain the passed in values and check if we're still changing our node
let resizing = (node.width !== width || node.height !== height);
let nn: GridStackNode = { x, y, width, height,
maxWidth: node.maxWidth, maxHeight: node.maxHeight, minWidth: node.minWidth, minHeight: node.minHeight};
nn = this.prepareNode(nn, resizing);
if (node.x === nn.x && node.y === nn.y && node.width === nn.width && node.height === nn.height) {
return null;
}

let resizing = node.width !== width;
node._dirty = true;

node.x = x;
node.y = y;
node.width = width;
node.height = height;

node._lastTriedX = x;
node._lastTriedY = y;
node._lastTriedWidth = width;
node._lastTriedHeight = height;

node = this.prepareNode(node, resizing);
node.x = node._lastTriedX = nn.x;
node.y = node._lastTriedY = nn.y;
node.width = node._lastTriedWidth = nn.width;
node.height = node._lastTriedHeight = nn.height;

this._fixCollisions(node);
if (!noPack) {
Expand Down
Loading