Skip to content

Commit 9f47613

Browse files
committed
can drag nested grid over nested grid - Part 2
* more partial fix for #1009 and #992 * you can now drag a nested grid over another one and nest it deeper (992) * fixed size transition * fixed handlers not set when nesting TODO: fix pause to work for enter/leave, more nested testing. Fix tests
1 parent 9200ce0 commit 9f47613

File tree

5 files changed

+32
-23
lines changed

5 files changed

+32
-23
lines changed

demo/nested_advanced.html

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,20 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1">
77
<title>Advance Nested grids demo</title>
88
<link rel="stylesheet" href="demo.css"/>
9-
<link rel="stylesheet" href="../dist/gridstack-extra.min.css"/>
9+
<link rel="stylesheet" href="../dist/gridstack-extra.min.css"/> <!-- required for [2-11] column of sub-grids -->
1010
<script src="../dist/gridstack-all.js"></script>
1111
</head>
1212
<body>
1313
<div class="container-fluid">
1414
<h1>Advanced Nested grids demo</h1>
15-
<p>Create sub-grids on the fly, by dragging items completely over others (nest) vs partially (push) using
15+
<p>Create sub-grids (darker background) on the fly, by dragging items completely over others (nest) vs partially (push) using
1616
the new v7 API <code>GridStackOptions.subGrid.createDynamic=true</code></p>
1717
<p>This will use the new delay drag&drop option <code>DDDragOpt.pause</code> to tell the gesture difference</p>
18+
<p>Note: <code>gridstack-extra.min.css</code> is required for [2-11] column of sub-grids</p>
1819
<a class="btn btn-primary" onClick="addNested()" href="#">Add Widget</a>
19-
<a class="btn btn-primary" onClick="addNewWidget('sub1_grid')" href="#">Add Widget Grid1</a>
20+
<a class="btn btn-primary" onClick="addNewWidget(0)" href="#">Add W Grid0</a>
21+
<a class="btn btn-primary" onClick="addNewWidget(1)" href="#">Add W Grid1</a>
22+
<a class="btn btn-primary" onClick="addNewWidget(2)" href="#">Add W Grid2</a>
2023
<span>entire save/re-create:</span>
2124
<a class="btn btn-primary" onClick="save()" href="#">Save</a>
2225
<a class="btn btn-primary" onClick="destroy()" href="#">Destroy</a>
@@ -31,10 +34,11 @@ <h1>Advanced Nested grids demo</h1>
3134
</div>
3235

3336
<script type="text/javascript">
34-
let main = [{x:0, y:0}, {x:1, y:0}, {x:0, y:1}]
37+
let main = [{x:0, y:0}, {x:0, y:1}, {x:0, y:2}]
38+
let sub0 = [{x:0, y:0}];
3539
let sub1 = [{x:0, y:0}, {x:1, y:0}];
3640
let count = 0;
37-
[...main, ...sub1].forEach(d => d.content = String(count++));
41+
[...main, ...sub0, ...sub1].forEach(d => d.content = String(count++));
3842
let subOptions = {
3943
cellHeight: 50, // should be 50 - top/bottom
4044
column: 'auto', // size to match container. make sure to include gridstack-extra.min.css
@@ -51,44 +55,46 @@ <h1>Advanced Nested grids demo</h1>
5155
subGrid: subOptions,
5256
children: [
5357
...main,
54-
{x:2, y:0, w:2, h:3, subGrid: {children: sub1, id:'sub1_grid', ...subOptions}/*,content: "<div>nested grid here</div>"*/},
58+
{x:1, y:2, h:2, subGrid: {children: sub0, ...subOptions}},
59+
{x:2, y:0, w:2, h:3, subGrid: {children: sub1, ...subOptions}},
60+
// {x:2, y:0, w:2, h:3, subGrid: {children: [...sub1, {x:0, y:1, subGrid: subOptions}], ...subOptions}/*,content: "<div>nested grid here</div>"*/},
5561
]
5662
};
5763

5864
// create and load it all from JSON above
5965
let grid = GridStack.addGrid(document.querySelector('.container-fluid'), options);
6066

61-
addNested = function() {
67+
function addNested() {
6268
grid.addWidget({x:0, y:100, content:"new item"});
6369
}
6470

65-
addNewWidget = function(selector) {
66-
let subGrid = document.querySelector(selector).gridstack;
71+
function addNewWidget(i) {
72+
let subGrid = document.querySelectorAll('.grid-stack-nested')[i].gridstack;
6773
let node = {
68-
x: Math.round(6 * Math.random()),
69-
y: Math.round(5 * Math.random()),
70-
w: Math.round(1 + 1 * Math.random()),
71-
h: Math.round(1 + 1 * Math.random()),
74+
// x: Math.round(6 * Math.random()),
75+
// y: Math.round(5 * Math.random()),
76+
// w: Math.round(1 + 1 * Math.random()),
77+
// h: Math.round(1 + 1 * Math.random()),
7278
content: String(count++)
7379
};
7480
subGrid.addWidget(node);
7581
return false;
7682
};
7783

78-
save = function(content = true, full = true) {
84+
function save(content = true, full = true) {
7985
options = grid.save(content, full);
8086
console.log(options);
8187
// console.log(JSON.stringify(options));
8288
}
83-
destroy = function(full = true) {
89+
function destroy(full = true) {
8490
if (full) {
8591
grid.destroy();
8692
grid = undefined;
8793
} else {
8894
grid.removeAll();
8995
}
9096
}
91-
load = function(full = true) {
97+
function load(full = true) {
9298
if (full) {
9399
grid = GridStack.addGrid(document.querySelector('.container-fluid'), options);
94100
} else {

src/dd-droppable.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export class DDDroppable extends DDBaseImplement implements HTMLElementExtendOpt
8888
protected _mouseEnter(e: MouseEvent): void {
8989
// console.log(`${count++} Enter ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST
9090
if (!DDManager.dragElement) return;
91-
if (!this._canDrop()) return;
91+
if (!this._canDrop(DDManager.dragElement.el)) return;
9292
e.preventDefault();
9393
e.stopPropagation();
9494

@@ -148,8 +148,8 @@ export class DDDroppable extends DDBaseImplement implements HTMLElementExtendOpt
148148
}
149149

150150
/** @internal true if element matches the string/method accept option */
151-
protected _canDrop(): boolean {
152-
return DDManager.dragElement && (!this.accept || this.accept(DDManager.dragElement.el));
151+
protected _canDrop(el: HTMLElement): boolean {
152+
return el && (!this.accept || this.accept(el));
153153
}
154154

155155
/** @internal */

src/dd-gridstack.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,6 @@ GridStack.prototype._setupAcceptWidget = function(this: GridStack): GridStack {
222222
// set accept drop to true on ourself (which we ignore) so we don't get "can't drop" icon in HTML5 mode while moving
223223
if (node?.grid === this) return true;
224224
if (!this.opts.acceptWidgets) return false;
225-
// prevent deeper nesting until rest of 992 can be fixed
226-
if (node?.subGrid) return false;
227225
// check for accept method or class matching
228226
let canAccept = true;
229227
if (typeof this.opts.acceptWidgets === 'function') {
@@ -365,6 +363,8 @@ GridStack.prototype._setupAcceptWidget = function(this: GridStack): GridStack {
365363
Utils.removePositioningStyles(el);// @ts-ignore
366364
this._writeAttr(el, node);
367365
this.el.appendChild(el);// @ts-ignore // TODO: now would be ideal time to _removeHelperStyle() overriding floating styles (native only)
366+
let subGrid: GridStack = node.subGrid;
367+
if (subGrid?.el && !subGrid.opts.styleInHead) subGrid._updateStyles(true); // re-create sub-grid styles now that we've moved
368368
this._updateContainerHeight();
369369
this.engine.addedNodes.push(node);// @ts-ignore
370370
this._triggerAddEvent();// @ts-ignore

src/gridstack.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ $animation_speed: .3s !default;
112112
&.grid-stack-animate .grid-stack-item.ui-draggable-dragging,
113113
&.grid-stack-animate .grid-stack-item.ui-resizable-resizing,
114114
&.grid-stack-animate .grid-stack-item.grid-stack-placeholder{
115-
@include vendor(transition, left .0s, top .0s, height .0s, width .0s);
115+
@include vendor(transition, left 0s, top 0s, height 0s, width 0s);
116116
}
117117

118118
// without this, the html5 drag will flicker between no-drop and drop when dragging over second grid

src/gridstack.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ export class GridStack {
464464
let newItem: HTMLElement;
465465
let newItemOpt: GridStackNode;
466466
if (saveContent) {
467-
this._removeDD(el); // remove any (content) D7D
467+
this._removeDD(node.el); // remove D&D since it's set on content div
468468
let doc = document.implementation.createHTMLDocument(''); // IE needs a param
469469
doc.body.innerHTML = `<div class="grid-stack-item"></div>`;
470470
newItem = doc.body.children[0] as HTMLElement;
@@ -482,7 +482,10 @@ export class GridStack {
482482
if (nodeToAdd) {
483483
let w = autoColumn ? ops.column : node.w;
484484
let h = node.h + nodeToAdd.h;
485+
let style = node.el.style;
486+
style.transition = 'none'; // show up instantly so we don't see scrollbar with nodeToAdd
485487
this.update(node.el, {w, h});
488+
setTimeout(() => style.transition = null); // recover animation
486489
ops.isTemp = true; // prevent re-nesting as we add over
487490
}
488491

0 commit comments

Comments
 (0)