@@ -16,9 +16,23 @@ <h1>Nested grids demo</h1>
1616 Use v9.2 < b > sizeToContent:true</ b > on first subgrid item parent to grow/shrink as needed, while leaving leaf green items unchanged.< br >
1717 Uses v3.1 API to load the entire nested grid from JSON.< br >
1818 Nested grids uses v5 < b > column:'auto'</ b > to keep items same size during resize.</ p >
19- < a class ="btn btn-primary " onClick ="addNested() " href ="# "> Add Widget</ a >
19+ < div style ="display: flex; flex-direction: row; gap: 5px; ">
20+ < a class ="btn btn-primary " onClick ="addWidget() " href ="# "> Add Widget</ a >
2021 < a class ="btn btn-primary " onClick ="addNewWidget('.sub1') " href ="# "> Add Widget Grid1</ a >
2122 < a class ="btn btn-primary " onClick ="addNewWidget('.sub2') " href ="# "> Add Widget Grid2</ a >
23+ < a class ="btn btn-primary " onClick ="addNested() " href ="# "> Add Widget With Nested Content</ a >
24+ < div style ="width: 100px; ">
25+ < div
26+ class ="gridstack-add-widget grid-stack-item ui-draggable "
27+ gs-h ="2 "
28+ gs-w ="2 "
29+ data-gs-drop ="true "
30+ >
31+ < div class ="grid-stack-item-content "> drop a nested widget</ div >
32+ </ div >
33+ </ div >
34+ </ div >
35+ < br />
2236 < span > entire save/re-create:</ span >
2337 < a class ="btn btn-primary " onClick ="save() " href ="# "> Save</ a >
2438 < a class ="btn btn-primary " onClick ="destroy() " href ="# "> Destroy</ a >
@@ -55,6 +69,10 @@ <h1>Nested grids demo</h1>
5569 { x :5 , y :0 , w :3 , h :4 , subGridOpts : { children : sub2 , id :'sub2_grid' , class : 'sub2' , ...subOptions } } ,
5670 ]
5771 } ;
72+ // setup drag drop behavior
73+ GridStack . setupDragIn ( '.gridstack-add-widget' , {
74+ helper : 'clone' ,
75+ } ) ;
5876
5977 // create and load it all from JSON above
6078 let grid = GridStack . addGrid ( document . querySelector ( '.container-fluid' ) , options ) ;
@@ -66,10 +84,15 @@ <h1>Nested grids demo</h1>
6684 addEvents ( grid , grid . opts . id ) ;
6785 } )
6886
69- function addNested ( ) {
87+ function addWidget ( ) {
7088 grid . addWidget ( { x :0 , y :100 , content :"new item" } ) ;
7189 }
7290
91+ function addNested ( ) {
92+ let subAddNested = [ { w :1 , h :1 , content : 'hello' } , { w :1 , h :1 , y : 1 , content : 'world' } ] ;
93+ grid . addWidget ( { x :0 , y :100 , w :1 , h :2 , sizeToContent : true , subGridOpts : { children : subAddNested , id :`grid-${ Math . random ( ) } ` , class : 'sub1' , ...subOptions } } ) ;
94+ }
95+
7396 function addNewWidget ( selector ) {
7497 let subGrid = document . querySelector ( selector ) . gridstack ;
7598 let node = {
@@ -83,13 +106,62 @@ <h1>Nested grids demo</h1>
83106 return false ;
84107 } ;
85108
109+ //--- Drag and Drop Nested widget logic
110+
111+ // the definition of the new node to add on drag and drop
112+ let nodeToAdd = {
113+ w : 2 ,
114+ h : 2 ,
115+ ...subOptions ,
116+ subGridOpts : subOptions ,
117+ children : [
118+ {
119+ w : 1 ,
120+ h : 1 ,
121+ content : '1'
122+ } ,
123+ {
124+ w : 1 ,
125+ h : 1 ,
126+ content : '2'
127+ } ,
128+ ] ,
129+ }
130+
131+ // listener on add event: everytime a widget with data-gs-drop is dropped, a new subgrid is created
132+ function addEventHandler ( event , gridNodes ) {
133+ gridNodes . forEach ( ( node ) => {
134+ // check if the added event was triggered by a drop
135+ let isAddedByDrop = Boolean ( node . el . getAttribute ( 'data-gs-drop' ) ) ;
136+ if ( isAddedByDrop ) {
137+ // clear the content of the node before applying the content of our widget to add
138+ node . el . querySelector ( '.grid-stack-item-content' ) . innerHTML = '' ;
139+ // create a nested widget
140+ let subgrid = node . grid . makeSubGrid ( node . el , nodeToAdd , undefined , false ) ;
141+ // add a listener to the subgrid to allow widgets to be added into this newly created nested widget
142+ subgrid . on ( 'added' , addEventHandler ) ;
143+ }
144+ // remove the data-gs-drop attribute to clean the node and avoid adding a new subgrid when a widget is moved between nested grids
145+ node . el . removeAttribute ( 'data-gs-drop' )
146+ } ) ;
147+ }
148+ // add listener to the main grid
149+ grid . on ( 'added' , addEventHandler ) ;
150+ // add listener to the already existing nested grids
151+ document . querySelectorAll ( '.grid-stack-nested' ) . forEach ( ( subGrid ) => {
152+ subGrid . gridstack . on ( 'added' , addEventHandler ) ;
153+ } ) ;
154+
155+ //--- end of Drag and Drop Nested widget logic
156+
86157 function save ( content = true , full = true ) {
87158 options = grid . save ( content , full ) ;
88159 console . log ( options ) ;
89160 // console.log(JSON.stringify(options));
90161 }
91162 function destroy ( full = true ) {
92163 if ( full ) {
164+ grid . off ( 'added' ) ;
93165 grid . destroy ( ) ;
94166 grid = undefined ;
95167 } else {
@@ -99,11 +171,11 @@ <h1>Nested grids demo</h1>
99171 function load ( full = true ) {
100172 if ( full ) {
101173 grid = GridStack . addGrid ( document . querySelector ( '.container-fluid' ) , options ) ;
174+ grid . on ( 'added' , addEventHandler ) ;
102175 } else {
103176 grid . load ( options ) ;
104177 }
105178 }
106-
107179 </ script >
108180</ body >
109181</ html >
0 commit comments