* 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 removed. * @param saveGridOpt if
(saveContent = true, saveGridOpt = false, saveCB = GridStack.saveCB, column?: number)
| 632 | * @returns list of widgets or full grid option, including .children list of widgets |
| 633 | */ |
| 634 | public save(saveContent = true, saveGridOpt = false, saveCB = GridStack.saveCB, column?: number): GridStackWidget[] | GridStackOptions { |
| 635 | // return copied GridStackWidget (with optionally .el) we can modify at will... |
| 636 | const list = this.engine.save(saveContent, saveCB, column); |
| 637 | |
| 638 | // check for HTML content and nested grids |
| 639 | list.forEach(n => { |
| 640 | if (saveContent && n.el && !n.subGrid && !saveCB) { // sub-grid are saved differently, not plain content |
| 641 | const itemContent = n.el.querySelector('.grid-stack-item-content'); |
| 642 | n.content = itemContent?.innerHTML; |
| 643 | if (!n.content) delete n.content; |
| 644 | } else { |
| 645 | if (!saveContent && !saveCB) { delete n.content; } |
| 646 | // check for nested grid - make sure it saves to the given container size to be consistent |
| 647 | if (n.subGrid?.el) { |
| 648 | const column = n.w || n.subGrid.getColumn(); |
| 649 | const listOrOpt = n.subGrid.save(saveContent, saveGridOpt, saveCB, column); |
| 650 | n.subGridOpts = (saveGridOpt ? listOrOpt : { children: listOrOpt }) as GridStackOptions; |
| 651 | delete n.subGrid; |
| 652 | } |
| 653 | } |
| 654 | delete n.el; |
| 655 | }); |
| 656 | |
| 657 | // check if save entire grid options (needed for recursive) + children... |
| 658 | if (saveGridOpt) { |
| 659 | const o: InternalGridStackOptions = Utils.cloneDeep(this.opts); |
| 660 | // delete default values that will be recreated on launch |
| 661 | if (o.marginBottom === o.marginTop && o.marginRight === o.marginLeft && o.marginTop === o.marginRight) { |
| 662 | o.margin = o.marginTop; |
| 663 | delete o.marginTop; delete o.marginRight; delete o.marginBottom; delete o.marginLeft; |
| 664 | } |
| 665 | if (o.rtl === (this.el.style.direction === 'rtl')) { o.rtl = 'auto' } |
| 666 | if (this._isAutoCellHeight) { |
| 667 | o.cellHeight = 'auto' |
| 668 | } |
| 669 | if (this._autoColumn) { |
| 670 | o.column = 'auto'; |
| 671 | } |
| 672 | const origShow = o._alwaysShowResizeHandle; |
| 673 | delete o._alwaysShowResizeHandle; |
| 674 | if (origShow !== undefined) { |
| 675 | o.alwaysShowResizeHandle = origShow; |
| 676 | } else { |
| 677 | delete o.alwaysShowResizeHandle; |
| 678 | } |
| 679 | Utils.removeInternalAndSame(o, gridDefaults); |
| 680 | o.children = list; |
| 681 | return o; |
| 682 | } |
| 683 | |
| 684 | return list; |
| 685 | } |
| 686 | |
| 687 | /** |
| 688 | * Load widgets from a list. This will call update() on each (matching by id) or add/remove widgets that are not there. |
no test coverage detected