Skip to content

Commit 216a6cb

Browse files
authored
Merge pull request #2603 from adumesny/master
demo: nested drop
2 parents 03a056e + b632373 commit 216a6cb

File tree

2 files changed

+35
-63
lines changed

2 files changed

+35
-63
lines changed

demo/nested.html

Lines changed: 34 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,17 @@ <h1>Nested grids demo</h1>
1616
Use v9.2 <b>sizeToContent:true</b> on first subgrid item parent to grow/shrink as needed, while leaving leaf green items unchanged.<br>
1717
Uses v3.1 API to load the entire nested grid from JSON.<br>
1818
Nested grids uses v5 <b>column:'auto'</b> to keep items same size during resize.</p>
19-
<div style="display: flex; flex-direction: row; gap: 5px;">
20-
<a class="btn btn-primary" onClick="addWidget()" href="#">Add Widget</a>
21-
<a class="btn btn-primary" onClick="addNewWidget('.sub1')" href="#">Add Widget Grid1</a>
22-
<a class="btn btn-primary" onClick="addNewWidget('.sub2')" href="#">Add Widget Grid2</a>
23-
<a class="btn btn-primary" onClick="addNested()" href="#">Add Widget With Nested Content</a>
24-
<div style="width: 100px;">
25-
<div
26-
class="gridstack-add-widget grid-stack-item ui-draggable"
27-
gs-h="2"
28-
gs-w="2"
29-
data-gs-drop="true"
30-
>
31-
<div class="grid-stack-item-content">drop a nested widget</div>
32-
</div>
33-
</div>
19+
<div class="actions" style="display: flex; flex-direction: row; gap: 5px;">
20+
<a class="btn btn-primary" onClick="addWidget()" href="#">Add Widget</a>
21+
<a class="btn btn-primary" onClick="addNewWidget('.sub1')" href="#">Add Widget Grid1</a>
22+
<a class="btn btn-primary" onClick="addNewWidget('.sub2')" href="#">Add Widget Grid2</a>
23+
<a class="btn btn-primary" onClick="addNested()" href="#">Add Nested Grid</a>
24+
<div class="sidebar" style="height:50px; padding: 0">
25+
<!-- manually force a drop size of 2x2 for nested size -->
26+
<div class="grid-stack-item" gs-w="2" gs-h="2">
27+
<div class="grid-stack-item-content">Drag nested</div>
28+
</div>
29+
</div>
3430
</div>
3531
<br />
3632
<span>entire save/re-create:</span>
@@ -69,10 +65,6 @@ <h1>Nested grids demo</h1>
6965
{x:5, y:0, w:3, h:4, subGridOpts: {children: sub2, id:'sub2_grid', class: 'sub2', ...subOptions}},
7066
]
7167
};
72-
// setup drag drop behavior
73-
GridStack.setupDragIn('.gridstack-add-widget', {
74-
helper: 'clone',
75-
});
7668

7769
// create and load it all from JSON above
7870
let grid = GridStack.addGrid(document.querySelector('.container-fluid'), options);
@@ -84,13 +76,18 @@ <h1>Nested grids demo</h1>
8476
addEvents(grid, grid.opts.id);
8577
})
8678

79+
// setup drag drop behavior
80+
GridStack.setupDragIn('.sidebar .grid-stack-item', { appendTo: 'body', helper: 'clone' });
81+
8782
function addWidget() {
8883
grid.addWidget({x:0, y:100, content:"new item"});
8984
}
9085

9186
function addNested() {
92-
let subAddNested = [ {w:1, h:1, content: 'hello'}, {w:1, h:1, y: 1, content: 'world'}];
93-
grid.addWidget({x:0, y:100, w:1, h:2, sizeToContent: true, subGridOpts: {children: subAddNested, id:`grid-${Math.random()}`, class: 'sub1', ...subOptions}});
87+
grid.addWidget({x:0, y:100, sizeToContent: true, subGridOpts: {
88+
children: [ {content: 'hello'}, {y:1, content: 'world'}],
89+
...subOptions}
90+
});
9491
}
9592

9693
function addNewWidget(selector) {
@@ -106,50 +103,24 @@ <h1>Nested grids demo</h1>
106103
return false;
107104
};
108105

109-
//--- Drag and Drop Nested widget logic
106+
// listener on drop event: every time the sidebar item is dropped create a new subgrid
107+
function droppedHandler(event, prevNode, n) {
108+
// if we don't have a prevNode that means it came from toolbar, which today is the only nested case (else check for some node.el.getAttribute or some custom field...)
109+
if (prevNode) return;
110110

111-
// the definition of the new node to add on drag and drop
112-
let nodeToAdd = {
113-
w: 2,
114-
h: 2,
115-
...subOptions,
116-
subGridOpts: subOptions,
117-
children: [
118-
{
119-
w: 1,
120-
h: 1,
121-
content: '1'
122-
},
123-
{
124-
w: 1,
125-
h: 1,
126-
content: '2'
127-
},
128-
],
129-
}
111+
// clear the content and make it a subgrid
112+
n.el.querySelector('.grid-stack-item-content').innerHTML = '';
130113

131-
// listener on add event: everytime a widget with data-gs-drop is dropped, a new subgrid is created
132-
function addEventHandler (event, gridNodes) {
133-
gridNodes.forEach((node) => {
134-
// check if the added event was triggered by a drop
135-
let isAddedByDrop = Boolean(node.el.getAttribute('data-gs-drop'));
136-
if (isAddedByDrop) {
137-
// clear the content of the node before applying the content of our widget to add
138-
node.el.querySelector('.grid-stack-item-content').innerHTML = '';
139-
// create a nested widget
140-
let subgrid = node.grid.makeSubGrid(node.el, nodeToAdd, undefined, false);
141-
// add a listener to the subgrid to allow widgets to be added into this newly created nested widget
142-
subgrid.on('added', addEventHandler);
143-
}
144-
// remove the data-gs-drop attribute to clean the node and avoid adding a new subgrid when a widget is moved between nested grids
145-
node.el.removeAttribute('data-gs-drop')
146-
});
114+
// let nodeToAdd = { subGridOpts: {children: [{content: 'nest 1'}, {content: 'nest 2'}], ...subOptions }} TODO that is correct info ?
115+
let nodeToAdd = { ...subOptions, subGridOpts: subOptions, children: [{content: 'nest 1'}, {content: 'nest 2'}]}
116+
let subgrid = n.grid.makeSubGrid(n.el, nodeToAdd, undefined, false);
117+
// add a listener to the subgrid to allow widgets to be added into this newly created nested widget
118+
subgrid.on('dropped', droppedHandler);
147119
}
148-
// add listener to the main grid
149-
grid.on('added', addEventHandler);
150-
// add listener to the already existing nested grids
120+
// add listener to the main grid and subgrids
121+
grid.on('dropped', droppedHandler);
151122
document.querySelectorAll('.grid-stack-nested').forEach((subGrid) => {
152-
subGrid.gridstack.on('added', addEventHandler);
123+
subGrid.gridstack.on('dropped', droppedHandler);
153124
});
154125

155126
//--- end of Drag and Drop Nested widget logic
@@ -161,7 +132,7 @@ <h1>Nested grids demo</h1>
161132
}
162133
function destroy(full = true) {
163134
if (full) {
164-
grid.off('added');
135+
grid.off('dropped');
165136
grid.destroy();
166137
grid = undefined;
167138
} else {
@@ -171,7 +142,7 @@ <h1>Nested grids demo</h1>
171142
function load(full = true) {
172143
if (full) {
173144
grid = GridStack.addGrid(document.querySelector('.container-fluid'), options);
174-
grid.on('added', addEventHandler);
145+
grid.on('dropped', droppedHandler);
175146
} else {
176147
grid.load(options);
177148
}

src/gridstack.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ export class GridStack {
512512
* @param el gridItem element to convert
513513
* @param ops (optional) sub-grid options, else default to node, then parent settings, else defaults
514514
* @param nodeToAdd (optional) node to add to the newly created sub grid (used when dragging over existing regular item)
515+
* @param saveContent if true (default) the html inside .grid-stack-content will be saved to child widget
515516
* @returns newly created grid
516517
*/
517518
public makeSubGrid(el: GridItemHTMLElement, ops?: GridStackOptions, nodeToAdd?: GridStackNode, saveContent = true): GridStack {

0 commit comments

Comments
 (0)