Thanks to visit codestin.com
Credit goes to github.com

Skip to content

save(false, false) fixes #1808

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 11, 2021
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
6 changes: 6 additions & 0 deletions demo/float.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ <h1>Float grid demo</h1>
document.querySelector('#float').innerHTML = 'float: ' + grid.getFloat();
};
addNewWidget();
addNewWidget();

grid.enable();
grid.save(false, true); // causes error at the end
grid.disable();
grid.enable();
</script>
</body>
</html>
36 changes: 25 additions & 11 deletions demo/nested.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,19 @@
<div class="container-fluid">
<h1>Nested grids demo</h1>
<p>This example uses new v3.1 API to load the entire nested grid from JSON, and shows dragging between nested grid items (pink) vs dragging higher grid items (green)</p>
<p>Note: initial v3 HTML5 release doesn't support 'dragOut:false' constrain so use jq version if you need that.</p>
<p>Note: HTML5 release doesn't yet support 'dragOut:false' constrain so use JQ version if you need that.</p>
<a class="btn btn-primary" onClick="addNested()" href="#">Add Widget</a>
<a class="btn btn-primary" onClick="addNewWidget('.nested1')" href="#">Add Widget Grid1</a>
<a class="btn btn-primary" onClick="addNewWidget('.nested2')" href="#">Add Widget Grid2</a>
<span>entire save/re-create:</span>
<a class="btn btn-primary" onClick="save()" href="#">Save</a>
<a class="btn btn-primary" onClick="destroy()" href="#">Clear</a>
<a class="btn btn-primary" onClick="load()" href="#">Load</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>
Expand All @@ -45,7 +51,7 @@ <h1>Nested grids demo</h1>
minWidth: 300, // min to go 1 column mode
margin: 1
};
let json = {cellHeight: 70, children: [
let json = {cellHeight: 70, minRow: 2, children: [
{y:0, content: 'regular item'},
{x:1, w:4, h:4, content: 'nested 1 - can drag items out', subGrid: {children: sub1, dragOut: true, class: 'nested1', ...subOptions}},
{x:5, w:4, h:4, content: 'nested 2 - constrained to parent (default)', subGrid: {children: sub2, class: 'nested2', ...subOptions}},
Expand All @@ -71,17 +77,25 @@ <h1>Nested grids demo</h1>
return false;
};

save = function() {
json = grid.save(false, true);
save = function(content = true, full = true) {
json = grid.save(content, full);
console.log(json);
// console.log(JSON.stringify(json));
}
destroy = function() {
grid.destroy();
grid = undefined;
destroy = function(full = true) {
if (full) {
grid.destroy();
grid = undefined;
} else {
grid.removeAll();
}
}
load = function() {
grid = GridStack.addGrid(document.querySelector('.container-fluid'), json);
load = function(full = true) {
if (full) {
grid = GridStack.addGrid(document.querySelector('.container-fluid'), json);
} else {
grid.load(json);
}
}

</script>
Expand Down
2 changes: 1 addition & 1 deletion demo/serialization.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ <h1>Serialization demo</h1>
</div>

<script type="text/javascript">
let grid = GridStack.init({minRow: 1}); // don't let it collapse when empty
let grid = GridStack.init({minRow: 1, cellHeight: 70}); // don't let it collapse when empty

grid.on('added removed change', function(e, items) {
let str = '';
Expand Down
3 changes: 2 additions & 1 deletion doc/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ Change log

* fix [#1784](https://github.com/gridstack/gridstack.js/issues/1784) `removable:true` working by itself (without needing `acceptWidgets:true`)
* fix [#1791](https://github.com/gridstack/gridstack.js/pull/1791) removed drag flicker and scroll issue. Thanks [@nelsieborja](https://github.com/nelsieborja)
* better doc for save [#1795](https://github.com/gridstack/gridstack.js/issues/1795)
* fix [#1795](https://github.com/gridstack/gridstack.js/issues/1795) `save(false)` will no longer have `.content` field (removed existing one if present)
* fix [#1782](https://github.com/gridstack/gridstack.js/issues/1782) `save(false, false)` now correctly saves nested grids

## 4.2.5 (2021-5-31)

Expand Down
2 changes: 1 addition & 1 deletion doc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ Enables/Disables user resizing of specific grid element. If you want all items,
### `save(saveContent = true, saveGridOpt = false): GridStackWidget[] | GridStackOptions`

saves the current layout returning a list of widgets for serialization which might include any nested grids.
- `saveContent` if true (default) the latest html inside `.grid-stack-content` will be saved to `GridStackWidget.content` field, else it will be left unchanged for initial load values.
- `saveContent` if true (default) the latest html inside `.grid-stack-content` will be saved to `GridStackWidget.content` field, else it will be removed.
- `saveGridOpt` if true (default `false`), save the grid options itself, so you can call the new `GridStack.addGrid()` to recreate everything from scratch. GridStackOptions.children would then contain the widget list instead.
- returns list of widgets or full grid option, including .children list of widgets
- see [serialization](http://gridstackjs.com/demo/serialization.html) and [nested](http://gridstackjs.com/demo/nested.html)
Expand Down
9 changes: 8 additions & 1 deletion spec/gridstack-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1744,14 +1744,21 @@ describe('gridstack', function() {
document.body.removeChild(document.getElementById('gs-cont'));
});
it('save layout', function() {
let grid = GridStack.init();
let grid = GridStack.init({maxRow: 10});
let layout = grid.save(false);
expect(layout).toEqual([{x:0, y:0, w:4, h:2, id:'gsItem1'}, {x:4, y:0, w:4, h:4, id:'gsItem2'}]);
layout = grid.save();
expect(layout).toEqual([{x:0, y:0, w:4, h:2, id:'gsItem1', content:'item 1 text'}, {x:4, y:0, w:4, h:4, id:'gsItem2', content:'item 2 text'}]);
layout = grid.save(true);
expect(layout).toEqual([{x:0, y:0, w:4, h:2, id:'gsItem1', content:'item 1 text'}, {x:4, y:0, w:4, h:4, id:'gsItem2', content:'item 2 text'}]);
});
it('save layout full', function() {
let grid = GridStack.init({maxRow: 10, _foo: 'bar'} as any); // using bogus 'internal' field (stripped)
let layout = grid.save(false, true);
expect(layout).toEqual({maxRow: 10, children: [{x:0, y:0, w:4, h:2, id:'gsItem1'}, {x:4, y:0, w:4, h:4, id:'gsItem2'}]});
layout = grid.save(true, true);
expect(layout).toEqual({maxRow: 10, children: [{x:0, y:0, w:4, h:2, id:'gsItem1', content:'item 1 text'}, {x:4, y:0, w:4, h:4, id:'gsItem2', content:'item 2 text'}]});
});
it('load move 1 item, delete others', function() {
let grid = GridStack.init();
grid.load([{x:2, h:1, id:'gsItem2'}]);
Expand Down
34 changes: 15 additions & 19 deletions src/gridstack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ export class GridStack {
/**
* saves the current layout returning a list of widgets for serialization which might include any nested grids.
* @param saveContent if true (default) the latest html inside .grid-stack-content will be saved to GridStackWidget.content field, else it will
* be left unchanged for initial load values.
* be removed.
* @param saveGridOpt if true (default false), save the grid options itself, so you can call the new GridStack.addGrid()
* to recreate everything from scratch. GridStackOptions.children would then contain the widget list instead.
* @returns list of widgets or full grid option, including .children list of widgets
Expand All @@ -452,28 +452,24 @@ export class GridStack {
// return copied nodes we can modify at will...
let list = this.engine.save(saveContent);

// check for HTML content as well
if (saveContent) {
list.forEach(n => {
if (n.el && !n.subGrid) { // sub-grid are saved differently, not plain content
let sub = n.el.querySelector('.grid-stack-item-content');
n.content = sub ? sub.innerHTML : undefined;
if (!n.content) delete n.content;
delete n.el;
// check for HTML content and nested grids
list.forEach(n => {
if (saveContent && n.el && !n.subGrid) { // sub-grid are saved differently, not plain content
let sub = n.el.querySelector('.grid-stack-item-content');
n.content = sub ? sub.innerHTML : undefined;
if (!n.content) delete n.content;
} else {
if (!saveContent) { delete n.content; }
// check for nested grid
if (n.subGrid) {
n.subGrid = (n.subGrid as GridStack).save(saveContent, true) as GridStackOptions;
}
});
}
}
delete n.el;
});

// check if save entire grid options (needed for recursive) + children...
if (saveGridOpt) {

// check for nested grid
list.forEach(n => {
if (n.subGrid) {
n.subGrid = (n.subGrid as GridStack).save(saveContent, saveGridOpt) as GridStackOptions;
}
})

let o: GridStackOptions = {...this.opts};
// delete default values that will be recreated on launch
if (o.marginBottom === o.marginTop && o.marginRight === o.marginLeft && o.marginTop === o.marginRight) {
Expand Down
6 changes: 4 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,12 +243,14 @@ export class Utils {
if (typeof a !== 'object' || typeof b !== 'object') return;
for (let key in a) {
let val = a[key];
if (val && typeof val === 'object' && b[key] !== undefined) {
if (key[0] === '_' || val === b[key]) {
delete a[key]
} else if (val && typeof val === 'object' && b[key] !== undefined) {
for (let i in val) {
if (val[i] === b[key][i] || i[0] === '_') { delete val[i] }
}
if (!Object.keys(val).length) { delete a[key] }
} else if (val === b[key] || key[0] === '_') { delete a[key] }
}
}
}

Expand Down