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
1 change: 1 addition & 0 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ <h1>Demos</h1>
<li><a href="responsive.html">Responsive</a></li>
<li><a href="right-to-left(rtl).html">Right-To-Left (RTL)</a></li>
<li><a href="serialization.html">Serialization</a></li>
<li><a href="static.html">Static</a></li>
<li><a href="two.html">Two grids</a></li>
<li><a href="vuej2s.html">Vue2.js</a></li>
<li><a href="vuej3s.html">Vue3.js</a></li>
Expand Down
43 changes: 43 additions & 0 deletions demo/static.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Static Grid</title>

<link rel="stylesheet" href="demo.css"/>
<script src="../dist/gridstack.all.js"></script>

</head>
<body>
<div class="container-fluid">
<h1>Static vs can move/drag Demo</h1>
<div>
<a class="btn btn-primary" onClick="grid.setStatic(true)" href="#">Static</a>
<a class="btn btn-primary" onclick="grid.setStatic(false)" id="float" href="#">Editable</a>
</div>
<br><br>
<div class="grid-stack"></div>
</div>
<script src="events.js"></script>
<script type="text/javascript">
let grid = GridStack.init({
float: true,
cellHeight: 70,
staticGrid: true
});
addEvents(grid);

let serializedData = [
{x: 0, y: 0, width: 2, height: 2, id: '0'},
{x: 3, y: 1, width: 1, height: 2, id: 'no_move', noMove: true, html: 'no move'},
{x: 4, y: 1, width: 1, height: 1, id: '2'},
{x: 2, y: 3, width: 3, height: 1, id: 'no_resize', noResize: true, html: 'no resize'},
{x: 1, y: 3, width: 1, height: 1, id: 'locked', locked: true, html: 'locked'}
];
grid.load(serializedData, true);

</script>
</body>
</html>
4 changes: 3 additions & 1 deletion doc/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ Change log

## 2.0.2-dev

- TBD
- fix grid `static: true` to no longer add any drag&drop (even disabled) which should speed things up, and `setStatic(T/F)` will now correctly add it back/delete for items that need it only.
Also fixed JQ draggable warning if not initialized first [858](https://github.com/gridstack/gridstack.js/issues/858)
- add `GridStackWidget.html` now lets you add any HTML content when calling `grid.load()`

## 2.0.2 (2020-10-05)

Expand Down
1 change: 1 addition & 0 deletions doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ You need to add `noResize` and `noMove` attributes to completely lock the widget
- `noMove` - disable element moving
- `resizeHandles` - sets resize handles for a specific widget.
- `id`- (number | string) good for quick identification (for example in change event)
- `html` - (string) html content to be added when calling `grid.load()` as content inside the item

## Item attributes

Expand Down
9 changes: 9 additions & 0 deletions src/gridstack-dd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ export class GridStackDD {
this.grid = grid;
}

/** removes any drag&drop present (called during destroy) */
public remove(el: GridItemHTMLElement): GridStackDD {
this.draggable(el, 'destroy').resizable(el, 'destroy');
if (el.gridstackNode) {
delete el.gridstackNode._initDD; // reset our DD init flag
}
return this;
}

public resizable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): GridStackDD {
return this;
}
Expand Down
52 changes: 33 additions & 19 deletions src/gridstack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ export class GridStack {
if (typeof(addAndRemove) === 'function') {
addAndRemove(w, true);
} else {
this.addWidget('<div><div class="grid-stack-item-content"></div></div>', w);
this.addWidget(`<div><div class="grid-stack-item-content">${w.html || ''}</div></div>`, w);
}
}
});
Expand Down Expand Up @@ -539,7 +539,7 @@ export class GridStack {
*/
public destroy(removeDOM = true): GridStack {
this._updateWindowResizeEvent(true);
this.disable();
this.setStatic(true); // permanently removes DD
if (!removeDOM) {
this.removeAll(removeDOM);
this.el.classList.remove(this.opts._class);
Expand Down Expand Up @@ -586,6 +586,7 @@ export class GridStack {
* doEnable`s value by changing the disableDrag grid option (default: true).
*/
public enableMove(doEnable: boolean, includeNewWidgets = true): GridStack {
if (doEnable && this.opts.staticGrid) { return this; } // can't move a static grid!
this.getGridItems().forEach(el => this.movable(el, doEnable));
if (includeNewWidgets) {
this.opts.disableDrag = !doEnable;
Expand All @@ -600,6 +601,7 @@ export class GridStack {
* doEnable`s value by changing the disableResize grid option (default: true).
*/
public enableResize(doEnable: boolean, includeNewWidgets = true): GridStack {
if (doEnable && this.opts.staticGrid) { return this; } // can't size a static grid!
this.getGridItems().forEach(el => this.resizable(el, doEnable));
if (includeNewWidgets) {
this.opts.disableResize = !doEnable;
Expand Down Expand Up @@ -756,6 +758,7 @@ export class GridStack {
* @param val if true widget will be draggable.
*/
public movable(els: GridStackElement, val: boolean): GridStack {
if (val && this.opts.staticGrid) { return this; } // can't move a static grid!
GridStack.getElements(els).forEach(el => {
let node = el.gridstackNode;
if (!node) { return }
Expand All @@ -764,6 +767,7 @@ export class GridStack {
this.dd.draggable(el, 'disable');
el.classList.remove('ui-draggable-handle');
} else {
this._prepareDragDropByNode(node); // init DD if need be
this.dd.draggable(el, 'enable');
el.classList.remove('ui-draggable-handle');
}
Expand Down Expand Up @@ -872,7 +876,7 @@ export class GridStack {

// remove our DOM data (circular link) and drag&drop permanently
delete el.gridstackNode;
this.dd.draggable(el, 'destroy').resizable(el, 'destroy');
this.dd.remove(el);

this.engine.removeNode(node, removeDOM, triggerEvent);

Expand All @@ -895,7 +899,7 @@ export class GridStack {
// always remove our DOM data (circular link) before list gets emptied and drag&drop permanently
this.engine.nodes.forEach(n => {
delete n.el.gridstackNode;
this.dd.draggable(n.el, 'destroy').resizable(n.el, 'destroy');
this.dd.remove(n.el);
});
this.engine.removeAll(removeDOM);
this._triggerRemoveEvent();
Expand Down Expand Up @@ -924,13 +928,15 @@ export class GridStack {
* @param val if true widget will be resizable.
*/
public resizable(els: GridStackElement, val: boolean): GridStack {
if (val && this.opts.staticGrid) { return this; } // can't resize a static grid!
GridStack.getElements(els).forEach(el => {
let node = el.gridstackNode;
if (!node) { return; }
node.noResize = !(val || false);
if (node.noResize) {
this.dd.resizable(el, 'disable');
} else {
this._prepareDragDropByNode(node); // init DD if need be
this.dd.resizable(el, 'enable');
}
});
Expand All @@ -951,13 +957,19 @@ export class GridStack {
}

/**
* Toggle the grid static state. Also toggle the grid-stack-static class.
* @param staticValue if true the grid become static.
* Toggle the grid static state, which permanently removes/add Drag&Drop support, unlike disable()/enable() that just turns it off/on.
* Also toggle the grid-stack-static class.
* @param val if true the grid become static.
*/
public setStatic(staticValue: boolean): GridStack {
this.opts.staticGrid = (staticValue === true);
this.enableMove(!staticValue);
this.enableResize(!staticValue);
public setStatic(val: boolean): GridStack {
if (this.opts.staticGrid === val) { return this; }
this.opts.staticGrid = val;
// either delete Drag&drop or initialize it
if (val) {
this.getGridItems().forEach(el => this.dd.remove(el));
} else {
this.engine.nodes.forEach(n => this._prepareDragDropByNode(n));
}
this._setStaticClass();
return this;
}
Expand Down Expand Up @@ -1191,6 +1203,12 @@ export class GridStack {

/** @internal prepares the element for drag&drop **/
private _prepareDragDropByNode(node: GridStackNode): GridStack {
// check if init already done or not needed (static/disabled)
if (node._initDD || this.opts.staticGrid ||
((node.noMove || this.opts.disableDrag) && (node.noResize || this.opts.disableResize))) {
return;
}

// variables used/cashed between the 3 start/move/end methods, in addition to node passed above
let cellWidth: number;
let cellHeight: number;
Expand Down Expand Up @@ -1304,7 +1322,7 @@ export class GridStack {
gridToNotify._gsEventHandler[event.type](event, target);
}
gridToNotify.engine.removedNodes.push(node);
gridToNotify.dd.draggable(el, 'destroy').resizable(el, 'destroy');
gridToNotify.dd.remove(el);
delete el.gridstackNode; // hint we're removing it next and break circular link
gridToNotify._triggerRemoveEvent();
if (el.parentElement) {
Expand Down Expand Up @@ -1350,16 +1368,14 @@ export class GridStack {
stop: onEndMoving,
resize: dragOrResize
});
node._initDD = true; // we've set DD support now

if (node.noMove || this.opts.disableDrag || this.opts.staticGrid) {
this.dd.draggable(el, 'disable');
}

if (node.noResize || this.opts.disableResize || this.opts.staticGrid) {
this.dd.resizable(el, 'disable');
}

this._writeAttr(el, node);
return this;
}

Expand All @@ -1379,7 +1395,7 @@ export class GridStack {
let node = this._readAttr(el, { el: el, grid: this });
node = this.engine.addNode(node, triggerAddEvent);
el.gridstackNode = node;

this._writeAttr(el, node);
this._prepareDragDropByNode(node);
return this;
}
Expand Down Expand Up @@ -1474,7 +1490,7 @@ export class GridStack {
private _setStaticClass(): GridStack {
let staticClassName = 'grid-stack-static';

if (this.opts.staticGrid === true) {
if (this.opts.staticGrid) {
this.el.classList.add(staticClassName);
} else {
this.el.classList.remove(staticClassName);
Expand Down Expand Up @@ -1683,9 +1699,7 @@ export class GridStack {
el = el.cloneNode(true) as GridItemHTMLElement;
} else {
el.remove(); // reduce flicker as we change depth here, and size further down
this.dd
.draggable(el, 'destroy')
.resizable(el, 'destroy');
this.dd.remove(el);
}
el.gridstackNode = node;
node.el = el;
Expand Down
12 changes: 6 additions & 6 deletions src/jq/gridstack-dd-jqueryui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ export class GridStackDDJQueryUI extends GridStackDD {

public resizable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): GridStackDD {
let $el: JQuery = $(el);
if (opts === 'disable' || opts === 'enable') {
$el.resizable(opts);
} else if (opts === 'destroy') {
if (opts === 'enable') {
$el.resizable().resizable(opts);
} else if (opts === 'disable' || opts === 'destroy') {
if ($el.data('ui-resizable')) { // error to call destroy if not there
$el.resizable(opts);
}
Expand All @@ -47,9 +47,9 @@ export class GridStackDDJQueryUI extends GridStackDD {

public draggable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): GridStackDD {
let $el: JQuery = $(el);
if (opts === 'disable' || opts === 'enable') {
$el.draggable(opts);
} else if (opts === 'destroy') {
if (opts === 'enable') {
$el.draggable().draggable('enable');
} else if (opts === 'disable' || opts === 'destroy') {
if ($el.data('ui-draggable')) { // error to call destroy if not there
$el.draggable(opts);
}
Expand Down
4 changes: 4 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ export interface GridStackWidget {
resizeHandles?: string;
/** value for `data-gs-id` stored on the widget (default?: undefined) */
id?: numberOrString;
/** html to append inside the content */
html?: string;
}

/** Drag&Drop resize options */
Expand Down Expand Up @@ -291,4 +293,6 @@ export interface GridStackNode extends GridStackWidget {
_prevYPix?: number;
/** @internal */
_temporaryRemoved?: boolean;
/** @internal */
_initDD?: boolean;
}