Skip to content
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
13 changes: 7 additions & 6 deletions demo/angular/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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++);
});
}
Expand Down Expand Up @@ -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!);
}
Expand Down
2 changes: 1 addition & 1 deletion demo/angular/src/app/gridstack.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
}

Expand Down
4 changes: 2 additions & 2 deletions demo/nested.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ <h1>Nested grids demo</h1>
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}},
]
};

Expand Down
10 changes: 5 additions & 5 deletions demo/nested_advanced.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,19 @@ <h1>Advanced Nested grids demo</h1>
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: "<div>nested grid here</div>"*/},
{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: "<div>nested grid here</div>"*/},
]
};
let count = 0;
Expand Down
4 changes: 2 additions & 2 deletions demo/nested_constraint.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ <h1>Constraint Nested grids demo</h1>
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}},
]
};

Expand Down
4 changes: 2 additions & 2 deletions demo/old_nested-jq.html
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ <h1>Nested JQuery grids demo</h1>
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}},
]
};

Expand Down
1 change: 1 addition & 0 deletions doc/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
37 changes: 19 additions & 18 deletions src/gridstack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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();

Expand Down
12 changes: 7 additions & 5 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,8 @@ export interface GridStackOptions {
/** if `true` will add style element to `<head>` 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. */
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down