diff --git a/demo/two.html b/demo/two.html index b27453145..732556a3a 100644 --- a/demo/two.html +++ b/demo/two.html @@ -87,8 +87,8 @@

Two grids demo

cellHeight: 70, disableOneColumnMode: true, float: false, - dragIn: '.sidebar .grid-stack-item', // add draggable to class - dragInOptions: { revert: 'invalid', scroll: false, appendTo: 'body', helper: 'clone' }, // clone + // dragIn: '.sidebar .grid-stack-item', // add draggable to class + // dragInOptions: { revert: 'invalid', scroll: false, appendTo: 'body', helper: 'clone' }, // clone removable: '.trash', // drag-out delete class removeTimeout: 100, acceptWidgets: function(el) { return true; } // function example, else can be simple: true | false | '.someClass' value @@ -96,6 +96,10 @@

Two grids demo

let grids = GridStack.initAll(options); grids[1].float(true); + // new 4.x static method instead of setting up options on every grid (never been per grid really but old options still work) + GridStack.setupDragIn('.sidebar .grid-stack-item', { revert: 'invalid', scroll: false, appendTo: 'body', helper: 'clone' }); + // GridStack.setupDragIn(); // will now work as well (cache last values) + let items = [ {x: 0, y: 0, w: 2, h: 2}, {x: 3, y: 1, h: 2}, diff --git a/doc/CHANGES.md b/doc/CHANGES.md index 129dad895..b307576f0 100644 --- a/doc/CHANGES.md +++ b/doc/CHANGES.md @@ -55,6 +55,7 @@ Change log - handle mid point of dragged over items (>50%) rather than a new row/column and check for the most covered when multiple items collide. - fix [1617](https://github.com/gridstack/gridstack.js/issues/1617) FireFox DOM order issue. Thanks [@marcel-necker](https://github.com/marcel-necker) - add `drag | resize` events while dragging [1616](https://github.com/gridstack/gridstack.js/pull/1616). Thanks [@MrCorba](https://github.com/MrCorba) +- add `GridStack.setupDragIn()` so user can update external draggable after the grid has been created [1637](https://github.com/gridstack/gridstack.js/issues/1637) ## 3.3.0 (2021-2-2) diff --git a/doc/README.md b/doc/README.md index df45db49d..2d6efc58a 100644 --- a/doc/README.md +++ b/doc/README.md @@ -52,6 +52,7 @@ gridstack.js API - [save(saveContent = true): GridStackWidget[]](#savesavecontent--true-gridstackwidget) - [setAnimation(doAnimate)](#setanimationdoanimate) - [setStatic(staticValue)](#setstaticstaticvalue) + - [GridStack.setupDragIn(dragIn?: string, dragInOptions?: DDDragInOpt)](#gridstacksetupdragindragin-string-draginoptions-dddraginopt) - [update(el: GridStackElement, opts: GridStackWidget)](#updateel-gridstackelement-opts-gridstackwidget) - [willItFit(x, y, width, height, autoPosition)](#willitfitx-y-width-height-autoposition) - [Utils](#utils) @@ -86,8 +87,12 @@ gridstack.js API - `disableDrag` - disallows dragging of widgets (default: `false`). - `disableOneColumnMode` - disables the onColumnMode when the grid width is less than minW (default: 'false') - `disableResize` - disallows resizing of widgets (default: `false`). -- `dragIn` - specify the class of items that can be dragged into the grid (ex: dragIn: '.newWidget' -- `dragInOptions` - options for items that can be dragged into the grid (ex: dragInOptions: { revert: 'invalid', scroll: false, appendTo: 'body', helper: 'clone' } +- `dragIn` - specify the class of items that can be dragged into grids + * example: `dragIn: '.newWidget'`. + * **Note**: if you have multiple grids, it's best to call `GridStack.setupDragIn()` with same params as it only need to be done once. +- `dragInOptions` - options for items that can be dragged into grids + * example `dragInOptions: { revert: 'invalid', scroll: false, appendTo: 'body', helper: 'clone', handle: '.grid-stack-item-content' }` + * **Note**: if you have multiple grids, it's best to call `GridStack.setupDragIn()` with same params as it only need to be done once. - `draggable` - allows to override jQuery UI draggable options. (default: `{handle: '.grid-stack-item-content', scroll: false, appendTo: 'body', containment: null}`) - `dragOut` to let user drag nested grid items out of a parent or not (default false) See [example](http://gridstackjs.com/demo/nested.html) - `float` - enable floating widgets (default: `false`) See [example](http://gridstackjs.com/demo/float.html) @@ -494,6 +499,15 @@ Toggle the grid static state. Also toggle the `grid-stack-static` class. - `staticValue` - if `true` the grid becomes static. +### GridStack.setupDragIn(dragIn?: string, dragInOptions?: DDDragInOpt) + + * 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 cached) in case the toolbar + * is dynamically create and needs to change later. + * `dragIn` string selector (ex: `'.sidebar .grid-stack-item'`) + * `dragInOptions` options - see `DDDragInOpt`. (default: `{revert: 'invalid', handle: '.grid-stack-item-content', scroll: false, appendTo: 'body'}` + + ### update(el: GridStackElement, opts: GridStackWidget) Parameters: diff --git a/src/gridstack-dd.ts b/src/gridstack-dd.ts index 898135a48..72c537a4e 100644 --- a/src/gridstack-dd.ts +++ b/src/gridstack-dd.ts @@ -328,15 +328,31 @@ GridStack.prototype._clearRemovingTimeout = function(el: GridItemHTMLElement): G return this; } -/** @internal call to setup dragging in from the outside (say toolbar), with options */ -GridStack.prototype._setupDragIn = function(): GridStack { - if (!this.opts.staticGrid && typeof this.opts.dragIn === 'string') { - if (!GridStackDD.get().isDraggable(this.opts.dragIn)) { - GridStackDD.get().dragIn(this.opts.dragIn, this.opts.dragInOptions); - } +/** + * 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 cached) in case the toolbar + * is dynamically create and needs to change later. + **/ +GridStack.setupDragIn = function(_dragIn?: string, _dragInOptions?: DDDragInOpt) { + // cache in the passed in values (form grid init?) so they don't have to resend them each time + if (_dragIn) { + dragIn = _dragIn; + dragInOptions = {...dragInDefaultOptions, ...(_dragInOptions || {})}; } - return this; + if (typeof dragIn !== 'string') return; + let dd = GridStackDD.get(); + Utils.getElements(dragIn).forEach(el => { + if (!dd.isDraggable(el)) dd.dragIn(el, dragInOptions); + }); } +let dragIn: string; +let dragInOptions: DDDragInOpt; +const dragInDefaultOptions: DDDragInOpt = { + revert: 'invalid', + handle: '.grid-stack-item-content', + scroll: false, + appendTo: 'body' +}; /** @internal prepares the element for drag&drop **/ GridStack.prototype._prepareDragDropByNode = function(node: GridStackNode): GridStack { diff --git a/src/gridstack.ts b/src/gridstack.ts index e17500bbe..221cdba1a 100644 --- a/src/gridstack.ts +++ b/src/gridstack.ts @@ -9,7 +9,7 @@ import { GridStackEngine } from './gridstack-engine'; import { obsoleteOpts, obsoleteAttr, Utils, HeightData } from './utils'; import { ColumnOptions, GridItemHTMLElement, GridStackElement, GridStackEventHandlerCallback, - GridStackNode, GridStackOptions, GridStackWidget, numberOrString, DDUIData } from './types'; + GridStackNode, GridStackOptions, GridStackWidget, numberOrString, DDUIData, DDDragInOpt } from './types'; import { GridStackDDI } from './gridstack-ddi'; // export all dependent file as well to make it easier for users to just import the main file @@ -70,13 +70,6 @@ const GridDefaults: GridStackOptions = { scroll: false, appendTo: 'body' }, - dragIn: undefined, - dragInOptions : { - revert: 'invalid', - handle: '.grid-stack-item-content', - scroll: false, - appendTo: 'body' - }, disableDrag: false, disableResize: false, rtl: 'auto', @@ -147,6 +140,7 @@ export class GridStack { GridStack.getGridElements(selector).forEach(el => { if (!el.gridstack) { el.gridstack = new GridStack(el, {...options}); + delete options.dragIn; delete options.dragInOptions; // only need to be done once (really a static global thing, not per grid) } grids.push(el.gridstack); }); @@ -357,7 +351,11 @@ export class GridStack { this.el.classList.add('grid-stack-' + this.opts.column); } - this._setupDragIn(); + // legacy support to appear 'per grid` options when really global. + if (this.opts.dragIn) GridStack.setupDragIn(this.opts.dragIn, this.opts.dragInOptions); + delete this.opts.dragIn; + delete this.opts.dragInOptions; + this._setupRemoveDrop(); this._setupAcceptWidget(); this._updateWindowResizeEvent(); @@ -1457,6 +1455,15 @@ export class GridStack { */ /* eslint-disable @typescript-eslint/no-unused-vars */ + /** + * 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 cached) in case the toolbar + * is dynamically create and needs to change later. + * @param dragIn string selector (ex: '.sidebar .grid-stack-item') + * @param dragInOptions options - see DDDragInOpt. (default: {revert: 'invalid', handle: '.grid-stack-item-content', scroll: false, appendTo: 'body'} + **/ + public static setupDragIn(dragIn?: string, dragInOptions?: DDDragInOpt): void { /* implemented in gridstack-dd.ts */ } + /** * Enables/Disables moving. No-op for static grids. * @param els widget or selector to modify. @@ -1503,6 +1510,7 @@ export class GridStack { * doEnable`s value by changing the disableResize grid option (default: true). */ public enableResize(doEnable: boolean, includeNewWidgets = true): GridStack { return this } + /** @internal called to add drag over support to support widgets */ public _setupAcceptWidget(): GridStack { return this } /** @internal called to setup a trash drop zone if the user specifies it */ @@ -1511,8 +1519,6 @@ export class GridStack { public _setupRemovingTimeout(el: GridItemHTMLElement): GridStack { return this } /** @internal */ public _clearRemovingTimeout(el: GridItemHTMLElement): GridStack { return this } - /** @internal call to setup dragging in from the outside (say toolbar), with options */ - public _setupDragIn(): GridStack { return this } /** @internal prepares the element for drag&drop **/ public _prepareDragDropByNode(node: GridStackNode): GridStack { return this } /** @internal handles actual drag/resize start **/