diff --git a/demo/angular/src/app/app.component.ts b/demo/angular/src/app/app.component.ts
index 3e62abdc5..75b4ca883 100644
--- a/demo/angular/src/app/app.component.ts
+++ b/demo/angular/src/app/app.component.ts
@@ -51,8 +51,8 @@ export class AppComponent implements OnInit {
private sub2: NgGridStackWidget[] = [ {x:0, y:0}, {x:0, y:1, w:2}];
private subChildren: NgGridStackWidget[] = [
{x:0, y:0, content: 'regular item'},
- {x:1, y:0, w:4, h:4, subGrid: {children: this.sub1, id:'sub1_grid', class: 'sub1', ...this.subOptions}},
- {x:5, y:0, w:3, h:4, subGrid: {children: this.sub2, id:'sub2_grid', class: 'sub2', ...this.subOptions}},
+ {x:1, y:0, w:4, h:4, subGridOpts: {children: this.sub1, id:'sub1_grid', class: 'sub1', ...this.subOptions}},
+ {x:5, y:0, w:3, h:4, subGridOpts: {children: this.sub2, id:'sub2_grid', class: 'sub2', ...this.subOptions}},
]
public nestedGridOptions: GridStackOptions = { // main grid options
cellHeight: 50,
@@ -68,7 +68,7 @@ export class AppComponent implements OnInit {
constructor() {
// give them content and unique id to make sure we track them during changes below...
[...this.items, ...this.subChildren, ...this.sub1, ...this.sub2].forEach((w: NgGridStackWidget) => {
- if (!w.type && !w.subGrid) w.content = `item ${ids}`;
+ if (!w.type && !w.subGridOpts) w.content = `item ${ids}`;
w.id = String(ids++);
});
}
@@ -141,9 +141,10 @@ export class AppComponent implements OnInit {
let grid = this.gridComp?.grid;
if (!grid) return;
let node = grid.engine.nodes[0];
- if (node?.subGrid) {
- grid = node.subGrid as GridStack;
- node = grid?.engine.nodes[0];
+ // delete any children first before subGrid itself...
+ if (node?.subGrid && node.subGrid.engine.nodes.length) {
+ grid = node.subGrid;
+ node = grid.engine.nodes[0];
}
if (node) grid.removeWidget(node.el!);
}
diff --git a/demo/angular/src/app/gridstack.component.ts b/demo/angular/src/app/gridstack.component.ts
index 3869c4700..8d33a3ee8 100644
--- a/demo/angular/src/app/gridstack.component.ts
+++ b/demo/angular/src/app/gridstack.component.ts
@@ -216,7 +216,7 @@ export function gsCreateNgComponents(host: GridCompHTMLElement | HTMLElement, w:
// IFF we're not a subGrid, define what type of component to create as child, OR you can do it GridstackItemComponent template, but this is more generic
const type = (w as NgGridStackWidget).type;
- if (!w.subGrid && type && GridstackComponent.selectorToType[type]) {
+ if (!w.subGridOpts && type && GridstackComponent.selectorToType[type]) {
gridItem?.container?.createComponent(GridstackComponent.selectorToType[type]);
}
diff --git a/demo/nested.html b/demo/nested.html
index 2d05e8952..ef9f63d3a 100644
--- a/demo/nested.html
+++ b/demo/nested.html
@@ -51,8 +51,8 @@
Nested grids demo
id: 'main',
children: [
{x:0, y:0, content: 'regular item'},
- {x:1, y:0, w:4, h:4, subGrid: {children: sub1, id:'sub1_grid', class: 'sub1', ...subOptions}},
- {x:5, y:0, w:3, h:4, subGrid: {children: sub2, id:'sub2_grid', class: 'sub2', ...subOptions}},
+ {x:1, y:0, w:4, h:4, subGridOpts: {children: sub1, id:'sub1_grid', class: 'sub1', ...subOptions}},
+ {x:5, y:0, w:3, h:4, subGridOpts: {children: sub2, id:'sub2_grid', class: 'sub2', ...subOptions}},
]
};
diff --git a/demo/nested_advanced.html b/demo/nested_advanced.html
index e34e3150f..4c6a44688 100644
--- a/demo/nested_advanced.html
+++ b/demo/nested_advanced.html
@@ -45,19 +45,19 @@ Advanced Nested grids demo
let main = [{x:0, y:0}, {x:0, y:1}, {x:1, y:0}]
let sub1 = [{x:0, y:0}];
let sub0 = [{x:0, y:0}, {x:1, y:0}];
- // let sub0 = [{x:0, y:0}, {x:1, y:0}, {x:1, y:1, h:2, subGrid: {children: sub1, ...subOptions}}];
+ // let sub0 = [{x:0, y:0}, {x:1, y:0}, {x:1, y:1, h:2, subGridOpts: {children: sub1, ...subOptions}}];
let options = { // main grid options
cellHeight: 50,
margin: 5,
minRow: 2, // don't collapse when empty
acceptWidgets: true,
- subGrid: subOptions,
+ subGridOpts: subOptions,
subGridDynamic: true, // v7 api to create sub-grids on the fly
children: [
...main,
- {x:2, y:0, w:2, h:3, id: 'sub0', subGrid: {children: sub0, ...subOptions}},
- {x:4, y:0, h:2, id: 'sub1', subGrid: {children: sub1, ...subOptions}},
- // {x:2, y:0, w:2, h:3, subGrid: {children: [...sub1, {x:0, y:1, subGrid: subOptions}], ...subOptions}/*,content: "nested grid here
"*/},
+ {x:2, y:0, w:2, h:3, id: 'sub0', subGridOpts: {children: sub0, ...subOptions}},
+ {x:4, y:0, h:2, id: 'sub1', subGridOpts: {children: sub1, ...subOptions}},
+ // {x:2, y:0, w:2, h:3, subGridOpts: {children: [...sub1, {x:0, y:1, subGridOpts: subOptions}], ...subOptions}/*,content: "nested grid here
"*/},
]
};
let count = 0;
diff --git a/demo/nested_constraint.html b/demo/nested_constraint.html
index 5d6c62604..615ba5e73 100644
--- a/demo/nested_constraint.html
+++ b/demo/nested_constraint.html
@@ -55,8 +55,8 @@ Constraint Nested grids demo
id: 'main',
children: [
{y:0, content: 'regular item'},
- {x:1, w:4, h:4, subGrid: {children: sub1, class: 'sub1', ...subOptions}},
- {x:5, w:4, h:4, subGrid: {children: sub2, class: 'sub2', ...subOptions}},
+ {x:1, w:4, h:4, subGridOpts: {children: sub1, class: 'sub1', ...subOptions}},
+ {x:5, w:4, h:4, subGridOpts: {children: sub2, class: 'sub2', ...subOptions}},
]
};
diff --git a/demo/old_nested-jq.html b/demo/old_nested-jq.html
index dd7449b3e..4f320ab09 100644
--- a/demo/old_nested-jq.html
+++ b/demo/old_nested-jq.html
@@ -76,8 +76,8 @@ Nested JQuery grids demo
id: 'main',
children: [
{x:0, y:0, content: 'regular item'},
- {x:1, w:4, h:4, subGrid: {children: sub1, dragOut: true, class: 'sub1', ...subOptions}},
- {x:5, w:3, h:4, subGrid: {children: sub2, dragOut: false, class: 'sub2', ...subOptions}},
+ {x:1, w:4, h:4, subGridOpts: {children: sub1, dragOut: true, class: 'sub1', ...subOptions}},
+ {x:5, w:3, h:4, subGridOpts: {children: sub2, dragOut: false, class: 'sub2', ...subOptions}},
]
};
diff --git a/doc/CHANGES.md b/doc/CHANGES.md
index f8be404db..14c068ca8 100644
--- a/doc/CHANGES.md
+++ b/doc/CHANGES.md
@@ -91,6 +91,7 @@ Change log
* add: `GridStack.saveCB` global callback for each item during save so app can insert any custom data before serializing it. `save()` can now be passed optional callback
* move: `GridStack.addRemoveCB` is now global instead of grid option. `load()` can still be passed different optional callback
* fix: addGrid() to handle passing an existing initialized grid already
+* break: `GridStackOptions.subGrid` -> `GridStackOptions.subGridOpts`. We now have `GridStackWidget.subGridOpts` vs `GridStackNode.subGrid` (subclass) rather than try to merge the two at runtime since very different types...
## 7.3.0 (2023-04-01)
* feat [#2229](https://github.com/gridstack/gridstack.js/pull/2229) support nonce for CSP. Thank you [@jedwards1211](https://github.com/jedwards1211)
diff --git a/src/gridstack.ts b/src/gridstack.ts
index 1f894ed12..aba695461 100644
--- a/src/gridstack.ts
+++ b/src/gridstack.ts
@@ -469,8 +469,8 @@ export class GridStack {
this._updateContainerHeight();
// see if there is a sub-grid to create
- if (node.subGrid) {
- this.makeSubGrid(node.el, undefined, undefined, false); //node.subGrid will be used as option in method, no need to pass
+ if (node.subGridOpts) {
+ this.makeSubGrid(node.el, node.subGridOpts, undefined, false); // node.subGrid will be used as option in method, no need to pass
}
// if we're adding an item into 1 column (_prevColumn is set only when going to 1) make sure
@@ -498,18 +498,18 @@ export class GridStack {
if (!node) {
node = this.makeWidget(el).gridstackNode;
}
- if ((node.subGrid as GridStack)?.el) return node.subGrid as GridStack; // already done
+ if (node.subGrid?.el) return node.subGrid; // already done
// find the template subGrid stored on a parent as fallback...
let subGridTemplate: GridStackOptions; // eslint-disable-next-line @typescript-eslint/no-this-alias
let grid: GridStack = this;
while (grid && !subGridTemplate) {
- subGridTemplate = grid.opts?.subGrid;
+ subGridTemplate = grid.opts?.subGridOpts;
grid = grid.parentGridItem?.grid;
}
//... and set the create options
- ops = Utils.cloneDeep({...(subGridTemplate || {}), children: undefined, ...(ops || node.subGrid as GridStackOptions)});
- node.subGrid = ops;
+ ops = Utils.cloneDeep({...(subGridTemplate || {}), children: undefined, ...(ops || node.subGridOpts)});
+ node.subGridOpts = ops;
// if column special case it set, remember that flag and set default
let autoColumn: boolean;
@@ -527,7 +527,7 @@ export class GridStack {
this._removeDD(node.el); // remove D&D since it's set on content div
newItemOpt = {...node, x:0, y:0};
Utils.removeInternalForSave(newItemOpt);
- delete newItemOpt.subGrid;
+ delete newItemOpt.subGridOpts;
if (node.content) {
newItemOpt.content = node.content;
delete node.content;
@@ -625,9 +625,10 @@ export class GridStack {
} else {
if (!saveContent && !saveCB) { delete n.content; }
// check for nested grid
- if ((n.subGrid as GridStack)?.el) {
- const listOrOpt = (n.subGrid as GridStack).save(saveContent, saveGridOpt, saveCB);
- n.subGrid = (saveGridOpt ? listOrOpt : {children: listOrOpt}) as GridStackOptions;
+ if (n.subGrid?.el) {
+ const listOrOpt = n.subGrid.save(saveContent, saveGridOpt, saveCB);
+ n.subGridOpts = (saveGridOpt ? listOrOpt : {children: listOrOpt}) as GridStackOptions;
+ delete n.subGrid;
}
}
delete n.el;
@@ -711,10 +712,10 @@ export class GridStack {
let item = (w.id || w.id === 0) ? this.engine.nodes.find(n => n.id === w.id) : undefined;
if (item) {
this.update(item.el, w);
- if (w.subGrid && (w.subGrid as GridStackOptions).children) { // update any sub grid as well
+ if (w.subGridOpts?.children) { // update any sub grid as well
let sub = item.el.querySelector('.grid-stack') as GridHTMLElement;
if (sub && sub.gridstack) {
- sub.gridstack.load((w.subGrid as GridStackOptions).children); // TODO: support updating grid options ?
+ sub.gridstack.load(w.subGridOpts.children); // TODO: support updating grid options ?
this._insertNotAppend = true; // got reset by above call
}
}
@@ -1138,7 +1139,7 @@ export class GridStack {
this._setupAcceptWidget();
this.engine.nodes.forEach(n => {
this._prepareDragDropByNode(n); // either delete or init Drag&drop
- if (n.subGrid && recurse) (n.subGrid as GridStack).setStatic(val, updateClass, recurse);
+ if (n.subGrid && recurse) n.subGrid.setStatic(val, updateClass, recurse);
});
if (updateClass) { this._setStaticClass(); }
return this;
@@ -1553,7 +1554,7 @@ export class GridStack {
// finally update any nested grids
this.engine.nodes.forEach(n => {
- if (n.subGrid) {(n.subGrid as GridStack).onParentResize()}
+ if (n.subGrid) n.subGrid.onParentResize()
});
return this;
@@ -1757,7 +1758,7 @@ export class GridStack {
this.opts.disableDrag = !doEnable; // FIRST before we update children as grid overrides #1658
this.engine.nodes.forEach(n => {
this.movable(n.el, doEnable);
- if (n.subGrid && recurse) (n.subGrid as GridStack).enableMove(doEnable, recurse);
+ if (n.subGrid && recurse) n.subGrid.enableMove(doEnable, recurse);
});
return this;
}
@@ -1771,7 +1772,7 @@ export class GridStack {
this.opts.disableResize = !doEnable; // FIRST before we update children as grid overrides #1658
this.engine.nodes.forEach(n => {
this.resizable(n.el, doEnable);
- if (n.subGrid && recurse) (n.subGrid as GridStack).enableResize(doEnable, recurse);
+ if (n.subGrid && recurse) n.subGrid.enableResize(doEnable, recurse);
});
return this;
}
@@ -1987,7 +1988,7 @@ export class GridStack {
if (!wasAdded) return false;
el.gridstackNode = node;
node.el = el;
- let subGrid = (node.subGrid as GridStack)?.el?.gridstack; // set when actual sub-grid present
+ let subGrid = node.subGrid?.el?.gridstack; // set when actual sub-grid present
// @ts-ignore
Utils.copyPos(node, this._readAttr(this.placeholder)); // placeholder values as moving VERY fast can throw things off #1578
Utils.removePositioningStyles(el);// @ts-ignore
@@ -2263,7 +2264,7 @@ export class GridStack {
node._lastUiPosition = ui.position;
this.engine.cacheRects(cellWidth, cellHeight, mTop, mRight, mBottom, mLeft);
delete node._skipDown;
- if (resizing && node.subGrid) { (node.subGrid as GridStack).onParentResize(); }// @ts-ignore
+ if (resizing && node.subGrid) node.subGrid.onParentResize();
this._extraDragRow = 0;// @ts-ignore
this._updateContainerHeight();
diff --git a/src/types.ts b/src/types.ts
index fbea2ea52..1f1d063c1 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -252,8 +252,8 @@ export interface GridStackOptions {
/** if `true` will add style element to `` otherwise will add it to element's parent node (default `false`). */
styleInHead?: boolean;
- /** list of differences in options for automatically created sub-grids under us */
- subGrid?: GridStackOptions;
+ /** list of differences in options for automatically created sub-grids under us (inside our grid-items) */
+ subGridOpts?: GridStackOptions;
/** enable/disable the creation of sub-grids on the fly by dragging items completely
* over others (nest) vs partially (push). Forces `DDDragOpt.pause=true` to accomplish that. */
@@ -318,8 +318,8 @@ export interface GridStackWidget extends GridStackPosition {
id?: numberOrString;
/** html to append inside as content */
content?: string;
- /** optional nested grid options and list of children, which then turns into actual instance at runtime */
- subGrid?: GridStackOptions | GridStack;
+ /** optional nested grid options and list of children, which then turns into actual instance at runtime to get options from */
+ subGridOpts?: GridStackOptions;
}
/** Drag&Drop resize options */
@@ -390,8 +390,10 @@ export interface DDUIData {
export interface GridStackNode extends GridStackWidget {
/** pointer back to HTML element */
el?: GridItemHTMLElement;
- /** pointer back to Grid instance */
+ /** pointer back to parent Grid instance */
grid?: GridStack;
+ /** actual sub-grid instance */
+ subGrid?: GridStack;
/** @internal internal id used to match when cloning engines or saving column layouts */
_id?: number;
/** @internal */