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

Skip to content

Commit 771f546

Browse files
committed
GridStackOptions.draggable.cancel option
* you can now specify children that will prevent item from being dragged when clicked on. * fix for gridstack#2205 * updated demo to showcase custom non draggable item
1 parent 319b34a commit 771f546

File tree

5 files changed

+23
-16
lines changed

5 files changed

+23
-16
lines changed

demo/serialization.html

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ <h1>Serialization demo</h1>
2727
<script type="text/javascript">
2828
let grid = GridStack.init({
2929
minRow: 1, // don't let it collapse when empty
30-
cellHeight: '7rem'
30+
cellHeight: '7rem',
31+
draggable: { cancel: '.no-drag'} // example of additional custom elements to skip drag on
3132
});
3233

3334
grid.on('added removed change', function(e, items) {
@@ -39,8 +40,8 @@ <h1>Serialization demo</h1>
3940

4041
let serializedData = [
4142
{x: 0, y: 0, w: 2, h: 2, id: '0'},
42-
{x: 3, y: 1, h: 2, id: '1',
43-
content: "<button onclick=\"alert('clicked!')\">Press me</button><div>text area</div><div><textarea></textarea></div><div>Input Field</div><input type='text'><div contentEditable=\"true\">Editable Div</div>"},
43+
{x: 3, y: 1, h: 3, id: '1',
44+
content: "<button onclick=\"alert('clicked!')\">Press me</button><div>text area</div><div><textarea></textarea></div><div>Input Field</div><input type='text'><div contentEditable=\"true\">Editable Div</div><div class=\"no-drag\">no drag</div>"},
4445
{x: 4, y: 1, id: '2'},
4546
{x: 2, y: 3, w: 3, id: '3'},
4647
{x: 1, y: 3, id: '4'}

doc/CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ Change log
8989
* break: remove `GridStackOptions.minWidth` obsolete since 5.1, use `oneColumnSize` instead
9090
* optimize: CSS files now even 25% smaller (after being halfed in 8.0.0) by removing `.grid-stack` prefix for anything already gs based, and 3 digit rounding.
9191
* fix: [#2275](https://github.com/gridstack/gridstack.js/issues/2275) `setupDragIn()` signature tweaks (HTMLElement | Document)
92+
* feat: [#2205](https://github.com/gridstack/gridstack.js/issues/2205) added `GridStackOptions.draggable.cancel` for list of selectors that should prevent item dragging
9293

9394
## 8.0.1 (2023-04-29)
9495
* feat: [#2275](https://github.com/gridstack/gridstack.js/issues/2275) `setupDragIn()` now can take an array or elements (in addition to selector string) and optional parent root (for shadow DOM support)

doc/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,10 @@ GridStack will add it to the <style> elements it creates.
131131
- `appendTo`?: string - default to 'body' (TODO: is this even used anymore ?)
132132
- `pause`?: boolean | number - if set (true | msec), dragging placement (collision) will only happen after a pause by the user. Note: this is Global
133133
- `scroll`?: boolean - default to 'true', enable or disable the scroll when an element is dragged on bottom or top of the grid.
134+
- `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'
134135

135136
### DDDragInOpt extends DDDragOpt
136-
- `helper`?: string | ((event: Event) => HTMLElement) - helper function when dropping (ex: 'clone' or your own method)
137+
- `helper`?: 'clone' | ((event: Event) => HTMLElement) - helper function when dropping (ex: 'clone' or your own method)
137138

138139
## Grid attributes
139140

src/dd-draggable.ts

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ import { isTouch, touchend, touchmove, touchstart, pointerdown } from './dd-touc
1414
export interface DDDraggableOpt {
1515
appendTo?: string | HTMLElement;
1616
handle?: string;
17-
helper?: string | HTMLElement | ((event: Event) => HTMLElement);
17+
helper?: 'clone' | HTMLElement | ((event: Event) => HTMLElement);
18+
cancel?: string;
1819
// containment?: string | HTMLElement; // TODO: not implemented yet
1920
// revert?: string | boolean | unknown; // TODO: not implemented yet
20-
// scroll?: boolean; // native support by HTML5 drag drop, can't be switch to off actually
21+
// scroll?: boolean;
2122
start?: (event: Event, ui: DDUIData) => void;
2223
stop?: (event: Event) => void;
2324
drag?: (event: Event, ui: DDUIData) => void;
@@ -34,6 +35,9 @@ interface DragOffset {
3435

3536
type DDDragEvent = 'drag' | 'dragstart' | 'dragstop';
3637

38+
// make sure we are not clicking on known object that handles mouseDown
39+
const skipMouseDown = 'input,textarea,button,select,option,[contenteditable="true"],.ui-resizable-handle';
40+
3741
// let count = 0; // TEST
3842

3943
export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt<DDDraggableOpt> {
@@ -64,6 +68,7 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
6468
super();
6569
this.el = el;
6670
this.option = option;
71+
6772
// get the element that is actually supposed to be dragged by
6873
let handleName = option.handle.substring(1);
6974
this.dragEl = el.classList.contains(handleName) ? el : el.querySelector(option.handle) || el;
@@ -127,12 +132,11 @@ export class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt
127132
if (DDManager.mouseHandled) return;
128133
if (e.button !== 0) return true; // only left click
129134

130-
// make sure we are not clicking on known object that handles mouseDown (TODO: make this extensible ?) #2054
131-
const skipMouseDown = ['input', 'textarea', 'button', 'select', 'option'];
132-
const name = (e.target as HTMLElement).nodeName.toLowerCase();
133-
if (skipMouseDown.find(skip => skip === name)) return true;
134-
// also check for content editable
135-
if ((e.target as HTMLElement).closest('[contenteditable="true"]')) return true;
135+
// make sure we are not clicking on known object that handles mouseDown, or ones supplied by the user
136+
if ((e.target as HTMLElement).closest(skipMouseDown)) return true;
137+
if (this.option.cancel) {
138+
if ((e.target as HTMLElement).closest(this.option.cancel)) return true;
139+
}
136140

137141
// REMOVE: why would we get the event if it wasn't for us or child ?
138142
// make sure we are clicking on a drag handle or child of it...

src/types.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -343,12 +343,12 @@ export interface DDDragOpt {
343343
pause?: boolean | number;
344344
/** default to `true` */
345345
scroll?: boolean;
346-
/** parent constraining where item can be dragged out from (default: null = no constrain) */
347-
// containment?: string;
346+
/** prevents dragging from starting on specified elements, listed as comma separated selectors (eg: '.no-drag'). default built in is 'input,textarea,button,select,option' */
347+
cancel?: string;
348348
}
349349
export interface DDDragInOpt extends DDDragOpt {
350-
/** helper function when dropping (ex: 'clone' or your own method) */
351-
helper?: string | ((event: Event) => HTMLElement);
350+
/** helper function when dropping: 'clone' or your own method */
351+
helper?: 'clone' | ((event: Event) => HTMLElement);
352352
/** used when dragging item from the outside, and canceling (ex: 'invalid' or your own method)*/
353353
// revert?: string | ((event: Event) => HTMLElement);
354354
}

0 commit comments

Comments
 (0)