Advanced Draggable & Selectable Library – DragSelect

Category: Drag & Drop , Javascript | September 25, 2023
Author:ThibaultJanBeyer
Views Total:78 views
Official Page:Go to website
Last Update:September 25, 2023
License:MIT

Preview:

Advanced Draggable & Selectable Library – DragSelect

Description:

DragSelect is a lightweight and easy-to-use JavaScript library for creating draggable, droppable, and selectable DOM elements. Accessible, highly customizable, and mobile-friendly.

See Also:

How to use it:

1. Install & download.

# NPM
$ npm i dragselect

2. Load the DragSelect library.

// CDN
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/DragSelect.min.js"></script>
// OR
import DragSelect from "dragselect";

3. Initialize the DragSelect on the elements which should be selectable.

<div class="item">
  Drag To Select
</div>
const ds = new DragSelect({
      selectables: document.querySelectorAll('.item')
});
// callback
ds.subscribe('callback', (e) => console.log(e))

4. Restrict the draggable and selectable functions to a specified container.

const ds = new DragSelect({
      selectables: document.querySelectorAll('.item'),
      area: document.getElementById('myContainer'),
});

5. You can also define a drop zone into which you can drag & drop the selected elements.

const ds = new DragSelect({
      selectables: document.querySelectorAll('.item'),
      dropZones: [
        { 
          element: document.querySelector('#zone-1'), 
          id: 'zone-1', 
          droppables: document.querySelectorAll('#item-1,#item-3') 
        },
        { 
          element: document.querySelector('#zone-2'), 
          id: 'zone-2', 
          droppables: document.querySelectorAll('#item-2,#item-3') 
        },
        { 
          element: document.querySelector('#zone-3'), 
          id: 'zone-3' 
        },
    ],
});

6. All possible options.

  • area=document: area in which you can drag. If not provided it will be the whole document
  • selectables=[]: the elements that can be selected
  • autoScrollSpeed=5: Speed in which the area scrolls while selecting (if available). Unit is pixel per movement.
  • overflowTolerance={x:25,y:25}: Tolerance for autoScroll (how close one has to be near an edges for autoScroll to start)
  • zoom=1: Zoom scale factor (in case of using CSS style transform: scale() which messes with real positions). Unit scale zoom.
  • customStyles=false: if set to true, no styles (except for position absolute) will be applied by default
  • multiSelectMode=false: Add newly selected elements to the selection instead of replacing them
  • multiSelectToggling=true: Whether or not to toggle already active elements while multi-selecting
  • multiSelectKeys=['Control', 'Shift', 'Meta']: Keys that allows switching to the multi-select mode (see the multiSelectMode option). Any key value is possible ([see MDN docs](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key)). Note that the best support is given for <kbd>Control</kbd>, <kbd>Shift</kbd> and <kbd>Meta</kbd>. Provide an empty array `[]` if you want to turn off the functionality.
  • selector=HTMLElement: the square that will draw the selection
  • selectionThreshold=0: how much % of the element has to be selected to be considered selected (0 = just touching, 1 = inside the selection)
  • draggability=true: When a user is dragging on an already selected element, the selection is dragged.
  • immediateDrag=true: Whether an element is draggable from the start or needs to be selected first
  • keyboardDrag=true: Whether or not the user can drag with the keyboard (we don’t recommend disabling it)
  • dragKeys={up:['ArrowUp'],down:['ArrowDown'],left:['ArrowLeft'],righ:['ArrowRight']}: The keys available to drag element using the keyboard.
  • keyboardDragSpeed=10: The speed at which elements are dragged using the keyboard. In pixels per keydown.
  • useTransform=true: Whether to use hardware accelerated css transforms when dragging or top/left instead
  • refreshMemoryRate=80: Refresh rate on memoization, higher numbers mean better performance but more lag if elements are moving, lower numbers mean less lag but worse performance. If none of your DOMNodes are moving, you can set it to a very high number to increase performance. Value in milliseconds.
  • dropZones=[]: one or more drop-elements: where the selectables can be dropped into
  • dropInsideThreshold=1: how much % of the item has to be inside the dropzone to be considered inside (0 = barely touching, 1 = completely inside)
  • dropTargetThreshold=0: how much % of the zone does the pointer has to be in to be considered a target (0 = anywhere in the zone, max: 0.5 = has to point at the center of the zone)
  • usePointerEvents=false: Whether to use Pointer Events to replace traditional Mouse or Touch Events. Useful for tools like Google Blockly.
  • hoverClass=ds-hover: the class assigned to the mouse hovered items
  • selectableClass=ds-selectable: the class assigned to the elements that can be selected
  • selectedClass=ds-selected: the class assigned to the selected items
  • selectorClass=ds-selector: the class assigned to the square selector helper
  • selectorAreaClass=ds-selector-area: the class assigned to the square in which the selector resides. By default it’s invisible
  • droppedTargetClass=ds-dropped-target: on an item corresponding the target dropzone. This is also the prefix for ds-dropped-target-${zone.id}
  • droppedInsideClass=ds-dropped-inside: on an item that is within its dropzone bounds after a drop. This is also the prefix for ds-dropped-inside-${zone.id}
  • droppableClass=ds-droppable: on element that can be dropped into at least one container. This is also the prefix for ds-droppable-${zone.id}
  • dropZoneClass=ds-dropzone: on each dropZone
  • dropZoneReadyClass=ds-dropzone-ready: on corresponding dropZone when element is dragged
  • dropZoneTargetClass=ds-dropzone-target: on dropZone that has elements from any successful target drop
  • dropZoneInsideClass=ds-dropzone-inside: on dropZone that has elements inside after any drop
  • dragAsBlock=false: Whether to drag multiple elements as a single block or as individual items

7. Event handlers. Available parameters:

  • items: The items currently selected
  • event: The respective event object
  • item: The single item currently interacted with
  • isDragging: Whether the interaction is a drag or a select
  • isDraggingKeyboard: Whether or not the drag interaction is via keyboard
  • key: Pressed key (lowercase)
  • settings: the settings being updates/manipulated/passed, also holds the previous value. i.e. updating selectorClass will publish { settings: { selectorClass: ‘newVal’, ‘selectorClass:pre’>: ‘oldVal’ } }
  • scroll_directions: ‘top’|’bottom’|’left’|’right’|undefined
  • scroll_multiplier: number
  • dropTarget: The dropZone element that the element was dropped into (or the mouse is currently hovering over)
// after selection
ds.subscribe('DS:end',  { items, event, isDragging, isDraggingKeyboard, dropTarget, … } => {})
// before dragging
ds.subscribe('DS:start', { items, event, isDragging, isDraggingKeyboard, … } => {})
// when dragging
ds.subscribe('DS:update', { items, event, isDragging, isDraggingKeyboard, … } => {})
// auto scroll
ds.subscribe('DS:scroll', { items, isDragging, scroll_directions, scroll_multiplier, … } => {})
// when an element is added to the selection
ds.subscribe('DS:select', { items, item, isDragging, …} => {})
// when an element is removed from the selection
ds.subscribe('DS:unselect', { items, item, isDragging, … } => {})
// when an element is added from the list of selectable elements
ds.subscribe('DS:added', { items, item, isDragging, … } => {})
// when an element is removed from the list of selectable elements
ds.subscribe('DS:removed', { items, item, isDragging, … } => {})

8. API methods.

ds.start();
ds.stop();
ds.break();
ds.subscribe(event, callback);
ds.unsubscribe(event, callback);
ds.publish(event, callback);
ds.setSettings(settings); // update settings
ds.getSelection();
ds.addSelection(elements:[HTMLElement | SVGElement] | HTMLElement | SVGElement, triggerCallback:boolean, dontAddToSelectables:boolean);
ds.removeSelection(elements:[HTMLElement | SVGElement] | HTMLElement | SVGElement, triggerCallback:boolean, removeFromSelectables:boolean);
ds.toggleSelection(elements:[HTMLElement | SVGElement] | HTMLElement | SVGElement, triggerCallback:boolean, removeFromSelectables:boolean);
ds.setSelection(elements:[HTMLElement | SVGElement] | HTMLElement | SVGElement, triggerCallback:boolean, dontAddToSelectables:boolean);
ds.setSelection(elements:[HTMLElement | SVGElement] | HTMLElement | SVGElement, triggerCallback:boolean, dontAddToSelectables:boolean);
ds.clearSelection(elements:[HTMLElement | SVGElement] | HTMLElement | SVGElement, triggerCallback:boolean);
ds.addSelectables(elements:[HTMLElement | SVGElement] | HTMLElement | SVGElement, addToSelection:boolean);
ds.removeSelectables(elements:[HTMLElement | SVGElement] | HTMLElement | SVGElement, removeFromSelection:boolean);
ds.getSelectables();
ds.getInitialCursorPosition();
ds.getCurrentCursorPosition();
ds.getPreviousCursorPosition();
ds.getInitialCursorPositionArea();
ds.getCurrentCursorPositionArea();
ds.getPreviousCursorPositionArea();
ds.getZoneByCoordinates(coordinates:{ x:number, y:number } (Optional));
ds.getItemsDroppedByZoneId(zoneId:string);
ds.getItemsInsideByZoneId(zoneId:string, addClasses:boolean);

9. Style the draggable & selectable elements.

.ds-selector {
  /* ... */
}
.ds-selector-area {
  /* ... */
}
.ds-selectable {
  /* ... */
}
.ds-droppable {
  /* ... */
}
.ds-droppable-${id} {
  /* ... */
}
.ds-dropped-target {
  /* ... */
}
.ds-dropped-target-${id} {
  /* ... */
}
.ds-dropped-inside {
  /* ... */
}
.ds-dropped-inside-${id} {
  /* ... */
}
.ds-dropzone {
  /* ... */
}
.ds-dropzone-ready {
  /* ... */
}
.ds-dropzone-target {
  /* ... */
}
.ds-dropzone-inside {
  /* ... */
}

Changelog:

v3.0.3 (09/25/2023)

  • Refactor in TypeScript

v2.7.4 (04/21/2023)

  • Bugfixes

v2.7.0 (03/05/2023)

  • Introduce blog-drag ahs alpa. It is supposed to fix dragging of multiple elements: dragging them as one block keeping aspect ratio positions on drag-scroll. Instead of moving elements individually.

v2.6.1 (02/10/2023)

  • Fix bug calling dropZones

v2.6.0 (02/01/2023)

  • Expose filterSelected in Selection module
  • Expose isCollision helper method

You Might Be Interested In:


Leave a Reply