forked from gridstack/gridstack.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnested.html
152 lines (141 loc) · 6.09 KB
/
nested.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<!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>Nested grids demo</title>
<link rel="stylesheet" href="demo.css"/>
<link rel="stylesheet" href="../dist/gridstack-extra.min.css"/>
<script src="../dist/gridstack-all.js"></script>
</head>
<body>
<div class="container-fluid">
<h1>Nested grids demo</h1>
<p>This example shows v5.x dragging between nested grids (dark yellow) and parent grid (bright yellow.)<br>
Use v9.2 <b>sizeToContent:true</b> on first subgrid item parent to grow/shrink as needed, while leaving leaf green items unchanged.<br>
Uses v3.1 API to load the entire nested grid from JSON.<br>
Nested grids uses v5 <b>column:'auto'</b> to keep items same size during resize.</p>
<div class="actions" style="display: flex; flex-direction: row; gap: 5px;">
<a class="btn btn-primary" onClick="addWidget()" href="#">Add Widget</a>
<a class="btn btn-primary" onClick="addNewWidget('.sub1')" href="#">Add Widget Grid1</a>
<a class="btn btn-primary" onClick="addNewWidget('.sub2')" href="#">Add Widget Grid2</a>
<a class="btn btn-primary" onClick="addNested()" href="#">Add Nested Grid</a>
<div class="sidebar" style="height:50px; padding: 0">
<!-- manually force a drop size of 2x2 for nested size -->
<div class="grid-stack-item" gs-w="2" gs-h="2">
<div class="grid-stack-item-content">Drag nested</div>
</div>
</div>
</div>
<br />
<span>entire save/re-create:</span>
<a class="btn btn-primary" onClick="save()" href="#">Save</a>
<a class="btn btn-primary" onClick="destroy()" href="#">Destroy</a>
<a class="btn btn-primary" onClick="load()" href="#">Create</a>
<span>partial save/load:</span>
<a class="btn btn-primary" onClick="save(true, false)" href="#">Save list</a>
<a class="btn btn-primary" onClick="save(false, false)" href="#">Save no content</a>
<a class="btn btn-primary" onClick="destroy(false)" href="#">Clear</a>
<a class="btn btn-primary" onClick="load(false)" href="#">Load</a>
<br><br>
<!-- grid will be added here -->
</div>
<script src="events.js"></script>
<script type="text/javascript">
let sub1 = [ {x:0, y:0}, {x:1, y:0}, {x:2, y:0}, {x:3, y:0}, {x:0, y:1}, {x:1, y:1}];
let sub2 = [ {x:0, y:0, h:2}, {x:1, y:1, w:2}];
let count = 0;
[...sub1, ...sub2].forEach(d => d.content = String(count++));
let subOptions = {
cellHeight: 50, // should be 50 - top/bottom
column: 'auto', // size to match container. make sure to include gridstack-extra.min.css
acceptWidgets: true, // will accept .grid-stack-item by default
margin: 5,
};
let options = { // main grid options
cellHeight: 50,
margin: 5,
minRow: 2, // don't collapse when empty
acceptWidgets: true,
id: 'main',
subGridOpts: subOptions, // all sub grids will default to those
children: [
{x:0, y:0, content: 'regular item'},
{x:1, y:0, w:4, h:4, sizeToContent: true, subGridOpts: {children: sub1, id:'sub1_grid', class: 'sub1'}},
{x:5, y:0, w:3, h:4, subGridOpts: {children: sub2, id:'sub2_grid', class: 'sub2'}},
]
};
// create and load it all from JSON above
let grid = GridStack.addGrid(document.querySelector('.container-fluid'), options);
// add debug event handlers to each grid (no global set on parent yet)
let gridEls = GridStack.getElements('.grid-stack');
gridEls.forEach(gridEl => {
let grid = gridEl.gridstack;
addEvents(grid, grid.opts.id);
})
// setup drag drop behavior
GridStack.setupDragIn('.sidebar .grid-stack-item', { appendTo: 'body', helper: 'clone' });
function addWidget() {
grid.addWidget({x:0, y:100, content:"new item"});
}
function addNested() {
grid.addWidget({x:0, y:100, sizeToContent: true, subGridOpts: {
children: [ {content: 'hello'}, {y:1, content: 'world'}],
...subOptions}
});
}
function addNewWidget(selector) {
let subGrid = document.querySelector(selector).gridstack;
let node = {
x: Math.round(6 * Math.random()),
y: Math.round(5 * Math.random()),
w: Math.round(1 + 1 * Math.random()),
h: Math.round(1 + 1 * Math.random()),
content: String(count++)
};
subGrid.addWidget(node);
return false;
};
// listener on drop event: every time the sidebar item is dropped create a new subgrid
function droppedHandler(event, prevNode, n) {
// 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...)
if (prevNode) return;
// clear the content then make it a subgrid
n.el.querySelector('.grid-stack-item-content').innerHTML = '';
let nodeToAdd = { children: [{content: 'nest 1'}, {content: 'nest 2'}]};
let subgrid = n.grid.makeSubGrid(n.el, nodeToAdd, undefined, false);
// add a listener to the subgrid to allow widgets to be added into this newly created nested widget
subgrid.on('dropped', droppedHandler);
}
// add listener to the main grid and subgrids
grid.on('dropped', droppedHandler);
document.querySelectorAll('.grid-stack-nested').forEach((subGrid) => {
subGrid.gridstack.on('dropped', droppedHandler);
});
//--- end of Drag and Drop Nested widget logic
function save(content = true, full = true) {
options = grid.save(content, full);
console.log(options);
// console.log(JSON.stringify(options));
}
function destroy(full = true) {
if (full) {
grid.off('dropped');
grid.destroy();
grid = undefined;
} else {
grid.removeAll();
}
}
function load(full = true) {
if (full) {
grid = GridStack.addGrid(document.querySelector('.container-fluid'), options);
grid.on('dropped', droppedHandler);
} else {
grid.load(options);
}
}
</script>
</body>
</html>