-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
nested.html
145 lines (135 loc) · 5.65 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
<!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>
<!-- add .grid-stack-item for acceptWidgets:true -->
<div class="sidebar-item grid-stack-item">Drag nested</div>
</div>
<br />
<div>
<span>Grid Mode: </span>
<input type="radio" id="static" name="mode" value="true" onClick="setStatic(true)"><label for="static">static</label>
<input type="radio" id="edit" name="mode" value="false" checked onClick="setStatic(false)"><label for="edit">editable</label>
</div>
<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>d
<script src="events.js"></script>
<script type="text/javascript">
// NOTE: REAL apps would sanitize-html or DOMPurify before blinding setting innerHTML. see #2736
GridStack.renderCB = function(el, w) {
if (w.content) el.innerHTML = w.content;
};
let staticGrid = false;
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 options = { // main grid options
staticGrid, // test - force children to inherit too if we set to true above ^^^
// disableDrag: true,
// disableResize: true,
cellHeight: 50,
margin: 5,
minRow: 2, // don't collapse when empty
acceptWidgets: true,
id: 'main',
resizable: { handles: 'se,e,s,sw,w'},
// subGridOpts, // options for all subgrids, but defaults to column='auto' now so no need.
children: [
{x:0, y:0, content: 'regular item'},
{x:1, y:0, w:4, h:4, sizeToContent: true, content: '<div>nested grid sizeToContent:true with some header content</div>', 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
let sidebarContent = [
{ w:2, h:2, subGridOpts: { children: [{content: 'nest 1'}, {content: 'nest 2'}]}}
];
GridStack.setupDragIn('.sidebar-item', undefined, sidebarContent);
function setStatic(val) {
staticGrid = val;
grid.setStatic(staticGrid);
}
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;
};
//--- 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);
} else {
grid.load(options);
}
}
</script>
</body>
</html>