Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 546a1a7

Browse files
authored
Merge pull request gridstack#2813 from adumesny/master
big sidepanel drag&drop helper rewrite
2 parents edbd2d9 + 93ccb6f commit 546a1a7

File tree

11 files changed

+173
-175
lines changed

11 files changed

+173
-175
lines changed

README.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,9 +463,12 @@ breaking change:
463463
464464
## Migrating to v11
465465
466-
All instances of `el.innerHTML = 'some content'` have been removed for security reason as it opens up some potential for accidental XSS. we now create DIV directly or use `el.textContent = w.content` for `GridStackWidget.content` field.
466+
* All instances of `el.innerHTML = 'some content'` have been removed for security reason as it opens up some potential for accidental XSS.
467+
468+
* Side panel drag&drop complete rewrite.
469+
470+
**breaking change:**
467471
468-
breaking change:
469472
* if you code relies on `GridStackWidget.content` with real HTML (like a few demos) it is up to you to do this:
470473
```ts
471474
// NOTE: REAL apps would sanitize-html or DOMPurify before blinding setting innerHTML. see #2736
@@ -476,6 +479,13 @@ GridStack.renderCB = function(el, w) {
476479
* V11 add new `GridStack.renderCB` that is called for you to create the widget content (entire GridStackWidget is passed so you can use id or some other field as logic) while GS creates the 2 needed parent divs + classes, unlike `GridStack.addRemoveCB` which doesn't create anything for you. Both can be handy for Angular/React/Vue frameworks.
477480
* `addWidget(w: GridStackWidget)` is now the only supported format, no more string content passing. You will need to create content yourself (`Util.createWidgetDivs()` can be used to create parent divs) then call `makeWidget(el)` instead.
478481
482+
* BIG overall to how sidepanel helper drag&drop is done:
483+
1. `clone()` helper is now passed full HTML element dragged, not an event on `grid-stack-item-content` so can clone or set attr at the top.
484+
2. use any class/structure you want for side panel items (see two.html)
485+
3. `GridStack.setupDragIn()` now support associating a `GridStackWidget` for each sidepanel that will be used to define what to create on drop!
486+
4. if no `GridStackWidget` is defined, the helper will now be inserted as is, and NOT original sidepanel item.
487+
5. support DOM gs- attr as well as gridstacknode JSON (see two.html) alternatives.
488+
479489
# jQuery Application
480490
481491
This is **old and no longer apply to v6+**. You'll need to use v5.1.1 and before

demo/demo.css

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,29 @@ h1 {
2323
margin-bottom: .5rem;
2424
}
2525

26+
.sidebar {
27+
background: rgb(215, 243, 215);
28+
padding: 25px 0;
29+
height: 100px;
30+
text-align: center;
31+
}
32+
.sidebar > .grid-stack-item,
33+
.sidebar-item {
34+
width: 100px;
35+
height: 50px;
36+
border: 2px dashed green;
37+
text-align: center;
38+
line-height: 35px;
39+
background: rgb(192, 231, 192);
40+
cursor: default;
41+
display: inline-block;
42+
}
43+
2644
.grid-stack {
2745
background: #FAFAD2;
2846
}
2947

48+
.sidebar > .grid-stack-item,
3049
.grid-stack-item-content {
3150
text-align: center;
3251
background-color: #18bc9c;
@@ -39,25 +58,6 @@ h1 {
3958
height: 100px;
4059
background: rgba(255, 0, 0, 0.1) center center url(data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjY0cHgiIGhlaWdodD0iNjRweCIgdmlld0JveD0iMCAwIDQzOC41MjkgNDM4LjUyOSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDM4LjUyOSA0MzguNTI5OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPGc+CgkJPHBhdGggZD0iTTQxNy42ODksNzUuNjU0Yy0xLjcxMS0xLjcwOS0zLjkwMS0yLjU2OC02LjU2My0yLjU2OGgtODguMjI0TDMwMi45MTcsMjUuNDFjLTIuODU0LTcuMDQ0LTcuOTk0LTEzLjA0LTE1LjQxMy0xNy45ODkgICAgQzI4MC4wNzgsMi40NzMsMjcyLjU1NiwwLDI2NC45NDUsMGgtOTEuMzYzYy03LjYxMSwwLTE1LjEzMSwyLjQ3My0yMi41NTQsNy40MjFjLTcuNDI0LDQuOTQ5LTEyLjU2MywxMC45NDQtMTUuNDE5LDE3Ljk4OSAgICBsLTE5Ljk4NSw0Ny42NzZoLTg4LjIyYy0yLjY2NywwLTQuODUzLDAuODU5LTYuNTY3LDIuNTY4Yy0xLjcwOSwxLjcxMy0yLjU2OCwzLjkwMy0yLjU2OCw2LjU2N3YxOC4yNzQgICAgYzAsMi42NjQsMC44NTUsNC44NTQsMi41NjgsNi41NjRjMS43MTQsMS43MTIsMy45MDQsMi41NjgsNi41NjcsMi41NjhoMjcuNDA2djI3MS44YzAsMTUuODAzLDQuNDczLDI5LjI2NiwxMy40MTgsNDAuMzk4ICAgIGM4Ljk0NywxMS4xMzksMTkuNzAxLDE2LjcwMywzMi4yNjQsMTYuNzAzaDIzNy41NDJjMTIuNTY2LDAsMjMuMzE5LTUuNzU2LDMyLjI2NS0xNy4yNjhjOC45NDUtMTEuNTIsMTMuNDE1LTI1LjE3NCwxMy40MTUtNDAuOTcxICAgIFYxMDkuNjI3aDI3LjQxMWMyLjY2MiwwLDQuODUzLTAuODU2LDYuNTYzLTIuNTY4YzEuNzA4LTEuNzA5LDIuNTctMy45LDIuNTctNi41NjRWODIuMjIxICAgIEM0MjAuMjYsNzkuNTU3LDQxOS4zOTcsNzcuMzY3LDQxNy42ODksNzUuNjU0eiBNMTY5LjMwMSwzOS42NzhjMS4zMzEtMS43MTIsMi45NS0yLjc2Miw0Ljg1My0zLjE0aDkwLjUwNCAgICBjMS45MDMsMC4zODEsMy41MjUsMS40Myw0Ljg1NCwzLjE0bDEzLjcwOSwzMy40MDRIMTU1LjMxMUwxNjkuMzAxLDM5LjY3OHogTTM0Ny4xNzMsMzgwLjI5MWMwLDQuMTg2LTAuNjY0LDguMDQyLTEuOTk5LDExLjU2MSAgICBjLTEuMzM0LDMuNTE4LTIuNzE3LDYuMDg4LTQuMTQxLDcuNzA2Yy0xLjQzMSwxLjYyMi0yLjQyMywyLjQyNy0yLjk5OCwyLjQyN0gxMDAuNDkzYy0wLjU3MSwwLTEuNTY1LTAuODA1LTIuOTk2LTIuNDI3ICAgIGMtMS40MjktMS42MTgtMi44MS00LjE4OC00LjE0My03LjcwNmMtMS4zMzEtMy41MTktMS45OTctNy4zNzktMS45OTctMTEuNTYxVjEwOS42MjdoMjU1LjgxNVYzODAuMjkxeiIgZmlsbD0iI2ZmOWNhZSIvPgoJCTxwYXRoIGQ9Ik0xMzcuMDQsMzQ3LjE3MmgxOC4yNzFjMi42NjcsMCw0Ljg1OC0wLjg1NSw2LjU2Ny0yLjU2N2MxLjcwOS0xLjcxOCwyLjU2OC0zLjkwMSwyLjU2OC02LjU3VjE3My41ODEgICAgYzAtMi42NjMtMC44NTktNC44NTMtMi41NjgtNi41NjdjLTEuNzE0LTEuNzA5LTMuODk5LTIuNTY1LTYuNTY3LTIuNTY1SDEzNy4wNGMtMi42NjcsMC00Ljg1NCwwLjg1NS02LjU2NywyLjU2NSAgICBjLTEuNzExLDEuNzE0LTIuNTY4LDMuOTA0LTIuNTY4LDYuNTY3djE2NC40NTRjMCwyLjY2OSwwLjg1NCw0Ljg1MywyLjU2OCw2LjU3QzEzMi4xODYsMzQ2LjMxNiwxMzQuMzczLDM0Ny4xNzIsMTM3LjA0LDM0Ny4xNzJ6IiBmaWxsPSIjZmY5Y2FlIi8+CgkJPHBhdGggZD0iTTIxMC4xMjksMzQ3LjE3MmgxOC4yNzFjMi42NjYsMCw0Ljg1Ni0wLjg1NSw2LjU2NC0yLjU2N2MxLjcxOC0xLjcxOCwyLjU2OS0zLjkwMSwyLjU2OS02LjU3VjE3My41ODEgICAgYzAtMi42NjMtMC44NTItNC44NTMtMi41NjktNi41NjdjLTEuNzA4LTEuNzA5LTMuODk4LTIuNTY1LTYuNTY0LTIuNTY1aC0xOC4yNzFjLTIuNjY0LDAtNC44NTQsMC44NTUtNi41NjcsMi41NjUgICAgYy0xLjcxNCwxLjcxNC0yLjU2OCwzLjkwNC0yLjU2OCw2LjU2N3YxNjQuNDU0YzAsMi42NjksMC44NTQsNC44NTMsMi41NjgsNi41N0MyMDUuMjc0LDM0Ni4zMTYsMjA3LjQ2NSwzNDcuMTcyLDIxMC4xMjksMzQ3LjE3MnogICAgIiBmaWxsPSIjZmY5Y2FlIi8+CgkJPHBhdGggZD0iTTI4My4yMiwzNDcuMTcyaDE4LjI2OGMyLjY2OSwwLDQuODU5LTAuODU1LDYuNTctMi41NjdjMS43MTEtMS43MTgsMi41NjItMy45MDEsMi41NjItNi41N1YxNzMuNTgxICAgIGMwLTIuNjYzLTAuODUyLTQuODUzLTIuNTYyLTYuNTY3Yy0xLjcxMS0xLjcwOS0zLjkwMS0yLjU2NS02LjU3LTIuNTY1SDI4My4yMmMtMi42NywwLTQuODUzLDAuODU1LTYuNTcxLDIuNTY1ICAgIGMtMS43MTEsMS43MTQtMi41NjYsMy45MDQtMi41NjYsNi41Njd2MTY0LjQ1NGMwLDIuNjY5LDAuODU1LDQuODUzLDIuNTY2LDYuNTdDMjc4LjM2NywzNDYuMzE2LDI4MC41NSwzNDcuMTcyLDI4My4yMiwzNDcuMTcyeiIgZmlsbD0iI2ZmOWNhZSIvPgoJPC9nPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+Cjwvc3ZnPgo=) no-repeat;
4160
}
42-
.sidebar {
43-
background: rgba(0, 255, 0, 0.1);
44-
padding: 25px 0;
45-
height: 100px;
46-
text-align: center;
47-
}
48-
.sidebar .grid-stack-item {
49-
width: 120px;
50-
height: 50px;
51-
border: 2px dashed green;
52-
text-align: center;
53-
line-height: 35px;
54-
background: rgba(0, 255, 0, 0.1);
55-
cursor: default;
56-
display: inline-block;
57-
}
58-
.sidebar .grid-stack-item .grid-stack-item-content {
59-
background: none;
60-
}
6161

6262
/* make nested grid have slightly darker bg take almost all space (need some to tell them apart) so items inside can have similar to external size+margin */
6363
.grid-stack > .grid-stack-item.grid-stack-sub-grid > .grid-stack-item-content {

demo/nested.html

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@ <h1>Nested grids demo</h1>
7878
})
7979

8080
// setup drag drop behavior
81-
GridStack.setupDragIn('.sidebar .grid-stack-item', { appendTo: 'body', helper: 'clone' });
81+
let sidebarContent = [
82+
{ w:2, h:2, subGridOpts: { children: [{content: 'nest 1'}, {content: 'nest 2'}]}}
83+
];
84+
GridStack.setupDragIn('.sidebar .grid-stack-item', undefined, sidebarContent);
8285

8386
function addWidget() {
8487
grid.addWidget({x:0, y:100, content:"new item"});
@@ -113,15 +116,7 @@ <h1>Nested grids demo</h1>
113116
n.el.querySelector('.grid-stack-item-content').innerHTML = '';
114117
let nodeToAdd = { children: [{content: 'nest 1'}, {content: 'nest 2'}]};
115118
let subgrid = n.grid.makeSubGrid(n.el, nodeToAdd, undefined, false);
116-
117-
// add a listener to the subgrid to allow widgets to be added into this newly created nested widget
118-
subgrid.on('dropped', droppedHandler);
119119
}
120-
// add listener to the main grid and subgrids
121-
grid.on('dropped', droppedHandler);
122-
document.querySelectorAll('.grid-stack-nested').forEach((subGrid) => {
123-
subGrid.gridstack.on('dropped', droppedHandler);
124-
});
125120

126121
//--- end of Drag and Drop Nested widget logic
127122

@@ -142,7 +137,6 @@ <h1>Nested grids demo</h1>
142137
function load(full = true) {
143138
if (full) {
144139
grid = GridStack.addGrid(document.querySelector('.container-fluid'), options);
145-
grid.on('dropped', droppedHandler);
146140
} else {
147141
grid.load(options);
148142
}

demo/two.html

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,26 @@ <h1>Two grids demo</h1>
2222
<br>New v10.2: use 'Esc' to cancel any move/resize. Use 'r' to rotate as you drag.</p>
2323

2424
<div class="row">
25-
<div class="col-md-3">
25+
<div class="col-md-8">
2626
<div class="sidebar">
27-
<!-- will size to match content -->
28-
<div class="grid-stack-item">
29-
<div class="grid-stack-item-content">Drag me</div>
27+
<!-- will size to match content. Also see sidebarContent -->
28+
<div class="sidebar-item">Drag me</div>
29+
<!-- constrained in code using GridStackWidget[] sidebarContent -->
30+
<div class="sidebar-item">2x1, max=3</div>
31+
<!-- DOM JSON spelling GridStackWidget. NOTE: require content:'xyz' to work and RenderCB() to render -->
32+
<div class="sidebar-item" gridstacknode='{"w":3, "content":"w:3"}'>w:3</div>
33+
<!-- DOM id handled by myClone() case -->
34+
<div class="sidebar-item" gs-id="manual">gs-id case</div>
35+
<!-- DOM require proper GS format to be dropped as is without GridStackWidget above -->
36+
<div class="grid-stack-item" gs-w="3">
37+
<div class="grid-stack-item-content">DOM gs-w:3</div>
3038
</div>
31-
<!-- manually force a drop size of 2x1 -->
32-
<div class="grid-stack-item" gs-w="2" gs-h="1" gs-max-w="3">
33-
<div class="grid-stack-item-content">2x1, max=3</div>
39+
<div class="grid-stack-item" gridstacknode='{"w":2}'>
40+
<div class="grid-stack-item-content">DOM w:2</div>
3441
</div>
3542
</div>
3643
</div>
37-
<div class="col-md-9">
44+
<div class="col-md-4">
3845
<div class="trash" id="trash">
3946
</div>
4047
</div>
@@ -55,41 +62,54 @@ <h1>Two grids demo</h1>
5562
</div>
5663
<script src="events.js"></script>
5764
<script type="text/javascript">
65+
let items = [
66+
{x: 0, y: 0, w: 2, h: 2},
67+
{x: 1, y: 1, h: 2}, // intentional overlap to test collision on load
68+
{x: 1, y: 1}, // intentional overlap to test collision on load
69+
{x: 3, y: 1},
70+
{x: 2, y: 3, w: 3, maxW: 3, content: 'has maxW=3'},
71+
{x: 2, y: 5}
72+
];
73+
items.forEach((item, i) => item.content = item.content || String(i));
74+
75+
// sidebar content to create when we get dropped, instead of inserting the clone version
76+
let sidebarContent = [
77+
{content: 'dropped'},
78+
{content: 'max=3', w:2, h:1, maxW: 3},
79+
];
80+
5881
let options = {
5982
column: 6,
6083
minRow: 1, // don't collapse when empty
6184
cellHeight: 70,
6285
float: true,
6386
removable: '.trash', // true or drag-out delete class
87+
children: items,
6488
// itemClass: 'with-lines', // test a custom additional class #2110
6589
acceptWidgets: function(el) { return true } // function example, but can also be: true | false | '.someClass' value
6690
};
6791
let grids = GridStack.initAll(options);
6892
grids[1].float(false);
6993

70-
// new 4.x static method instead of setting up options on every grid (never been per grid really)
71-
GridStack.setupDragIn('.sidebar .grid-stack-item', { appendTo: 'body', helper: myClone });
94+
// new v4 static method instead of setting up options on every grid (never been per grid really)
95+
// new v11 method takes GridStackWidget[] to specify what to create on drop
96+
// NOTE: helper:'clone' is default and typically used but have custom logic here to showcase
97+
// NOTE2: handle not set to drag entire self.
98+
GridStack.setupDragIn('.sidebar-item, .sidebar>.grid-stack-item', { helper: myClone }, sidebarContent);
7299
// GridStack.setupDragIn(); // second call will now work (cache last values)
73100

74-
let items = [
75-
{x: 0, y: 0, w: 2, h: 2},
76-
{x: 1, y: 1, h: 2}, // intentional overlap to test collision on load
77-
{x: 1, y: 1}, // intentional overlap to test collision on load
78-
{x: 3, y: 1},
79-
{x: 2, y: 3, w: 3, maxW: 3, content: 'has maxW=3'},
80-
{x: 2, y: 5}
81-
];
82-
items.forEach((item, i) => item.content = item.content || String(i));
83-
84101
grids.forEach(function (grid, i) {
85102
addEvents(grid, i);
86-
grid.load(items);
87103
});
88104

89-
// decide what the dropped item will be - for now just a clone but can be anything
90-
function myClone(event) {
91-
const el = event.target.cloneNode(true);
92-
el.setAttribute('gs-id', 'foo'); // TEST why clone element is not used directly on drop #2231
105+
// clone the sidepanel item so we drag a copy, and in some case ('manual') create the final widget, else sidebarContent will be used.
106+
function myClone(el) {
107+
if (el.getAttribute('gs-id') === 'manual') {
108+
return GridStack.Utils.createWidgetDivs(undefined, {w:2, content:'manual'}); // RenderCB() will be called
109+
}
110+
el = el.cloneNode(true);
111+
// el.setAttribute('gs-id', 'foo'); // help debug #2231
112+
// el.innerHTML = 'cloned'; // help debug
93113
return el;
94114
}
95115

doc/CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ Change log
116116

117117
## 11.0.0 (TBD)
118118
* fix: [#2736](https://github.com/gridstack/gridstack.js/bug/2736) safe practices around GridStackWidget.content no longer setting innerHTML
119+
* fix: [#2231](https://github.com/gridstack/gridstack.js/bug/2231),[#1840](https://github.com/gridstack/gridstack.js/bug/1840),[#2354](https://github.com/gridstack/gridstack.js/bug/2354)
120+
big overall to how we do sidepanel drag&drop helper. see release notes.
119121

120122
## 10.3.1 (2024-07-21)
121123
* fix: [#2734](https://github.com/gridstack/gridstack.js/bug/2734) rotate() JS error

doc/README.md

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ gridstack.js API
99
- [Responsive](#responsive)
1010
- [Breakpoint](#breakpoint)
1111
- [DDDragOpt](#dddragopt)
12-
- [DDDragInOpt extends DDDragOpt](#dddraginopt-extends-dddragopt)
1312
- [Grid attributes](#grid-attributes)
1413
- [Item Options](#item-options)
1514
- [Item attributes](#item-attributes)
@@ -30,7 +29,7 @@ gridstack.js API
3029
- [`init(options: GridStackOptions = {}, elOrString: GridStackElement = '.grid-stack'): GridStack`](#initoptions-gridstackoptions---elorstring-gridstackelement--grid-stack-gridstack)
3130
- [`initAll(options: GridStackOptions = {}, selector = '.grid-stack'): GridStack[]`](#initalloptions-gridstackoptions---selector--grid-stack-gridstack)
3231
- [`addGrid(parent: HTMLElement, opt: GridStackOptions = {}): GridStack `](#addgridparent-htmlelement-opt-gridstackoptions---gridstack-)
33-
- [`setupDragIn(dragIn?: string | HTMLElement[], dragInOptions?: DDDragInOpt, root = HTMLElement | Document)`](#setupdragindragin-string--htmlelement-draginoptions-dddraginopt-root--htmlelement--document)
32+
- [`setupDragIn(dragIn?: string | HTMLElement[], dragInOptions?: DDDragOpt, widgets?: GridStackWidget[], root = HTMLElement | Document)`](#setupdragindragin-string--htmlelement-draginoptions-dddragopt-widgets-gridstackwidget-root--htmlelement--document)
3433
- [`GridStack.registerEngine(engineClass: typeof GridStackEngine)`](#gridstackregisterengineengineclass-typeof-gridstackengine)
3534
- [API](#api)
3635
- [`addWidget(w: GridStackWidget): GridItemHTMLElement`](#addwidgetw-gridstackwidget-griditemhtmlelement)
@@ -147,9 +146,7 @@ v10.x supports a much richer responsive behavior, you can have breakpoints of wi
147146
- `pause`?: boolean | number - if set (true | msec), dragging placement (collision) will only happen after a pause by the user. Note: this is Global
148147
- `scroll`?: boolean - default to 'true', enable or disable the scroll when an element is dragged on bottom or top of the grid.
149148
- `cancel`?: string - prevents dragging from starting on specified elements, listed as comma separated selectors (eg: '.no-drag'). default built in is 'input,textarea,button,select,option'
150-
151-
### DDDragInOpt extends DDDragOpt
152-
- `helper`?: 'clone' | ((event: Event) => HTMLElement) - helper function when dropping (ex: 'clone' or your own method)
149+
- `helper`?: 'clone' | ((el: HTMLElement) => HTMLElement) - helper function when dragging side panel items that need to be cloned before dropping (ex: 'clone' or your own method)
153150

154151
## Grid attributes
155152

@@ -341,14 +338,14 @@ grids.forEach(...)
341338
* @param opt grids options used to initialize the grid, and list of children
342339
* see [nested.html](https://github.com/gridstack/gridstack.js/tree/master/demo/nested.html) demo
343340

344-
### `setupDragIn(dragIn?: string | HTMLElement[], dragInOptions?: DDDragInOpt, root = HTMLElement | Document)`
341+
### `setupDragIn(dragIn?: string | HTMLElement[], dragInOptions?: DDDragOpt, widgets?: GridStackWidget[], root = HTMLElement | Document)`
345342

346343
* call to setup dragging in from the outside (say toolbar), by specifying the class selection and options.
347344
Called during `GridStack.init()` as options, but can also be called directly (last param are cached) in case the toolbar is dynamically create and needs to change later.
348-
* @param dragIn string selector (ex: `'.sidebar .grid-stack-item'`) or list of dom elements
349-
* @param dragInOptions options - see `DDDragInOpt`. (default: `{handle: '.grid-stack-item-content', appendTo: 'body'}`
350-
* @param root - default to document. for shadow dom support pass the parent container.
351-
but you will probably also want `helper: 'clone'` or your own callback function).
345+
* @param `dragIn` string selector (ex: `'.sidebar-item'`) or list of dom elements
346+
* @param `dragInOptions` options - see `DDDragOpt`. default: `{appendTo: 'body', helper: 'clone'}`
347+
* @param `widgets` GridStackWidget def to assign to each element which defines what to create on drop
348+
* @param `root` optional root which defaults to document (for shadow dom pass the parent HTMLDocument)
352349

353350
### `GridStack.registerEngine(engineClass: typeof GridStackEngine)`
354351

0 commit comments

Comments
 (0)