Override this method to return serializable data for this widget.
+
Return an object with properties that map to your component's @Input() fields.
+The selector is handled automatically, so only include component-specific data.
Override this method to handle widget restoration from saved data.
+
Use this for complex initialization that goes beyond simple @Input() mapping.
+The default implementation automatically assigns input data to component properties.
Extract the selector string from an Angular component type.
+
Parameters
type: Type<Object>
The component type to get selector from
+
Returns string
The component's selector string
+
ngOnInit
ngOnInit():void
A callback method that is invoked immediately after the
+default change detector has checked the directive's
+data-bound properties for the first time,
+and before any of the view or content children have been checked.
+It is invoked only once when the directive is instantiated.
+
Returns void
ngAfterContentInit
ngAfterContentInit():void
wait until after all DOM is ready to init gridstack children (after angular ngFor and sub-components run first)
+
Returns void
ngOnDestroy
ngOnDestroy():void
A callback method that performs custom clean-up, invoked immediately
+before a directive, pipe, or service instance is destroyed.
+
Returns void
updateAll
updateAll():void
called when the TEMPLATE (not recommended) list of items changes - get a list of nodes and
+update the layout accordingly (which will take care of adding/removing items changed by Angular)
+
Returns void
checkEmpty
checkEmpty():void
check if the grid is empty, if so show alternative content
+
Returns void
ProtectedhookEvents
hookEvents(grid?:GridStack):void
get all known events as easy to use Outputs for convenience
List of template-based grid items (not recommended approach).
+Used to sync between DOM and GridStack internals when items are defined in templates.
+Prefer dynamic component creation instead.
+
Optionalcontainer
container?:ViewContainerRef
Container for dynamic component creation (recommended approach).
+Used to append grid items programmatically at runtime.
+
OptionalisEmpty
isEmpty?:boolean
Controls whether empty content should be displayed.
+Set to true to show ng-content with 'empty-content' selector when grid has no items.
+
Example
<gridstack[isEmpty]="gridItems.length === 0"> <divempty-content>Drag widgets here to get started</div> </gridstack>
+
Use GridstackComponent and GridstackItemComponent as standalone components instead.
+
This NgModule is provided for backward compatibility but is no longer the recommended approach.
+Import components directly in your standalone components or use the new Angular module structure.
gsCreateNgComponents( Â Â Â Â host:HTMLElement|GridCompHTMLElement, Â Â Â Â n:NgGridStackNode, Â Â Â Â add:boolean, Â Â Â Â isGrid:boolean, ):undefined|HTMLElement
can be used when a new item needs to be created, which we do as a Angular component, or deleted (skip)
called for each item in the grid - check if additional information needs to be saved.
+Note: since this is options minus gridstack protected members using Utils.removeInternalForSave(),
+this typically doesn't need to do anything. However your custom Component @Input() are now supported
+using BaseWidget.serialize()
this is the recommended way if you are going to have multiple grids (alow drag&drop between) or drag from toolbar to create items, or drag to remove items, etc...
+
I.E. don't use Angular templating to create grid items as that is harder to sync when gridstack will also add/remove items.
In this example (build on previous one) will use your actual custom angular components inside each grid item (instead of dummy html content) and have per component saved settings as well (using BaseWidget).
+
HTML
+
<gridstack[options]="gridOptions"(changeCB)="onChange($event)"> <divempty-content>message when grid is empty</div> </gridstack>
+
// ...in your module (classic), OR your ng19 app.config provideEnvironmentInitializer call this: constructor() { // register all our dynamic components types created by the grid GridstackComponent.addComponentToSelectorType([AComponent, BComponent]) ; }
// now our content will use Components instead of dummy html content publicgridOptions: NgGridStackOptions = { margin:5, minRow:1, // make space for empty message children: [ // or call load()/addWidget() with same data {x:0, y:0, minW:2, selector:'app-a'}, {x:1, y:0, minW:2, selector:'app-a', input: { text:'bar' }}, // custom input that works using BaseWidget.deserialize() Object.assign(this, w.input) {x:2, y:0, selector:'app-b'}, {x:3, y:0, content:'plain html'}, ] }
// called whenever items change size/position/etc.. see other events publiconChange(data: nodesCB) { console.log('change ', data.nodes.length > 1 ? data.nodes : data.nodes[0]); }
+
+
+
ngFor with wrapper
For simple case where you control the children creation (gridstack doesn't do create or re-parenting)
+
HTML
+
<gridstack[options]="gridOptions"(changeCB)="onChange($event)"> <!-- Angular 17+ --> @for (n of items; track n.id) { <gridstack-item[options]="n">Item {{n.id}}</gridstack-item> } <!-- Angular 16 --> <gridstack-item*ngFor="let n of items; trackBy: identify"[options]="n"> Item {{n.id}} </gridstack-item> </gridstack>
+
// ngFor unique node id to have correct match between our items used and GS publicidentify(index: number, w: GridStackWidget) { returnw.id; // or use index if no id is set and you only modify at the end... }
+
to build the demo, go to angular/projects/demo and run yarn + yarn start and navigate to http://localhost:4200/
+
Code started shipping with v8.1.2+ in dist/angular for people to use directly and is an angular module! (source code under dist/angular/src)
+
Caveats
+
This wrapper needs:
+
+
gridstack v8+ to run as it needs the latest changes (use older version that matches GS versions)
+
Angular 14+ for dynamic createComponent() API and Standalone Components (verified against 19+)
+
+
+
+
NOTE: if you are on Angular 13 or below: copy the wrapper code over (or patch it - see main page example) and change createComponent() calls to use old API instead:
+NOTE2: now that we're using standalone, you will also need to remove standalone: true and imports on each component so you will to copy those locally (or use <11.1.2 version)
+
protectedresolver: ComponentFactoryResolver, ... constfactory = this.resolver.resolveComponentFactory(GridItemComponent); constgridItemRef = grid.container.createComponent(factory) asComponentRef<GridItemComponent>; // ...do the same for widget selector...
+
+
+
ngFor Caveats
+
This wrapper handles well ngFor loops, but if you're using a trackBy function (as I would recommend) and no element id change after an update,
+you must manually update the GridstackItemComponent.option directly - see modifyNgFor() example.
+
The original client list of items is not updated to match content changes made by gridstack (TBD later), but adding new item or removing (as shown in demo) will update those new items. Client could use change/added/removed events to sync that list if they wish to do so.
+
+
Would appreciate getting help doing the same for React and Vue (2 other popular frameworks)
Extended HTMLElement interface for grid items.
+Stores a back-reference to the Angular component for integration.
+
interfaceGridItemCompHTMLElement{     _gridItemComp?:GridstackItemComponent;     ariaAtomic:null|string;     ariaAutoComplete:null|string;     ariaBusy:null|string;     ariaChecked:null|string;     ariaColCount:null|string;     ariaColIndex:null|string;     ariaColSpan:null|string;     ariaCurrent:null|string;     ariaDisabled:null|string;     ariaExpanded:null|string;     ariaHasPopup:null|string;     ariaHidden:null|string;     ariaInvalid:null|string;     ariaKeyShortcuts:null|string;     ariaLabel:null|string;     ariaLevel:null|string;     ariaLive:null|string;     ariaModal:null|string;     ariaMultiLine:null|string;     ariaMultiSelectable:null|string;     ariaOrientation:null|string;     ariaPlaceholder:null|string;     ariaPosInSet:null|string;     ariaPressed:null|string;     ariaReadOnly:null|string;     ariaRequired:null|string;     ariaRoleDescription:null|string;     ariaRowCount:null|string;     ariaRowIndex:null|string;     ariaRowSpan:null|string;     ariaSelected:null|string;     ariaSetSize:null|string;     ariaSort:null|string;     ariaValueMax:null|string;     ariaValueMin:null|string;     ariaValueNow:null|string;     ariaValueText:null|string;     role:null|string;     animate(         keyframes:null|Keyframe[]|PropertyIndexedKeyframes,         options?:number|KeyframeAnimationOptions,     ):Animation;     getAnimations(options?:GetAnimationsOptions):Animation[];     after(...nodes: (string|Node)[]):void;     before(...nodes: (string|Node)[]):void;     remove():void;     replaceWith(...nodes: (string|Node)[]):void;     attributes:NamedNodeMap;     classList:DOMTokenList;     className:string;     clientHeight:number;     clientLeft:number;     clientTop:number;     clientWidth:number;     id:string;     localName:string;     namespaceURI:null|string;     onfullscreenchange:null| ((this:Element,ev:Event)=>any);     onfullscreenerror:null| ((this:Element,ev:Event)=>any);     outerHTML:string;     ownerDocument:Document;     part:DOMTokenList;     prefix:null|string;     scrollHeight:number;     scrollLeft:number;     scrollTop:number;     scrollWidth:number;     shadowRoot:null|ShadowRoot;     slot:string;     tagName:string;     attachShadow(init:ShadowRootInit):ShadowRoot;     checkVisibility(options?:CheckVisibilityOptions):boolean;     closest<KextendskeyofHTMLElementTagNameMap>(         selector:K,     ):null|HTMLElementTagNameMap[K];     closest<KextendskeyofSVGElementTagNameMap>(         selector:K,     ):null|SVGElementTagNameMap[K];     closest<KextendskeyofMathMLElementTagNameMap>(         selector:K,     ):null|MathMLElementTagNameMap[K];     closest<EextendsElement<E>=Element>(selectors:string):null|E;     getAttribute(qualifiedName:string):null|string;     getAttributeNS(namespace:null|string,localName:string):null|string;     getAttributeNames():string[];     getAttributeNode(qualifiedName:string):null|Attr;     getAttributeNodeNS(         namespace:null|string,         localName:string,     ):null|Attr;     getBoundingClientRect():DOMRect;     getClientRects():DOMRectList;     getElementsByClassName(classNames:string):HTMLCollectionOf<Element>;     getElementsByTagName<KextendskeyofHTMLElementTagNameMap>(         qualifiedName:K,     ):HTMLCollectionOf<HTMLElementTagNameMap[K]>;     getElementsByTagName<KextendskeyofSVGElementTagNameMap>(         qualifiedName:K,     ):HTMLCollectionOf<SVGElementTagNameMap[K]>;     getElementsByTagName<KextendskeyofMathMLElementTagNameMap>(         qualifiedName:K,     ):HTMLCollectionOf<MathMLElementTagNameMap[K]>;     getElementsByTagName<KextendskeyofHTMLElementDeprecatedTagNameMap>(         qualifiedName:K,     ):HTMLCollectionOf<HTMLElementDeprecatedTagNameMap[K]>;     getElementsByTagName(qualifiedName:string):HTMLCollectionOf<Element>;     getElementsByTagNameNS(         namespaceURI:"http://www.w3.org/1999/xhtml",         localName:string,     ):HTMLCollectionOf<HTMLElement>;     getElementsByTagNameNS(         namespaceURI:"http://www.w3.org/2000/svg",         localName:string,     ):HTMLCollectionOf<SVGElement>;     getElementsByTagNameNS(         namespaceURI:"http://www.w3.org/1998/Math/MathML",         localName:string,     ):HTMLCollectionOf<MathMLElement>;     getElementsByTagNameNS(         namespace:null|string,         localName:string,     ):HTMLCollectionOf<Element>;     hasAttribute(qualifiedName:string):boolean;     hasAttributeNS(namespace:null|string,localName:string):boolean;     hasAttributes():boolean;     hasPointerCapture(pointerId:number):boolean;     insertAdjacentElement(         where:InsertPosition,         element:Element,     ):null|Element;     insertAdjacentHTML(position:InsertPosition,text:string):void;     insertAdjacentText(where:InsertPosition,data:string):void;     matches(selectors:string):boolean;     releasePointerCapture(pointerId:number):void;     removeAttribute(qualifiedName:string):void;     removeAttributeNS(namespace:null|string,localName:string):void;     removeAttributeNode(attr:Attr):Attr;     requestFullscreen(options?:FullscreenOptions):Promise<void>;     requestPointerLock():void;     scroll(options?:ScrollToOptions):void;     scroll(x:number,y:number):void;     scrollBy(options?:ScrollToOptions):void;     scrollBy(x:number,y:number):void;     scrollIntoView(arg?:boolean|ScrollIntoViewOptions):void;     scrollTo(options?:ScrollToOptions):void;     scrollTo(x:number,y:number):void;     setAttribute(qualifiedName:string,value:string):void;     setAttributeNS(         namespace:null|string,         qualifiedName:string,         value:string,     ):void;     setAttributeNode(attr:Attr):null|Attr;     setAttributeNodeNS(attr:Attr):null|Attr;     setPointerCapture(pointerId:number):void;     toggleAttribute(qualifiedName:string,force?:boolean):boolean;     webkitMatchesSelector(selectors:string):boolean;     style:CSSStyleDeclaration;     contentEditable:string;     enterKeyHint:string;     inputMode:string;     isContentEditable:boolean;     dispatchEvent(event:Event):boolean;     onabort:null| ((this:GlobalEventHandlers,ev:UIEvent)=>any);     onanimationcancel:         |null         | ((this:GlobalEventHandlers,ev:AnimationEvent)=>any);     onanimationend:         |null         | ((this:GlobalEventHandlers,ev:AnimationEvent)=>any);     onanimationiteration:         |null         | ((this:GlobalEventHandlers,ev:AnimationEvent)=>any);     onanimationstart:         |null         | ((this:GlobalEventHandlers,ev:AnimationEvent)=>any);     onauxclick:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onbeforeinput:null| ((this:GlobalEventHandlers,ev:InputEvent)=>any);     onblur:null| ((this:GlobalEventHandlers,ev:FocusEvent)=>any);     oncancel:null| ((this:GlobalEventHandlers,ev:Event)=>any);     oncanplay:null| ((this:GlobalEventHandlers,ev:Event)=>any);     oncanplaythrough:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onchange:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onclick:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onclose:null| ((this:GlobalEventHandlers,ev:Event)=>any);     oncontextmenu:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     oncopy:null| ((this:GlobalEventHandlers,ev:ClipboardEvent)=>any);     oncuechange:null| ((this:GlobalEventHandlers,ev:Event)=>any);     oncut:null| ((this:GlobalEventHandlers,ev:ClipboardEvent)=>any);     ondblclick:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     ondrag:null| ((this:GlobalEventHandlers,ev:DragEvent)=>any);     ondragend:null| ((this:GlobalEventHandlers,ev:DragEvent)=>any);     ondragenter:null| ((this:GlobalEventHandlers,ev:DragEvent)=>any);     ondragleave:null| ((this:GlobalEventHandlers,ev:DragEvent)=>any);     ondragover:null| ((this:GlobalEventHandlers,ev:DragEvent)=>any);     ondragstart:null| ((this:GlobalEventHandlers,ev:DragEvent)=>any);     ondrop:null| ((this:GlobalEventHandlers,ev:DragEvent)=>any);     ondurationchange:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onemptied:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onended:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onerror:OnErrorEventHandler;     onfocus:null| ((this:GlobalEventHandlers,ev:FocusEvent)=>any);     onformdata:null| ((this:GlobalEventHandlers,ev:FormDataEvent)=>any);     ongotpointercapture:         |null         | ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     oninput:null| ((this:GlobalEventHandlers,ev:Event)=>any);     oninvalid:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onkeydown:null| ((this:GlobalEventHandlers,ev:KeyboardEvent)=>any);     onkeypress:null| ((this:GlobalEventHandlers,ev:KeyboardEvent)=>any);     onkeyup:null| ((this:GlobalEventHandlers,ev:KeyboardEvent)=>any);     onload:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onloadeddata:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onloadedmetadata:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onloadstart:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onlostpointercapture:         |null         | ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onmousedown:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onmouseenter:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onmouseleave:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onmousemove:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onmouseout:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onmouseover:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onmouseup:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onpaste:null| ((this:GlobalEventHandlers,ev:ClipboardEvent)=>any);     onpause:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onplay:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onplaying:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onpointercancel:         |null         | ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onpointerdown:         |null         | ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onpointerenter:         |null         | ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onpointerleave:         |null         | ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onpointermove:         |null         | ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onpointerout:null| ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onpointerover:         |null         | ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onpointerup:null| ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onprogress:null| ((this:GlobalEventHandlers,ev:ProgressEvent)=>any);     onratechange:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onreset:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onresize:null| ((this:GlobalEventHandlers,ev:UIEvent)=>any);     onscroll:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onsecuritypolicyviolation:         |null         | ((this:GlobalEventHandlers,ev:SecurityPolicyViolationEvent)=>any);     onseeked:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onseeking:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onselect:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onselectionchange:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onselectstart:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onslotchange:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onstalled:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onsubmit:null| ((this:GlobalEventHandlers,ev:SubmitEvent)=>any);     onsuspend:null| ((this:GlobalEventHandlers,ev:Event)=>any);     ontimeupdate:null| ((this:GlobalEventHandlers,ev:Event)=>any);     ontoggle:null| ((this:GlobalEventHandlers,ev:Event)=>any);     ontouchcancel?:null| ((this:GlobalEventHandlers,ev:TouchEvent)=>any);     ontouchend?:null| ((this:GlobalEventHandlers,ev:TouchEvent)=>any);     ontouchmove?:null| ((this:GlobalEventHandlers,ev:TouchEvent)=>any);     ontouchstart?:null| ((this:GlobalEventHandlers,ev:TouchEvent)=>any);     ontransitioncancel:         |null         | ((this:GlobalEventHandlers,ev:TransitionEvent)=>any);     ontransitionend:         |null         | ((this:GlobalEventHandlers,ev:TransitionEvent)=>any);     ontransitionrun:         |null         | ((this:GlobalEventHandlers,ev:TransitionEvent)=>any);     ontransitionstart:         |null         | ((this:GlobalEventHandlers,ev:TransitionEvent)=>any);     onvolumechange:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onwaiting:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onwebkitanimationend:         |null         | ((this:GlobalEventHandlers,ev:Event)=>any);     onwebkitanimationiteration:         |null         | ((this:GlobalEventHandlers,ev:Event)=>any);     onwebkitanimationstart:         |null         | ((this:GlobalEventHandlers,ev:Event)=>any);     onwebkittransitionend:         |null         | ((this:GlobalEventHandlers,ev:Event)=>any);     onwheel:null| ((this:GlobalEventHandlers,ev:WheelEvent)=>any);     accessKey:string;     accessKeyLabel:string;     autocapitalize:string;     dir:string;     draggable:boolean;     hidden:boolean;     inert:boolean;     innerText:string;     lang:string;     offsetHeight:number;     offsetLeft:number;     offsetParent:null|Element;     offsetTop:number;     offsetWidth:number;     outerText:string;     spellcheck:boolean;     title:string;     translate:boolean;     attachInternals():ElementInternals;     click():void;     addEventListener<KextendskeyofHTMLElementEventMap>(         type:K,         listener:(this:HTMLElement,ev:HTMLElementEventMap[K])=>any,         options?:boolean|AddEventListenerOptions,     ):void;     addEventListener(         type:string,         listener:EventListenerOrEventListenerObject,         options?:boolean|AddEventListenerOptions,     ):void;     removeEventListener<KextendskeyofHTMLElementEventMap>(         type:K,         listener:(this:HTMLElement,ev:HTMLElementEventMap[K])=>any,         options?:boolean|EventListenerOptions,     ):void;     removeEventListener(         type:string,         listener:EventListenerOrEventListenerObject,         options?:boolean|EventListenerOptions,     ):void;     autofocus:boolean;     dataset:DOMStringMap;     nonce?:string;     tabIndex:number;     blur():void;     focus(options?:FocusOptions):void;     innerHTML:string;     baseURI:string;     childNodes:NodeListOf<ChildNode>;     firstChild:null|ChildNode;     isConnected:boolean;     lastChild:null|ChildNode;     nextSibling:null|ChildNode;     nodeName:string;     nodeType:number;     nodeValue:null|string;     parentElement:null|HTMLElement;     parentNode:null|ParentNode;     previousSibling:null|ChildNode;     textContent:null|string;     appendChild<TextendsNode<T>>(node:T):T;     cloneNode(deep?:boolean):Node;     compareDocumentPosition(other:Node):number;     contains(other:null|Node):boolean;     getRootNode(options?:GetRootNodeOptions):Node;     hasChildNodes():boolean;     insertBefore<TextendsNode<T>>(node:T,child:null|Node):T;     isDefaultNamespace(namespace:null|string):boolean;     isEqualNode(otherNode:null|Node):boolean;     isSameNode(otherNode:null|Node):boolean;     lookupNamespaceURI(prefix:null|string):null|string;     lookupPrefix(namespace:null|string):null|string;     normalize():void;     removeChild<TextendsNode<T>>(child:T):T;     replaceChild<TextendsNode<T>>(node:Node,child:T):T;     ELEMENT_NODE:1;     ATTRIBUTE_NODE:2;     TEXT_NODE:3;     CDATA_SECTION_NODE:4;     ENTITY_REFERENCE_NODE:5;     ENTITY_NODE:6;     PROCESSING_INSTRUCTION_NODE:7;     COMMENT_NODE:8;     DOCUMENT_NODE:9;     DOCUMENT_TYPE_NODE:10;     DOCUMENT_FRAGMENT_NODE:11;     NOTATION_NODE:12;     DOCUMENT_POSITION_DISCONNECTED:1;     DOCUMENT_POSITION_PRECEDING:2;     DOCUMENT_POSITION_FOLLOWING:4;     DOCUMENT_POSITION_CONTAINS:8;     DOCUMENT_POSITION_CONTAINED_BY:16;     DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC:32;     nextElementSibling:null|Element;     previousElementSibling:null|Element;     childElementCount:number;     children:HTMLCollection;     firstElementChild:null|Element;     lastElementChild:null|Element;     append(...nodes: (string|Node)[]):void;     prepend(...nodes: (string|Node)[]):void;     querySelector<KextendskeyofHTMLElementTagNameMap>(         selectors:K,     ):null|HTMLElementTagNameMap[K];     querySelector<KextendskeyofSVGElementTagNameMap>(         selectors:K,     ):null|SVGElementTagNameMap[K];     querySelector<KextendskeyofMathMLElementTagNameMap>(         selectors:K,     ):null|MathMLElementTagNameMap[K];     querySelector<KextendskeyofHTMLElementDeprecatedTagNameMap>(         selectors:K,     ):null|HTMLElementDeprecatedTagNameMap[K];     querySelector<EextendsElement<E>=Element>(selectors:string):null|E;     querySelectorAll<KextendskeyofHTMLElementTagNameMap>(         selectors:K,     ):NodeListOf<HTMLElementTagNameMap[K]>;     querySelectorAll<KextendskeyofSVGElementTagNameMap>(         selectors:K,     ):NodeListOf<SVGElementTagNameMap[K]>;     querySelectorAll<KextendskeyofMathMLElementTagNameMap>(         selectors:K,     ):NodeListOf<MathMLElementTagNameMap[K]>;     querySelectorAll<KextendskeyofHTMLElementDeprecatedTagNameMap>(         selectors:K,     ):NodeListOf<HTMLElementDeprecatedTagNameMap[K]>;     querySelectorAll<EextendsElement<E>=Element>(         selectors:string,     ):NodeListOf<E>;     replaceChildren(...nodes: (string|Node)[]):void;     assignedSlot:null|HTMLSlotElement; }
Returns a HTMLCollection of the elements in the object on which the method was invoked (a document or an element) that have all the classes given by classNames. The classNames argument is interpreted as a space-separated list of classes.
+
Parameters
classNames: string
Returns HTMLCollectionOf<Element>
getElementsByTagName
getElementsByTagName<KextendskeyofHTMLElementTagNameMap>( Â Â Â Â qualifiedName:K, ):HTMLCollectionOf<HTMLElementTagNameMap[K]>
Displays element fullscreen and resolves promise when done.
+
When supplied, options's navigationUI member indicates whether showing navigation UI while in fullscreen is preferred or not. If set to "show", navigation simplicity is preferred over screen space, and if set to "hide", more screen space is preferred. User agents are always free to honor user preference over the application's. The default value "auto" indicates no application preference.
If force is not given, "toggles" qualifiedName, removing it if it is present and adding it if it is not present. If force is true, adds qualifiedName. If force is false, removes qualifiedName.
+
Returns true if qualifiedName is now present, and false otherwise.
+
Parameters
qualifiedName: string
Optionalforce: boolean
Returns boolean
webkitMatchesSelector
webkitMatchesSelector(selectors:string):boolean
Parameters
selectors: string
Returns boolean
Deprecated
This is a legacy alias of matches.
+
dispatchEvent
dispatchEvent(event:Event):boolean
Dispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.
+
Parameters
event: Event
Returns boolean
attachInternals
attachInternals():ElementInternals
Returns ElementInternals
click
click():void
Returns void
addEventListener
addEventListener<KextendskeyofHTMLElementEventMap>( Â Â Â Â type:K, Â Â Â Â listener:(this:HTMLElement,ev:HTMLElementEventMap[K])=>any, Â Â Â Â options?:boolean|AddEventListenerOptions, ):void
addEventListener( Â Â Â Â type:string, Â Â Â Â listener:EventListenerOrEventListenerObject, Â Â Â Â options?:boolean|AddEventListenerOptions, ):void
Parameters
type: string
listener: EventListenerOrEventListenerObject
Optionaloptions: boolean|AddEventListenerOptions
Returns void
removeEventListener
removeEventListener<KextendskeyofHTMLElementEventMap>( Â Â Â Â type:K, Â Â Â Â listener:(this:HTMLElement,ev:HTMLElementEventMap[K])=>any, Â Â Â Â options?:boolean|EventListenerOptions, ):void
Extended HTMLElement interface for the grid container.
+Stores a back-reference to the Angular component for integration purposes.
+
interfaceGridCompHTMLElement{     _gridComp?:GridstackComponent;     ariaAtomic:null|string;     ariaAutoComplete:null|string;     ariaBusy:null|string;     ariaChecked:null|string;     ariaColCount:null|string;     ariaColIndex:null|string;     ariaColSpan:null|string;     ariaCurrent:null|string;     ariaDisabled:null|string;     ariaExpanded:null|string;     ariaHasPopup:null|string;     ariaHidden:null|string;     ariaInvalid:null|string;     ariaKeyShortcuts:null|string;     ariaLabel:null|string;     ariaLevel:null|string;     ariaLive:null|string;     ariaModal:null|string;     ariaMultiLine:null|string;     ariaMultiSelectable:null|string;     ariaOrientation:null|string;     ariaPlaceholder:null|string;     ariaPosInSet:null|string;     ariaPressed:null|string;     ariaReadOnly:null|string;     ariaRequired:null|string;     ariaRoleDescription:null|string;     ariaRowCount:null|string;     ariaRowIndex:null|string;     ariaRowSpan:null|string;     ariaSelected:null|string;     ariaSetSize:null|string;     ariaSort:null|string;     ariaValueMax:null|string;     ariaValueMin:null|string;     ariaValueNow:null|string;     ariaValueText:null|string;     role:null|string;     animate(         keyframes:null|Keyframe[]|PropertyIndexedKeyframes,         options?:number|KeyframeAnimationOptions,     ):Animation;     getAnimations(options?:GetAnimationsOptions):Animation[];     after(...nodes: (string|Node)[]):void;     before(...nodes: (string|Node)[]):void;     remove():void;     replaceWith(...nodes: (string|Node)[]):void;     attributes:NamedNodeMap;     classList:DOMTokenList;     className:string;     clientHeight:number;     clientLeft:number;     clientTop:number;     clientWidth:number;     id:string;     localName:string;     namespaceURI:null|string;     onfullscreenchange:null| ((this:Element,ev:Event)=>any);     onfullscreenerror:null| ((this:Element,ev:Event)=>any);     outerHTML:string;     ownerDocument:Document;     part:DOMTokenList;     prefix:null|string;     scrollHeight:number;     scrollLeft:number;     scrollTop:number;     scrollWidth:number;     shadowRoot:null|ShadowRoot;     slot:string;     tagName:string;     attachShadow(init:ShadowRootInit):ShadowRoot;     checkVisibility(options?:CheckVisibilityOptions):boolean;     closest<KextendskeyofHTMLElementTagNameMap>(         selector:K,     ):null|HTMLElementTagNameMap[K];     closest<KextendskeyofSVGElementTagNameMap>(         selector:K,     ):null|SVGElementTagNameMap[K];     closest<KextendskeyofMathMLElementTagNameMap>(         selector:K,     ):null|MathMLElementTagNameMap[K];     closest<EextendsElement<E>=Element>(selectors:string):null|E;     getAttribute(qualifiedName:string):null|string;     getAttributeNS(namespace:null|string,localName:string):null|string;     getAttributeNames():string[];     getAttributeNode(qualifiedName:string):null|Attr;     getAttributeNodeNS(         namespace:null|string,         localName:string,     ):null|Attr;     getBoundingClientRect():DOMRect;     getClientRects():DOMRectList;     getElementsByClassName(classNames:string):HTMLCollectionOf<Element>;     getElementsByTagName<KextendskeyofHTMLElementTagNameMap>(         qualifiedName:K,     ):HTMLCollectionOf<HTMLElementTagNameMap[K]>;     getElementsByTagName<KextendskeyofSVGElementTagNameMap>(         qualifiedName:K,     ):HTMLCollectionOf<SVGElementTagNameMap[K]>;     getElementsByTagName<KextendskeyofMathMLElementTagNameMap>(         qualifiedName:K,     ):HTMLCollectionOf<MathMLElementTagNameMap[K]>;     getElementsByTagName<KextendskeyofHTMLElementDeprecatedTagNameMap>(         qualifiedName:K,     ):HTMLCollectionOf<HTMLElementDeprecatedTagNameMap[K]>;     getElementsByTagName(qualifiedName:string):HTMLCollectionOf<Element>;     getElementsByTagNameNS(         namespaceURI:"http://www.w3.org/1999/xhtml",         localName:string,     ):HTMLCollectionOf<HTMLElement>;     getElementsByTagNameNS(         namespaceURI:"http://www.w3.org/2000/svg",         localName:string,     ):HTMLCollectionOf<SVGElement>;     getElementsByTagNameNS(         namespaceURI:"http://www.w3.org/1998/Math/MathML",         localName:string,     ):HTMLCollectionOf<MathMLElement>;     getElementsByTagNameNS(         namespace:null|string,         localName:string,     ):HTMLCollectionOf<Element>;     hasAttribute(qualifiedName:string):boolean;     hasAttributeNS(namespace:null|string,localName:string):boolean;     hasAttributes():boolean;     hasPointerCapture(pointerId:number):boolean;     insertAdjacentElement(         where:InsertPosition,         element:Element,     ):null|Element;     insertAdjacentHTML(position:InsertPosition,text:string):void;     insertAdjacentText(where:InsertPosition,data:string):void;     matches(selectors:string):boolean;     releasePointerCapture(pointerId:number):void;     removeAttribute(qualifiedName:string):void;     removeAttributeNS(namespace:null|string,localName:string):void;     removeAttributeNode(attr:Attr):Attr;     requestFullscreen(options?:FullscreenOptions):Promise<void>;     requestPointerLock():void;     scroll(options?:ScrollToOptions):void;     scroll(x:number,y:number):void;     scrollBy(options?:ScrollToOptions):void;     scrollBy(x:number,y:number):void;     scrollIntoView(arg?:boolean|ScrollIntoViewOptions):void;     scrollTo(options?:ScrollToOptions):void;     scrollTo(x:number,y:number):void;     setAttribute(qualifiedName:string,value:string):void;     setAttributeNS(         namespace:null|string,         qualifiedName:string,         value:string,     ):void;     setAttributeNode(attr:Attr):null|Attr;     setAttributeNodeNS(attr:Attr):null|Attr;     setPointerCapture(pointerId:number):void;     toggleAttribute(qualifiedName:string,force?:boolean):boolean;     webkitMatchesSelector(selectors:string):boolean;     style:CSSStyleDeclaration;     contentEditable:string;     enterKeyHint:string;     inputMode:string;     isContentEditable:boolean;     dispatchEvent(event:Event):boolean;     onabort:null| ((this:GlobalEventHandlers,ev:UIEvent)=>any);     onanimationcancel:         |null         | ((this:GlobalEventHandlers,ev:AnimationEvent)=>any);     onanimationend:         |null         | ((this:GlobalEventHandlers,ev:AnimationEvent)=>any);     onanimationiteration:         |null         | ((this:GlobalEventHandlers,ev:AnimationEvent)=>any);     onanimationstart:         |null         | ((this:GlobalEventHandlers,ev:AnimationEvent)=>any);     onauxclick:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onbeforeinput:null| ((this:GlobalEventHandlers,ev:InputEvent)=>any);     onblur:null| ((this:GlobalEventHandlers,ev:FocusEvent)=>any);     oncancel:null| ((this:GlobalEventHandlers,ev:Event)=>any);     oncanplay:null| ((this:GlobalEventHandlers,ev:Event)=>any);     oncanplaythrough:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onchange:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onclick:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onclose:null| ((this:GlobalEventHandlers,ev:Event)=>any);     oncontextmenu:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     oncopy:null| ((this:GlobalEventHandlers,ev:ClipboardEvent)=>any);     oncuechange:null| ((this:GlobalEventHandlers,ev:Event)=>any);     oncut:null| ((this:GlobalEventHandlers,ev:ClipboardEvent)=>any);     ondblclick:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     ondrag:null| ((this:GlobalEventHandlers,ev:DragEvent)=>any);     ondragend:null| ((this:GlobalEventHandlers,ev:DragEvent)=>any);     ondragenter:null| ((this:GlobalEventHandlers,ev:DragEvent)=>any);     ondragleave:null| ((this:GlobalEventHandlers,ev:DragEvent)=>any);     ondragover:null| ((this:GlobalEventHandlers,ev:DragEvent)=>any);     ondragstart:null| ((this:GlobalEventHandlers,ev:DragEvent)=>any);     ondrop:null| ((this:GlobalEventHandlers,ev:DragEvent)=>any);     ondurationchange:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onemptied:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onended:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onerror:OnErrorEventHandler;     onfocus:null| ((this:GlobalEventHandlers,ev:FocusEvent)=>any);     onformdata:null| ((this:GlobalEventHandlers,ev:FormDataEvent)=>any);     ongotpointercapture:         |null         | ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     oninput:null| ((this:GlobalEventHandlers,ev:Event)=>any);     oninvalid:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onkeydown:null| ((this:GlobalEventHandlers,ev:KeyboardEvent)=>any);     onkeypress:null| ((this:GlobalEventHandlers,ev:KeyboardEvent)=>any);     onkeyup:null| ((this:GlobalEventHandlers,ev:KeyboardEvent)=>any);     onload:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onloadeddata:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onloadedmetadata:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onloadstart:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onlostpointercapture:         |null         | ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onmousedown:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onmouseenter:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onmouseleave:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onmousemove:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onmouseout:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onmouseover:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onmouseup:null| ((this:GlobalEventHandlers,ev:MouseEvent)=>any);     onpaste:null| ((this:GlobalEventHandlers,ev:ClipboardEvent)=>any);     onpause:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onplay:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onplaying:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onpointercancel:         |null         | ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onpointerdown:         |null         | ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onpointerenter:         |null         | ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onpointerleave:         |null         | ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onpointermove:         |null         | ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onpointerout:null| ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onpointerover:         |null         | ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onpointerup:null| ((this:GlobalEventHandlers,ev:PointerEvent)=>any);     onprogress:null| ((this:GlobalEventHandlers,ev:ProgressEvent)=>any);     onratechange:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onreset:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onresize:null| ((this:GlobalEventHandlers,ev:UIEvent)=>any);     onscroll:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onsecuritypolicyviolation:         |null         | ((this:GlobalEventHandlers,ev:SecurityPolicyViolationEvent)=>any);     onseeked:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onseeking:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onselect:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onselectionchange:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onselectstart:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onslotchange:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onstalled:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onsubmit:null| ((this:GlobalEventHandlers,ev:SubmitEvent)=>any);     onsuspend:null| ((this:GlobalEventHandlers,ev:Event)=>any);     ontimeupdate:null| ((this:GlobalEventHandlers,ev:Event)=>any);     ontoggle:null| ((this:GlobalEventHandlers,ev:Event)=>any);     ontouchcancel?:null| ((this:GlobalEventHandlers,ev:TouchEvent)=>any);     ontouchend?:null| ((this:GlobalEventHandlers,ev:TouchEvent)=>any);     ontouchmove?:null| ((this:GlobalEventHandlers,ev:TouchEvent)=>any);     ontouchstart?:null| ((this:GlobalEventHandlers,ev:TouchEvent)=>any);     ontransitioncancel:         |null         | ((this:GlobalEventHandlers,ev:TransitionEvent)=>any);     ontransitionend:         |null         | ((this:GlobalEventHandlers,ev:TransitionEvent)=>any);     ontransitionrun:         |null         | ((this:GlobalEventHandlers,ev:TransitionEvent)=>any);     ontransitionstart:         |null         | ((this:GlobalEventHandlers,ev:TransitionEvent)=>any);     onvolumechange:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onwaiting:null| ((this:GlobalEventHandlers,ev:Event)=>any);     onwebkitanimationend:         |null         | ((this:GlobalEventHandlers,ev:Event)=>any);     onwebkitanimationiteration:         |null         | ((this:GlobalEventHandlers,ev:Event)=>any);     onwebkitanimationstart:         |null         | ((this:GlobalEventHandlers,ev:Event)=>any);     onwebkittransitionend:         |null         | ((this:GlobalEventHandlers,ev:Event)=>any);     onwheel:null| ((this:GlobalEventHandlers,ev:WheelEvent)=>any);     accessKey:string;     accessKeyLabel:string;     autocapitalize:string;     dir:string;     draggable:boolean;     hidden:boolean;     inert:boolean;     innerText:string;     lang:string;     offsetHeight:number;     offsetLeft:number;     offsetParent:null|Element;     offsetTop:number;     offsetWidth:number;     outerText:string;     spellcheck:boolean;     title:string;     translate:boolean;     attachInternals():ElementInternals;     click():void;     addEventListener<KextendskeyofHTMLElementEventMap>(         type:K,         listener:(this:HTMLElement,ev:HTMLElementEventMap[K])=>any,         options?:boolean|AddEventListenerOptions,     ):void;     addEventListener(         type:string,         listener:EventListenerOrEventListenerObject,         options?:boolean|AddEventListenerOptions,     ):void;     removeEventListener<KextendskeyofHTMLElementEventMap>(         type:K,         listener:(this:HTMLElement,ev:HTMLElementEventMap[K])=>any,         options?:boolean|EventListenerOptions,     ):void;     removeEventListener(         type:string,         listener:EventListenerOrEventListenerObject,         options?:boolean|EventListenerOptions,     ):void;     autofocus:boolean;     dataset:DOMStringMap;     nonce?:string;     tabIndex:number;     blur():void;     focus(options?:FocusOptions):void;     innerHTML:string;     baseURI:string;     childNodes:NodeListOf<ChildNode>;     firstChild:null|ChildNode;     isConnected:boolean;     lastChild:null|ChildNode;     nextSibling:null|ChildNode;     nodeName:string;     nodeType:number;     nodeValue:null|string;     parentElement:null|HTMLElement;     parentNode:null|ParentNode;     previousSibling:null|ChildNode;     textContent:null|string;     appendChild<TextendsNode<T>>(node:T):T;     cloneNode(deep?:boolean):Node;     compareDocumentPosition(other:Node):number;     contains(other:null|Node):boolean;     getRootNode(options?:GetRootNodeOptions):Node;     hasChildNodes():boolean;     insertBefore<TextendsNode<T>>(node:T,child:null|Node):T;     isDefaultNamespace(namespace:null|string):boolean;     isEqualNode(otherNode:null|Node):boolean;     isSameNode(otherNode:null|Node):boolean;     lookupNamespaceURI(prefix:null|string):null|string;     lookupPrefix(namespace:null|string):null|string;     normalize():void;     removeChild<TextendsNode<T>>(child:T):T;     replaceChild<TextendsNode<T>>(node:Node,child:T):T;     ELEMENT_NODE:1;     ATTRIBUTE_NODE:2;     TEXT_NODE:3;     CDATA_SECTION_NODE:4;     ENTITY_REFERENCE_NODE:5;     ENTITY_NODE:6;     PROCESSING_INSTRUCTION_NODE:7;     COMMENT_NODE:8;     DOCUMENT_NODE:9;     DOCUMENT_TYPE_NODE:10;     DOCUMENT_FRAGMENT_NODE:11;     NOTATION_NODE:12;     DOCUMENT_POSITION_DISCONNECTED:1;     DOCUMENT_POSITION_PRECEDING:2;     DOCUMENT_POSITION_FOLLOWING:4;     DOCUMENT_POSITION_CONTAINS:8;     DOCUMENT_POSITION_CONTAINED_BY:16;     DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC:32;     nextElementSibling:null|Element;     previousElementSibling:null|Element;     childElementCount:number;     children:HTMLCollection;     firstElementChild:null|Element;     lastElementChild:null|Element;     append(...nodes: (string|Node)[]):void;     prepend(...nodes: (string|Node)[]):void;     querySelector<KextendskeyofHTMLElementTagNameMap>(         selectors:K,     ):null|HTMLElementTagNameMap[K];     querySelector<KextendskeyofSVGElementTagNameMap>(         selectors:K,     ):null|SVGElementTagNameMap[K];     querySelector<KextendskeyofMathMLElementTagNameMap>(         selectors:K,     ):null|MathMLElementTagNameMap[K];     querySelector<KextendskeyofHTMLElementDeprecatedTagNameMap>(         selectors:K,     ):null|HTMLElementDeprecatedTagNameMap[K];     querySelector<EextendsElement<E>=Element>(selectors:string):null|E;     querySelectorAll<KextendskeyofHTMLElementTagNameMap>(         selectors:K,     ):NodeListOf<HTMLElementTagNameMap[K]>;     querySelectorAll<KextendskeyofSVGElementTagNameMap>(         selectors:K,     ):NodeListOf<SVGElementTagNameMap[K]>;     querySelectorAll<KextendskeyofMathMLElementTagNameMap>(         selectors:K,     ):NodeListOf<MathMLElementTagNameMap[K]>;     querySelectorAll<KextendskeyofHTMLElementDeprecatedTagNameMap>(         selectors:K,     ):NodeListOf<HTMLElementDeprecatedTagNameMap[K]>;     querySelectorAll<EextendsElement<E>=Element>(         selectors:string,     ):NodeListOf<E>;     replaceChildren(...nodes: (string|Node)[]):void;     assignedSlot:null|HTMLSlotElement; }
Returns a HTMLCollection of the elements in the object on which the method was invoked (a document or an element) that have all the classes given by classNames. The classNames argument is interpreted as a space-separated list of classes.
+
Parameters
classNames: string
Returns HTMLCollectionOf<Element>
getElementsByTagName
getElementsByTagName<KextendskeyofHTMLElementTagNameMap>( Â Â Â Â qualifiedName:K, ):HTMLCollectionOf<HTMLElementTagNameMap[K]>
Displays element fullscreen and resolves promise when done.
+
When supplied, options's navigationUI member indicates whether showing navigation UI while in fullscreen is preferred or not. If set to "show", navigation simplicity is preferred over screen space, and if set to "hide", more screen space is preferred. User agents are always free to honor user preference over the application's. The default value "auto" indicates no application preference.
If force is not given, "toggles" qualifiedName, removing it if it is present and adding it if it is not present. If force is true, adds qualifiedName. If force is false, removes qualifiedName.
+
Returns true if qualifiedName is now present, and false otherwise.
+
Parameters
qualifiedName: string
Optionalforce: boolean
Returns boolean
webkitMatchesSelector
webkitMatchesSelector(selectors:string):boolean
Parameters
selectors: string
Returns boolean
Deprecated
This is a legacy alias of matches.
+
dispatchEvent
dispatchEvent(event:Event):boolean
Dispatches a synthetic event event to target and returns true if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.
+
Parameters
event: Event
Returns boolean
attachInternals
attachInternals():ElementInternals
Returns ElementInternals
click
click():void
Returns void
addEventListener
addEventListener<KextendskeyofHTMLElementEventMap>( Â Â Â Â type:K, Â Â Â Â listener:(this:HTMLElement,ev:HTMLElementEventMap[K])=>any, Â Â Â Â options?:boolean|AddEventListenerOptions, ):void
addEventListener( Â Â Â Â type:string, Â Â Â Â listener:EventListenerOrEventListenerObject, Â Â Â Â options?:boolean|AddEventListenerOptions, ):void
Parameters
type: string
listener: EventListenerOrEventListenerObject
Optionaloptions: boolean|AddEventListenerOptions
Returns void
removeEventListener
removeEventListener<KextendskeyofHTMLElementEventMap>( Â Â Â Â type:K, Â Â Â Â listener:(this:HTMLElement,ev:HTMLElementEventMap[K])=>any, Â Â Â Â options?:boolean|EventListenerOptions, ):void
diff --git a/angular/doc/html/media/app.component.ts b/angular/doc/html/media/app.component.ts
new file mode 100644
index 000000000..4874f9b9d
--- /dev/null
+++ b/angular/doc/html/media/app.component.ts
@@ -0,0 +1,249 @@
+import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
+import { GridStack, GridStackOptions, GridStackWidget } from 'gridstack';
+import { AngularSimpleComponent } from './simple';
+import { AngularNgForTestComponent } from './ngFor';
+import { AngularNgForCmdTestComponent } from './ngFor_cmd';
+
+// TEST: local testing of file
+// import { GridstackComponent, NgGridStackOptions, NgGridStackWidget, elementCB, gsCreateNgComponents, nodesCB } from './gridstack.component';
+import { GridstackComponent, NgGridStackOptions, NgGridStackWidget, elementCB, gsCreateNgComponents, nodesCB } from 'gridstack/dist/angular';
+
+// unique ids sets for each item for correct ngFor updating
+let ids = 1;
+@Component({
+ selector: 'app-root',
+ templateUrl: './app.component.html',
+ styleUrls: ['./app.component.css']
+})
+export class AppComponent implements OnInit {
+
+ @ViewChild(AngularSimpleComponent) case0Comp?: AngularSimpleComponent;
+ @ViewChild(AngularNgForTestComponent) case1Comp?: AngularNgForTestComponent;
+ @ViewChild(AngularNgForCmdTestComponent) case2Comp?: AngularNgForCmdTestComponent;
+ @ViewChild(GridstackComponent) gridComp?: GridstackComponent;
+ @ViewChild('origTextArea', {static: true}) origTextEl?: ElementRef;
+ @ViewChild('textArea', {static: true}) textEl?: ElementRef;
+
+ // which sample to show
+ public show = 5;
+
+ /** sample grid options and items to load... */
+ public items: GridStackWidget[] = [
+ {x: 0, y: 0, minW: 2},
+ {x: 1, y: 1},
+ {x: 2, y: 2},
+ ];
+ public gridOptions: GridStackOptions = {
+ margin: 5,
+ // float: true,
+ minRow: 1,
+ cellHeight: 70,
+ columnOpts: { breakpoints: [{w:768, c:1}] },
+ }
+ public sub0: NgGridStackWidget[] = [{x:0, y:0, selector:'app-a'}, {x:1, y:0, selector:'app-a', input: {text: 'bar'}}, {x:1, y:1, content:'plain html'}, {x:0, y:1, selector:'app-b'} ];
+ public gridOptionsFull: NgGridStackOptions = {
+ ...this.gridOptions,
+ children: this.sub0,
+ }
+
+ public lazyChildren: NgGridStackWidget[] = [];
+ public gridOptionsDelay: NgGridStackOptions = {
+ ...this.gridOptions,
+ lazyLoad: true,
+ children: this.lazyChildren,
+ }
+
+ // nested grid options
+ private subOptions: GridStackOptions = {
+ cellHeight: 50, // should be 50 - top/bottom
+ column: 'auto', // size to match container
+ acceptWidgets: true, // will accept .grid-stack-item by default
+ margin: 5,
+ };
+ public sub1: NgGridStackWidget[] = [ {x:0, y:0, selector:'app-a'}, {x:1, y:0, selector:'app-b'}, {x:2, y:0, selector:'app-c'}, {x:3, y:0}, {x:0, y:1}, {x:1, y:1}];
+ public sub2: NgGridStackWidget[] = [ {x:0, y:0}, {x:0, y:1, w:2}];
+ public sub3: NgGridStackWidget = { selector: 'app-n', w:2, h:2, subGridOpts: { children: [{selector: 'app-a'}, {selector: 'app-b', y:0, x:1}]}};
+ private subChildren: NgGridStackWidget[] = [
+ {x:0, y:0, content: 'regular item'},
+ {x:1, y:0, w:4, h:4, subGridOpts: {children: this.sub1}},
+ // {x:5, y:0, w:3, h:4, subGridOpts: {children: this.sub2}},
+ this.sub3,
+ ]
+ public nestedGridOptions: NgGridStackOptions = { // main grid options
+ cellHeight: 50,
+ margin: 5,
+ minRow: 2, // don't collapse when empty
+ acceptWidgets: true,
+ subGridOpts: this.subOptions, // all sub grids will default to those
+ children: this.subChildren,
+ };
+ public twoGridOpt1: NgGridStackOptions = {
+ column: 6,
+ cellHeight: 50,
+ margin: 5,
+ minRow: 1, // don't collapse when empty
+ removable: '.trash',
+ acceptWidgets: true,
+ float: true,
+ children: [
+ {x: 0, y: 0, w: 2, h: 2, selector: 'app-a'},
+ {x: 3, y: 1, h: 2, selector: 'app-b'},
+ {x: 4, y: 1},
+ {x: 2, y: 3, w: 3, maxW: 3, id: 'special', content: 'has maxW=3'},
+ ]
+ };
+ public twoGridOpt2: NgGridStackOptions = { ...this.twoGridOpt1, float: false }
+ private serializedData?: NgGridStackOptions;
+
+ // sidebar content to create storing the Widget description to be used on drop
+ public sidebarContent6: NgGridStackWidget[] = [
+ { w:2, h:2, subGridOpts: { children: [{content: 'nest 1'}, {content: 'nest 2'}]}},
+ this.sub3,
+ ];
+ public sidebarContent7: NgGridStackWidget[] = [
+ {selector: 'app-a'},
+ {selector: 'app-b', w:2, maxW: 3},
+ ];
+
+ constructor() {
+ for (let y = 0; y <= 5; y++) this.lazyChildren.push({x:0, y, id:String(y), selector: y%2 ? 'app-b' : 'app-a'});
+
+ // give them content and unique id to make sure we track them during changes below...
+ [...this.items, ...this.subChildren, ...this.sub1, ...this.sub2, ...this.sub0].forEach((w: NgGridStackWidget) => {
+ if (!w.selector && !w.content && !w.subGridOpts) w.content = `item ${ids++}`;
+ });
+ }
+
+ ngOnInit(): void {
+ this.onShow(this.show);
+
+ // TEST
+ // setTimeout(() => {
+ // if (!this.gridComp) return;
+ // this.saveGrid();
+ // // this.clearGrid();
+ // this.delete();
+ // this.delete();
+ // this.loadGrid();
+ // this.delete();
+ // this.delete();
+ // }, 500)
+ }
+
+ public onShow(val: number) {
+ this.show = val;
+
+ // set globally our method to create the right widget type
+ if (val < 3) GridStack.addRemoveCB = undefined;
+ else GridStack.addRemoveCB = gsCreateNgComponents;
+
+ // let the switch take affect then load the starting values (since we sometimes save())
+ setTimeout(() => {
+ let data;
+ switch(val) {
+ case 0: data = this.case0Comp?.items; break;
+ case 1: data = this.case1Comp?.items; break;
+ case 2: data = this.case2Comp?.items; break;
+ case 3: data = this.gridComp?.grid?.save(true, true); break;
+ case 4: data = this.items; break;
+ case 5: data = this.gridOptionsFull; break;
+ case 6: data = this.nestedGridOptions;
+ GridStack.setupDragIn('.sidebar-item', undefined, this.sidebarContent6);
+ break;
+ case 7: data = this.twoGridOpt1;
+ GridStack.setupDragIn('.sidebar-item', undefined, this.sidebarContent7);
+ break;
+ }
+ if (this.origTextEl) this.origTextEl.nativeElement.value = JSON.stringify(data, null, ' ');
+ });
+ if (this.textEl) this.textEl.nativeElement.value = '';
+ }
+
+ /** called whenever items change size/position/etc.. */
+ public onChange(data: nodesCB) {
+ // TODO: update our TEMPLATE list to match ?
+ // NOTE: no need for dynamic as we can always use grid.save() to get latest layout, or grid.engine.nodes
+ console.log('change ', data.nodes.length > 1 ? data.nodes : data.nodes[0]);
+ }
+
+ public onResizeStop(data: elementCB) {
+ console.log('resizestop ', data.el.gridstackNode);
+ }
+
+ /**
+ * TEST dynamic grid operations - uses grid API directly (since we don't track structure that gets out of sync)
+ */
+ public add() {
+ // TODO: BUG the content doesn't appear until widget is moved around (or another created). Need to force
+ // angular detection changes...
+ this.gridComp?.grid?.addWidget({x:3, y:0, w:2, content:`item ${ids}`, id:String(ids++)});
+ }
+ public delete() {
+ let grid = this.gridComp?.grid;
+ if (!grid) return;
+ let 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!);
+ }
+ public modify() {
+ this.gridComp?.grid?.update(this.gridComp?.grid.engine.nodes[0]?.el!, {w:3})
+ }
+ public newLayout() {
+ this.gridComp?.grid?.load([
+ {x:0, y:1, id:'1', minW:1, w:1}, // new size/constrain
+ {x:1, y:1, id:'2'},
+ // {x:2, y:1, id:'3'}, // delete item
+ {x:3, y:0, w:2, content:'new item'}, // new item
+ ]);
+ }
+ public load(layout: GridStackWidget[]) {
+ this.gridComp?.grid?.load(layout);
+ }
+
+ /**
+ * ngFor case: TEST TEMPLATE operations - NOT recommended unless you have no GS creating/re-parenting
+ */
+ public addNgFor() {
+ // new array isn't required as Angular detects changes to content with trackBy:identify()
+ // this.items = [...this.items, { x:3, y:0, w:3, content:`item ${ids}`, id:String(ids++) }];
+ this.items.push({w:2, content:`item ${ids}`, id:String(ids++)});
+ }
+ public deleteNgFor() {
+ this.items.pop();
+ }
+ public modifyNgFor() {
+ // this will not update the DOM nor trigger gridstackItems.changes for GS to auto-update, so set new option of the gridItem instead
+ // this.items[0].w = 3;
+ const gridItem = this.gridComp?.gridstackItems?.get(0);
+ if (gridItem) gridItem.options = {w:3};
+ }
+ public newLayoutNgFor() {
+ this.items = [
+ {x:0, y:1, id:'1', minW:1, w:1}, // new size/constrain
+ {x:1, y:1, id:'2'},
+ // {x:2, y:1, id:'3'}, // delete item
+ {x:3, y:0, w:2, content:'new item'}, // new item
+ ];
+ }
+ public clearGrid() {
+ if (!this.gridComp) return;
+ this.gridComp.grid?.removeAll();
+ }
+ public saveGrid() {
+ this.serializedData = this.gridComp?.grid?.save(false, true) as GridStackOptions || ''; // no content, full options
+ if (this.textEl) this.textEl.nativeElement.value = JSON.stringify(this.serializedData, null, ' ');
+ }
+ public loadGrid() {
+ if (!this.gridComp) return;
+ GridStack.addGrid(this.gridComp.el, this.serializedData);
+ }
+
+ // ngFor TEMPLATE unique node id to have correct match between our items used and GS
+ public identify(index: number, w: GridStackWidget) {
+ return w.id; // or use index if no id is set and you only modify at the end...
+ }
+}
diff --git a/angular/doc/html/media/ngFor.ts b/angular/doc/html/media/ngFor.ts
new file mode 100644
index 000000000..2eeff838c
--- /dev/null
+++ b/angular/doc/html/media/ngFor.ts
@@ -0,0 +1,131 @@
+/**
+ * Example using Angular ngFor to loop through items and create DOM items
+ */
+
+import { Component, AfterViewInit, Input, ViewChildren, QueryList, ElementRef } from '@angular/core';
+import { GridItemHTMLElement, GridStack, GridStackNode, GridStackWidget, Utils } from 'gridstack';
+
+// unique ids sets for each item for correct ngFor updating
+let ids = 1;
+
+@Component({
+ selector: "angular-ng-for-test",
+ template: `
+
ngFor: Example using Angular ngFor to loop through items and create DOM items. This track changes made to the array of items, waits for DOM rendering, then update GS
+
+
+
+
+
+
+
+
item {{ n.id }}
+
+
+ `,
+ // gridstack.min.css and other custom styles should be included in global styles.scss or here
+})
+export class AngularNgForTestComponent implements AfterViewInit {
+ /** list of HTML items that we track to know when the DOM has been updated to make/remove GS widgets */
+ @ViewChildren("gridStackItem") gridstackItems!: QueryList>;
+
+ /** set the items to display. */
+ @Input() public set items(list: GridStackWidget[]) {
+ this._items = list || [];
+ this._items.forEach(w => w.id = w.id || String(ids++)); // make sure a unique id is generated for correct ngFor loop update
+ }
+ public get items(): GridStackWidget[] { return this._items}
+
+ private grid!: GridStack;
+ public _items!: GridStackWidget[];
+
+ constructor() {
+ this.items = [
+ {x: 0, y: 0},
+ {x: 1, y: 1},
+ {x: 2, y: 2},
+ ];
+ }
+
+ // wait until after DOM is ready to init gridstack - can't be ngOnInit() as angular ngFor needs to run first!
+ public ngAfterViewInit() {
+ this.grid = GridStack.init({
+ margin: 5,
+ float: true,
+ })
+ .on('change added', (event: Event, nodes: GridStackNode[]) => this.onChange(nodes));
+
+ // sync initial actual valued rendered (in case init() had to merge conflicts)
+ this.onChange();
+
+ /**
+ * this is called when the list of items changes - get a list of nodes and
+ * update the layout accordingly (which will take care of adding/removing items changed by Angular)
+ */
+ this.gridstackItems.changes.subscribe(() => {
+ const layout: GridStackWidget[] = [];
+ this.gridstackItems.forEach(ref => {
+ const n = ref.nativeElement.gridstackNode || this.grid.makeWidget(ref.nativeElement).gridstackNode;
+ if (n) layout.push(n);
+ });
+ this.grid.load(layout); // efficient that does diffs only
+ })
+ }
+
+ /** Optional: called when given widgets are changed (moved/resized/added) - update our list to match.
+ * Note this is not strictly necessary as demo works without this
+ */
+ public onChange(list = this.grid.engine.nodes) {
+ setTimeout(() => // prevent new 'added' items from ExpressionChangedAfterItHasBeenCheckedError. TODO: find cleaner way to sync outside Angular change detection ?
+ list.forEach(n => {
+ const item = this._items.find(i => i.id === n.id);
+ if (item) Utils.copyPos(item, n);
+ })
+ , 0);
+ }
+
+ /**
+ * CRUD operations
+ */
+ public add() {
+ // new array isn't required as Angular seem to detect changes to content
+ // this.items = [...this.items, { x:3, y:0, w:3, id:String(ids++) }];
+ this.items.push({ x:3, y:0, w:3, id:String(ids++) });
+ }
+
+ public delete() {
+ this.items.pop();
+ }
+
+ public modify() {
+ // this will only update the DOM attr (from the ngFor loop in our template above)
+ // but not trigger gridstackItems.changes for GS to auto-update, so call GS update() instead
+ // this.items[0].w = 2;
+ const n = this.grid.engine.nodes[0];
+ if (n?.el) this.grid.update(n.el, {w:3});
+ }
+
+ public newLayout() {
+ this.items = [ // test updating existing and creating new one
+ {x:0, y:1, id:'1'},
+ {x:1, y:1, id:'2'},
+ // {x:2, y:1, id:3}, // delete item
+ {x:3, y:0, w:3}, // new item
+ ];
+ }
+
+ // ngFor unique node id to have correct match between our items used and GS
+ identify(index: number, w: GridStackWidget) {
+ return w.id;
+ }
+}
diff --git a/angular/doc/html/media/simple.ts b/angular/doc/html/media/simple.ts
new file mode 100644
index 000000000..80df040de
--- /dev/null
+++ b/angular/doc/html/media/simple.ts
@@ -0,0 +1,46 @@
+/**
+ * Simplest Angular Example using GridStack API directly
+ */
+ import { Component, OnInit } from '@angular/core';
+
+ import { GridStack, GridStackWidget } from 'gridstack';
+
+ @Component({
+ selector: 'angular-simple-test',
+ template: `
+
SIMPLEST: angular example using GridStack API directly, so not really using any angular construct per say other than waiting for DOM rendering
+
+
+
+
+ `,
+ // gridstack.min.css and other custom styles should be included in global styles.scss
+ })
+ export class AngularSimpleComponent implements OnInit {
+ public items: GridStackWidget[] = [
+ { x: 0, y: 0, w: 9, h: 6, content: '0' },
+ { x: 9, y: 0, w: 3, h: 3, content: '1' },
+ { x: 9, y: 3, w: 3, h: 3, content: '2' },
+ ];
+ private grid!: GridStack;
+
+ constructor() {}
+
+ // simple div above doesn't require Angular to run, so init gridstack here
+ public ngOnInit() {
+ this.grid = GridStack.init({
+ cellHeight: 70,
+ })
+ .load(this.items); // and load our content directly (will create DOM)
+ }
+
+ public add() {
+ this.grid.addWidget({w: 3, content: 'new content'});
+ }
+ public delete() {
+ this.grid.removeWidget(this.grid.engine.nodes[0].el!);
+ }
+ public change() {
+ this.grid.update(this.grid.engine.nodes[0].el!, {w: 1});
+ }
+ }
diff --git a/angular/doc/html/modules.html b/angular/doc/html/modules.html
new file mode 100644
index 000000000..d412237a5
--- /dev/null
+++ b/angular/doc/html/modules.html
@@ -0,0 +1 @@
+GridStack Angular Library
We now ship an Angular Component
+ to make it supper easy for that framework
+
React wrapper
+
React original examples are shown above, but upcoming and better TS based /react folder (working to make that official and ship it) should be looked at instead.
This example shows v5.x dragging between nested grids (dark yellow) and parent grid (bright yellow.)
+ Use v9.2 sizeToContent:true on first subgrid item parent to grow/shrink as needed, while leaving leaf green items unchanged.
+ Uses v3.1 API to load the entire nested grid from JSON.
+ Nested grids uses v5 column:'auto' to keep items same size during resize.
Create sub-grids (darker background) on the fly, by dragging items completely over others (nest) vs partially (push) using
+ the new v7 API GridStackOptions.subGridDynamic=true
+
This will use the new delay drag&drop option DDDragOpt.pause to tell the gesture difference
+
+
+
+
\ No newline at end of file
diff --git a/demo/react-hooks.html b/demo/react-hooks.html
new file mode 100644
index 000000000..5ceaaa744
--- /dev/null
+++ b/demo/react-hooks.html
@@ -0,0 +1,174 @@
+
+
+
+
+
+
+ Gridstack.js React integration example
+
+
+
+
+
+
+
+
+
+
+
+
Using GridStack.js with React hooks
+
+ As with any virtual DOM based framework, you need to check if React has rendered the DOM (or any updates to it)
+ before you initialize GridStack or call its methods. This example shows how to make rendered
+ components widgets:
+
+
+
Render items, each with a reference
+
Convert each rendered item to a widget using the reference and the
+ makeWidget() function
+
+
+
+
Controlled stack
+
+
+
+
Uncontrolled stack
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo/react.html b/demo/react.html
new file mode 100644
index 000000000..711986963
--- /dev/null
+++ b/demo/react.html
@@ -0,0 +1,104 @@
+
+
+
+
+
+ Gridstack.js React integration example
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/responsive.html b/demo/responsive.html
new file mode 100644
index 000000000..a58f41cfa
--- /dev/null
+++ b/demo/responsive.html
@@ -0,0 +1,65 @@
+
+
+
+ Responsive column
+
+
+
+
+
+
+
Responsive: by column size
+
Using new v10 GridStackOptions.columnOpts: { columnWidth: x }
New 9.x feature that size the items to fit their content height as to not have scroll bars
+ case C: `sizeToContent:false` to turn off.
+ case E: has soft maxsize `sizeToContent:3`, shrinking to smaller content as needed
+ Defaulting to different initial size (see code) to show grow/shrink behavior
Two grids, one floating one not, showing drag&drop from sidebar and between grids.
+ New v10.2: use 'Esc' to cancel any move/resize. Use 'r' to rotate as you drag.
special care is needed to prevent top grid from growing and causing shifts while you are dragging (which is a know issue).
+ You can either set a fix row, or have enough padding on a parent div to allow for an extra row to be created as needed), or....
+ As with any virtual DOM based framework, you need to check if Vue has
+ rendered the DOM (or any updates to it) before you
+ initialize GridStack or call its methods. As a basic example, check this
+ component's mounted hook.
+
+
+ If your app requires more complex render logic than the inline template
+ in `addWidget`, consider
+ makeWidget
+ to let Vue deal with DOM rendering.
+
+ As with any virtual DOM based framework, you need to check if Vue has
+ rendered the DOM (or any updates to it) before you
+ initialize GridStack or call its methods. As a basic example, check this
+ component's mounted hook.
+
+
+ If your app requires more complex render logic than the inline template
+ in `addWidget`, consider
+ makeWidget
+ to let Vue deal with DOM rendering.
+
+ {{ info }}
+
+
+
+
+
diff --git a/demo/vue3js_dynamic-modern-renderCB.html b/demo/vue3js_dynamic-modern-renderCB.html
new file mode 100644
index 000000000..f796ce72a
--- /dev/null
+++ b/demo/vue3js_dynamic-modern-renderCB.html
@@ -0,0 +1,157 @@
+
+
+
+
+
+
+ Vue3 Gridstack: Gridstack DOM with Vue Rendering
+
+
+
+
+
+
+ Back to All Demos
+
Vue3: Gridstack Controls Vue Rendering Grid Items
+
+ Use Vue3 render functions with GridStack.renderCB
+ GridStack handles widget creation and Vue handles rendering the content using the modern (since V11) GridStack.renderCB.
+
+
+ {{ info }}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/demo/vue3js_dynamic-render_grid-item-content.html b/demo/vue3js_dynamic-render_grid-item-content.html
new file mode 100644
index 000000000..441e742ef
--- /dev/null
+++ b/demo/vue3js_dynamic-render_grid-item-content.html
@@ -0,0 +1,161 @@
+
+
+
+
+
+ Vue3 Gridstack: Gridstack DOM with Vue Rendering
+
+
+
+
+
+ Back to All Demos
+
+ Use Vue3 render functions to dynamically render only the grid item content.
+ GridStack is handles when items are added/removed, rendering grid item element, and Vue handles rendering only the item content.
+
This implementation currently does not support nested grid
+
+
+ {{ info }}
+
+
+
+
+
diff --git a/demo/vue3js_dynamic-render_grid-item.html b/demo/vue3js_dynamic-render_grid-item.html
new file mode 100644
index 000000000..2f3567f41
--- /dev/null
+++ b/demo/vue3js_dynamic-render_grid-item.html
@@ -0,0 +1,168 @@
+
+
+
+
+
+ Vue3 Gridstack: Gridstack DOM with Vue Rendering
+
+
+
+
+
+ Back to All Demos
+
Vue3: Gridstack Controls Vue Rendering Grid Item
+
+ Use Vue3 render functions to dynamically render the entire Gridstack item (wrapper and contents)
+ GridStack is handles when items are added/removed, and Vue handles rendering of the entire item in GridStack.addRemoveCB.
+
+ As with any virtual DOM based framework, you need to check if Vue has
+ rendered the DOM (or any updates to it) before you
+ initialize GridStack or call its methods. As a basic example, check this
+ component's mounted hook.
+
+
+ If your app requires more complex render logic than the inline template
+ in `addWidget`, consider
+ makeWidget
+ to let Vue deal with DOM rendering.
+
Abstract base class for all drag & drop implementations.
+Provides common functionality for event handling, enable/disable state,
+and lifecycle management used by draggable, droppable, and resizable implementations.
HTML Native Mouse and Touch Events Drag and Drop functionality.
+
This class provides the main drag & drop implementation for GridStack,
+handling resizing, dragging, and dropping of grid items using native HTML5 events.
+It manages the interaction between different DD components and the grid system.
Global state manager for all Drag & Drop instances.
+
This class maintains shared state across all drag & drop operations,
+ensuring proper coordination between multiple grids and drag/drop elements.
+All properties are static to provide global access throughout the DD system.
Reference to the element currently being resized.
+Helps ignore nested grid resize handles during resize operations.
+
StaticpauseDrag
pauseDrag:number|boolean
Controls drag operation pausing behavior.
+If set to true or a number (milliseconds), dragging placement and collision
+detection will only happen after the user pauses movement.
+This improves performance during rapid mouse movements.
Main gridstack class - you will need to call GridStack.init() first to initialize your grid.
+Note: your grid elements MUST have the following classes for the CSS layout to work:
call to create a grid with the given options, including loading any children from JSON structure. This will call GridStack.init(), then
+grid.load() on any passed children (recursively). Great alternative to calling init() if you want entire grid to come from
+JSON serialized data, including options.
Widget will be always placed even if result height is more than actual grid height.
+You need to use willItFit() before calling addWidget for additional check.
+See also makeWidget(el) for DOM element.
use before calling a bunch of addWidget() to prevent un-necessary relayouts in between (more efficient)
+and get a single event callback. You will see no changes until batchUpdate(false) is called.
Set the number of columns in the grid. Will update existing widgets to conform to new number of columns,
+as well as cache the original layout so you can revert back to previous positions without loss.
specify the type of re-layout that will happen. Options:
+
+
'moveScale' (default): scale widget positions and sizes
+
'move': keep widget sizes, only move positions
+
'scale': keep widget positions, only scale sizes
+
'none': don't change widget positions or sizes
+Note: items will never be outside of the current column boundaries.
+Ignored for column=1 as we always want to vertically stack.
Enables/disables widget moving for all widgets. No-op for static grids.
+Note: locally defined items (with noMove property) still override this setting.
+
Parameters
doEnable: boolean
if true widgets will be movable, if false moving is disabled
Enables/disables widget resizing for all widgets. No-op for static grids.
+Note: locally defined items (with noResize property) still override this setting.
+
Parameters
doEnable: boolean
if true widgets will be resizable, if false resizing is disabled
Returns an array of grid HTML elements (no placeholder) - used to iterate through our children in DOM order.
+This method excludes placeholder elements and returns only actual grid items.
Returns the current margin value as a number (undefined if the 4 sides don't match).
+This only returns a number if all sides have the same margin value.
+
Returns number
the margin value in pixels, or undefined if sides have different values
+
Example
constmargin = grid.getMargin(); if (margin !== undefined) { console.log('Uniform margin:', margin, 'px'); } else { console.log('Margins are different on different sides'); }
+
+
+
getRow
getRow():number
Returns the current number of rows, which will be at least minRow if set.
+The row count is based on the highest positioned widget in the grid.
initializing the HTML element, or selector string, into a grid will return the grid. Calling it again will
+simply return the existing instance (ignore any passed options). There is also an initAll() version that support
+multiple grids initialization at once. Or you can use addGrid() to create the entire grid from JSON.
Checks if the specified rectangular area is empty (no widgets occupy any part of it).
+
Parameters
x: number
the x coordinate (column) of the area to check
+
y: number
the y coordinate (row) of the area to check
+
w: number
the width in columns of the area to check
+
h: number
the height in rows of the area to check
+
Returns boolean
true if the area is completely empty, false if any widget overlaps
+
Example
// Check if a 2x2 area at position (1,1) is empty if (grid.isAreaEmpty(1, 1, 2, 2)) { console.log('Area is available for placement'); }
+
+
+
isIgnoreChangeCB
isIgnoreChangeCB():boolean
Returns true if change callbacks should be ignored due to column change, sizeToContent, loading, etc.
+This is useful for callers who want to implement dirty flag functionality.
+
Returns boolean
true if change callbacks are currently being ignored
+
Example
if (!grid.isIgnoreChangeCB()) { // Process the change event console.log('Grid layout changed'); }
+
Load widgets from a list. This will call update() on each (matching by id) or add/remove widgets that are not there.
+Used to restore a grid layout for a saved layout list (see save()).
boolean (default true) or callback method can be passed to control if and how missing widgets can be added/removed, giving
+the user control of insertion.
If you add elements to your grid by hand (or have some framework creating DOM), you have to tell gridstack afterwards to make them widgets.
+If you want gridstack to add the elements for you, use addWidget() instead.
+Makes the given element a widget and returns it.
// Convert existing elements to widgets grid.makeWidget('#item-1'); // Uses gs-* attributes from DOM grid.makeWidget('#item-2', {w:2, h:1, content:'Hello World'});
// Or pass DOM element directly constelement = document.getElementById('item-3'); grid.makeWidget(element, {x:0, y:1, w:4, h:2});
+
Updates the margins which will set all 4 sides at once - see GridStackOptions.margin for format options.
+Supports CSS string format of 1, 2, or 4 values or a single number.
grid.margin(10); // 10px all sides grid.margin('10px 20px'); // 10px top/bottom, 20px left/right grid.margin('5px 10px 15px 20px'); // Different for each side
+
on( Â Â Â Â name: Â Â Â Â Â Â Â Â |"resize" Â Â Â Â Â Â Â Â |"drag" Â Â Â Â Â Â Â Â |"dragstart" Â Â Â Â Â Â Â Â |"resizestart" Â Â Â Â Â Â Â Â |"resizestop" Â Â Â Â Â Â Â Â |"dragstop", Â Â Â Â callback:GridStackElementHandler, ):GridStack
Register event handler for grid events. You can call this on a single event name, or space separated list.
+
Supported events:
+
+
added: Called when widgets are being added to a grid
+
change: Occurs when widgets change their position/size due to constraints or direct changes
+
disable: Called when grid becomes disabled
+
dragstart: Called when grid item starts being dragged
+
drag: Called while grid item is being dragged (for each new row/column value)
+
dragstop: Called after user is done moving the item, with updated DOM attributes
+
dropped: Called when an item has been dropped and accepted over a grid
+
enable: Called when grid becomes enabled
+
removed: Called when items are being removed from the grid
+
resizestart: Called before user starts resizing an item
+
resize: Called while grid item is being resized (for each new row/column value)
+
resizestop: Called after user is done resizing the item, with updated DOM attributes
called when we are being resized - check if the one Column Mode needs to be turned on/off
+and remember the prev columns we used, or get our count from parent, as well as check for cellHeight==='auto' (square)
+or sizeToContent gridItem options.
call this method to register your engine instead of the default one.
+See instead GridStackOptions.engineClass if you only need to
+replace just one instance.
called when an item was converted into a nested grid to accommodate a dragged over item, but then item leaves - return back
+to the original grid-item. Also called to remove empty sub-grids when last item is dragged out (since re-creating is simple)
Updates widget height to match the content height to avoid vertical scrollbars or dead space.
+This automatically adjusts the widget height based on its content size.
+
Note: This assumes only 1 child under resizeToContentParent='.grid-stack-item-content'
+(sized to gridItem minus padding) that represents the entire content size.
Rotate widgets by swapping their width and height. This is typically called when the user presses 'r' during dragging.
+The rotation swaps the w/h dimensions and adjusts min/max constraints accordingly.
saves the current layout returning a list of widgets for serialization which might include any nested grids.
+
Parameters
saveContent: boolean = true
if true (default) the latest html inside .grid-stack-content will be saved to GridStackWidget.content field, else it will
+be removed.
+
saveGridOpt: boolean = false
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.
Toggle the grid static state, which permanently removes/add Drag&Drop support, unlike disable()/enable() that just turns it off/on.
+Also toggle the grid-stack-static class.
setupDragIn( Â Â Â Â dragIn?:string|HTMLElement[], Â Â Â Â dragInOptions?:DDDragOpt, Â Â Â Â widgets?:GridStackWidget[], Â Â Â Â root?:Document|HTMLElement, ):void
call to setup dragging in from the outside (say toolbar), by specifying the class selection and options.
+Called during GridStack.init() as options, but can also be called directly (last param are used) in case the toolbar
+is dynamically create and needs to be set later.
+
Parameters
OptionaldragIn: string|HTMLElement[]
string selector (ex: '.sidebar-item') or list of dom elements
Updates widget position/size and other info. This is used to change widget properties after creation.
+Can update position, size, content, and other widget properties.
+
Note: If you need to call this on all nodes, use load() instead which will update what changed.
+Setting the same x,y for multiple items will be indeterministic and likely unwanted.
callback method use when new items|grids needs to be created or deleted, instead of the default
+item:
w.content
+grid:
grid content...
+add = true: the returned DOM element will then be converted to a GridItemHTMLElement using makeWidget()|GridStack:init().
+add = false: the item will be removed from DOM (if not already done)
+grid = true|false for grid vs grid-items
+
animationDelay
animationDelay:number = ...
time to wait for animation (if enabled) to be done so content sizing can happen
callback to create the content of widgets so the app can control how to store and restore it
+By default this lib will do 'el.textContent = w.content' forcing text only support for avoiding potential XSS issues.
Defines the GridStack engine that handles all grid layout calculations and node positioning.
+This is the core engine that performs grid manipulation without any DOM operations.
+
The engine manages:
+
+
Node positioning and collision detection
+
Layout algorithms (compact, float, etc.)
+
Grid resizing and column changes
+
Widget movement and resizing logic
+
+
NOTE: Values should not be modified directly - use the main GridStack API instead
+to ensure proper DOM updates and event triggers.
// Start batch mode for multiple operations engine.batchUpdate(true); engine.addNode(node1); engine.addNode(node2); engine.batchUpdate(false); // Apply all changes at once
+
Part 2 of preparing a node to fit inside the grid - validates and fixes coordinates and dimensions.
+This ensures the node fits within grid boundaries and respects min/max constraints.
Prepare and validate a node's coordinates and values for the current grid.
+This ensures the node has valid position, size, and properties before being added to the grid.
saves a copy of the largest column layout (eg 12 even when rendering oneColumnMode) so we don't loose orig layout,
+returning a list of widgets for serialization
Attempt to swap the positions of two nodes if they meet swapping criteria.
+Nodes can swap if they are the same size or in the same column/row, not locked, and touching.
Collection of utility methods used throughout GridStack.
+These are general-purpose helper functions for DOM manipulation,
+positioning calculations, object operations, and more.
Recursive clone version that returns a full copy, checking for nested objects and arrays ONLY.
+Note: this will use as-is any key starting with double __ (and not copy inside) some lib have circular dependencies.
interfaceDDDragOpt{ Â Â Â Â appendTo?:string; Â Â Â Â cancel?:string; Â Â Â Â drag?:(event:Event,ui:DDUIData)=>void; Â Â Â Â handle?:string; Â Â Â Â helper?:"clone"| ((el:HTMLElement)=>HTMLElement); Â Â Â Â pause?:number|boolean; Â Â Â Â scroll?:boolean; Â Â Â Â start?:(event:Event,ui:DDUIData)=>void; Â Â Â Â stop?:(event:Event)=>void; }
prevents dragging from starting on specified elements, listed as comma separated selectors (eg: '.no-drag'). default built in is 'input,textarea,button,select,option'
interfaceDDDroppableOpt{ Â Â Â Â accept?:string| ((el:HTMLElement)=>boolean); Â Â Â Â drop?:(event:DragEvent,ui:DDUIData)=>void; Â Â Â Â out?:(event:DragEvent,ui:DDUIData)=>void; Â Â Â Â over?:(event:DragEvent,ui:DDUIData)=>void; }
do resize handle hide by default until mouse over ? - default: true on desktop, false on mobile
+
Optionalhandles
handles?:string
sides where you can resize from (ex: 'e, se, s, sw, w') - default 'se' (south-east)
+Note: it is not recommended to resize from the top sides as weird side effect may occur.
value for gs-id stored on the widget (default?: undefined)
+
OptionallazyLoad
lazyLoad?:boolean
true when widgets are only created when they scroll into view (visible)
+
Optionallocked
locked?:boolean
prevents being pushed by other widgets or api (default?: undefined = un-constrained), which is different from noMove (user action only)
+
OptionalmaxH
maxH?:number
maximum height allowed during resize/creation (default?: undefined = un-constrained)
+
OptionalmaxW
maxW?:number
maximum width allowed during resize/creation (default?: undefined = un-constrained)
+
OptionalminH
minH?:number
minimum height allowed during resize/creation (default?: undefined = un-constrained)
+
OptionalminW
minW?:number
minimum width allowed during resize/creation (default?: undefined = un-constrained)
+
OptionalnoMove
noMove?:boolean
prevents direct moving by the user (default?: undefined = un-constrained)
+
OptionalnoResize
noResize?:boolean
prevent direct resizing by the user (default?: undefined = un-constrained)
+
OptionalresizeToContentParent
resizeToContentParent?:string
local override of GridStack.resizeToContentParent that specify the class to use for the parent (actual) vs child (wanted) height
+
OptionalsizeToContent
sizeToContent?:number|boolean
local (vs grid) override - see GridStackOptions.
+Note: This also allow you to set a maximum h value (but user changeable during normal resizing) to prevent unlimited content from taking too much space (get scrollbar)
possible values (default: mobile) - does not apply to non-resizable widgets
+false the resizing handles are only shown while hovering over a widget
+true the resizing handles are always shown
+'mobile' if running on a mobile device, default to true (since there is no hovering per say), else false.
+See example
+
Optionalanimate
animate?:boolean
turns animation on (default?: true)
+
Optionalauto
auto?:boolean
if false gridstack will not initialize existing items (default?: true)
a string (ex: '100px', '10em', '10rem'): CSS length value
+
0: library will not generate styles for rows (define your own CSS)
+
'auto': height calculated for square cells (width / column) and updated live on window resize
+
'initial': similar to 'auto' but stays fixed size during window resizing
+
+
Note: % values don't work correctly - see demo/cell-height.html
+
Example
// Fixed 100px height cellHeight: 100
// CSS units cellHeight: '5rem' cellHeight: '100px'
// Auto-sizing for square cells cellHeight: 'auto'
// No CSS generation (custom styles) cellHeight: 0
+
+
+
OptionalcellHeightThrottle
cellHeightThrottle?:number
throttle time delay (in ms) used when cellHeight='auto' to improve performance vs usability (default?: 100).
+A value of 0 will make it instant at a cost of re-creating the CSS file at ever window resize event!
+
OptionalcellHeightUnit
cellHeightUnit?:string
(internal) unit for cellHeight (default? 'px') which is set when a string cellHeight with a unit is passed (ex: '10rem')
list of children item to create when calling load() or addGrid()
+
Optionalclass
class?:string
additional class on top of '.grid-stack' (which is required for our CSS) to differentiate this instance.
+Note: only used by addGrid(), else your element should have the needed class
+
Optionalcolumn
column?:number|"auto"
number of columns (default?: 12). Note: IF you change this, CSS also have to change. See https://github.com/gridstack/gridstack.js#change-grid-columns.
+Note: for nested grids, it is recommended to use 'auto' which will always match the container grid-item current width (in column) to keep inside and outside
+items always the same. flag is NOT supported for regular non-nested grids.
gap between grid item and content (default?: 10). This will set all 4 sides and support the CSS formats below
+an integer (px)
+a string with possible units (ex: '2em', '20px', '2rem')
+string with space separated values (ex: '5px 10px 0 20px' for all 4 sides, or '5em 10em' for top/bottom and left/right pairs like CSS).
+Note: all sides must have same units (last one wins, default px)
OLD way to optionally set each side - use margin: '5px 10px 0 20px' instead. Used internally to store each side.
+
OptionalmarginUnit
marginUnit?:string
(internal) unit for margin (default? 'px') set when margin is set as string with unit (ex: 2rem')
+
OptionalmaxRow
maxRow?:number
maximum rows amount. Default? is 0 which means no maximum rows
+
OptionalminRow
minRow?:number
minimum rows amount which is handy to prevent grid from collapsing when empty. Default is 0.
+When no set the min-height CSS attribute on the grid div (in pixels) can be used, which will round to the closest row.
+
Optionalnonce
nonce?:string
If you are using a nonce-based Content Security Policy, pass your nonce here and
+GridStack will add it to the
Base widget class for GridStack Angular integration.
+