Drag and Drop for Dart web apps with mouse and touch support.

Related tags

Templates dart-dnd
Overview

Dart Drag and Drop

Drag and Drop for Dart web apps with mouse and touch support.

Star this Repo Pub Package

GitHub | Pub | Demos and Examples

DnD Screenshot

Features

  • Use any HTML Element as Draggable or Dropzone.
  • Mouse and Touch dragging.
  • Draggable events: dragStart, drag, and dragEnd
  • Dropzone events: dragEnter, dragOver, dragLeave, and drop
  • Drag avatars as visual indication of a drag operation:
    • Original element as drag avatar.
    • Clone as drag avatar.
    • Custom drag avatar.
  • Support for Shadow DOM (Web Components, Custom Elements, Polymer, etc.).
  • Much more... see examples.

Usage

Before you read the instructions below, you should take a look at the examples.

Basic Set Up

Create a Draggable and give it some HTML elements; this will make them draggable. You can either pass a single Element to the constructor or an ElementList that is returned by querySelectorAll.

If you also want to drop somewhere, you'll need a Dropzone.

// Install draggable (no avatar).
Draggable draggable = Draggable(querySelectorAll('.draggable'));

// Install dropzone.
Dropzone dropzone = Dropzone(querySelector('.dropzone'));

You'll most likely want some drag avatar to show the user that a drag is going on. There are two predefined AvatarHandlers that you can use as follows. But you could also provide your own implementation of AvatarHandler.

// Draggable with clone as avatar.
Draggable draggable = Draggable(querySelectorAll('.draggable'),
    avatarHandler: AvatarHandler.clone());


// Draggable with original element as avatar.
Draggable draggable = Draggable(querySelectorAll('.draggable'),
    avatarHandler: AvatarHandler.original());

Draggable Options

The following options can be passed as named parameters to the constructor of Draggable:

  • avatarHandler: Is responsible for creating, position, and removing a drag avatar. A drag avatar provides visual feedback during a drag operation. Here are possible options (see above for an example):

    • null (the default) - will not create a drag avatar
    • AvatarHandler.original() - handler that uses the original draggable as avatar. See OriginalAvatarHandler.
    • AvatarHandler.clone() - handler that uses a clone of the draggable element as avatar. See CloneAvatarHandler.
    • A custom AvatarHandler - you can provide your own implementation of AvatarHandler.
  • horizontalOnly: If set to true, only horizontal dragging is tracked. This enables vertical touch dragging to be used for scrolling.

  • verticalOnly: If set to true, only vertical dragging is tracked. This enables horizontal touch dragging to be used for scrolling.

  • handle: If handle query String is specified, it restricts the dragging from starting unless it occurs on the specified element(s). Only elements that descend from the draggables elements are permitted.

  • cancel: If cancel query String is specified, drag starting is prevented on specified elements.

  • draggingClass: Is the css class set to the dragged element during a drag. If set to null, no such css class is added.

  • draggingClassBody: Is the css class set to the html body tag during a drag. If set to null, no such css class is added.

  • minDragStartDistance: Is the minimum distance in pixels that is needed for a drag to start. Default is 4. This allows for clicks with tiny movement.

Draggable Events

Available event Streams on Draggable:

  • onDragStart: Fired when the user starts dragging.
    Note: onDragStart is fired not on touchStart or mouseDown but as soon as there is a drag movement. When a drag is started an onDrag event will also be fired.

  • onDrag: Fired periodically throughout the drag operation.

  • onDragEnd: Fired when the user ends the dragging.
    Note: Is also fired when the user clicks the 'esc'-key or the window loses focus.

Dropzone Options

The following options can be passed as named parameters to the constructor of Dropzone:

  • acceptor: Is used to determine which Draggables will be accepted by this Dropzone. If none is specified, all Draggables will be accepted.

  • overClass: Is the css class set to the dropzone element when an accepted draggable is dragged over it. If set to null, no such css class is added.

  • invalidClass: Is the css class set to the dropzone element when a not-accepted draggable is dragged over it. If set to null, no such css class is added.

Dropzone Events

Available event Streams on Dropzone:

  • onDragEnter: Fired when a Draggable enters this Dropzone.

  • onDragOver: Fired periodically while a Draggable is moved over a Dropzone.

  • onDragLeave: Fired when a Draggable leaves this Dropzone.

  • onDrop: Fired when a Draggable is dropped inside this Dropzone.

Note: Dropzone events are only fired when the Draggable is accepted by the Acceptor.

Shadow DOM

Web Components create a nice ecapsulation through Shadow DOM. But this creates a problem with dropzones inside the Shadow DOM as they never receive events because all events are captured by the host element. To make this work we need to retarget events to the Shadow DOM children through recursive elementFromPoint() calls.

For performance reasons it wouldn't make sense to retarget all drag and drop events. If you wish to retarget events to the Shadow DOM children, you must add a dnd-retarget attribute to the host:

// Retarget drag and drop events to Shadow DOM children.
<my-element dnd-retarget></my-element>

Attribution

The Dart Drag and Drop library is inspired by

Thank you for your work!

Running / Building / Testing

  • Run from the terminal: webdev serve
  • Build from the terminal: webdev build

License

The MIT License (MIT)

Comments
  • Not working in Windows 8.1 IE11 Metro

    Not working in Windows 8.1 IE11 Metro

    By the way it's not working on Windows 8.1 IE11 Metro. Some <meta ...> should be added to html for disabling default back/forward on drag?

    Reported by Slava Pankov

    bug 
    opened by marcojakob 17
  • Fix mouse drag suppression

    Fix mouse drag suppression

    We noticed that drag suppression hasn't really been working. This fixes that, by effectively not starting a drag event until the suppression distance has been met. Once the distance has been exceeded, the drag started event is dispatched.

    @marcojakob

    opened by spencercornish-wk 10
  • If the page contents scrolls out of the visible area x + y for mouse position becomes wrong

    If the page contents scrolls out of the visible area x + y for mouse position becomes wrong

    screenshot-1669

    Here you can see where the mouse cursor is and where the draggable object ist. http://wsk.angular.mikemitterer.at/styleguide/index.html#/draganddrop

    The problem becomes even worser on mobile where the page is narrower...

    opened by MikeMitterer 9
  • Dropzones don't work with Shadow DOM due to event retargeting

    Dropzones don't work with Shadow DOM due to event retargeting

    The onMouseMove events setup in draggable.dart (https://github.com/marcojakob/dart-dnd/blob/master/lib/src/draggable.dart#L320) will never handle targets within Shadow DOM. Reason for this is, that events from within the Shadow DOM are retargeted to its host. For event handlers setup outside the host, the event target will always be the host and not potential drop targets within.

    // Install mouseMove listener.
        _dragSubs.add(document.onMouseMove.listen((MouseEvent event) {
    

    Also have a look here: http://www.html5rocks.com/en/tutorials/webcomponents/shadowdom-301/#toc-events

    A solution might be to also register mouseover handlers, when the dropzone is installed to elements and react properly.

    help wanted 
    opened by friegger 8
  • fix for shadow dom

    fix for shadow dom

    Hi Marco, I fix your DnD to work with polymer. It's only in added Document in which events happens. Feel free about pull / rewrite / drop this ;)

    Br, František Belšán

    opened by Belsi 7
  • NoSuchMethodError: method not found: 'pubspec'

    NoSuchMethodError: method not found: 'pubspec'

    Since 0.2.0 I get

    Precompiling dependencies...
    Loading source assets...
    The null object does not have a getter 'pubspec'.
    
    NoSuchMethodError: method not found: 'pubspec'
    Receiver: null
    Arguments: []
    dart:core                                                                                                                       Object.noSuchMethod
    /Volumes/data/b/build/slave/dart-editor-mac-dev/build/dart/sdk/lib/_internal/pub/lib/src/barback/dependency_computer.dart 251   _PackageDependencyComputer._PackageDependencyComputer
    /Volumes/data/b/build/slave/dart-editor-mac-dev/build/dart/sdk/lib/_internal/pub/lib/src/barback/dependency_computer.dart 199   DependencyComputer._loadPackageComputer
    /Volumes/data/b/build/slave/dart-editor-mac-dev/build/dart/sdk/lib/_internal/pub/lib/src/barback/dependency_computer.dart 107   DependencyComputer._transformersNeededByTransformer
    /Volumes/data/b/build/slave/dart-editor-mac-dev/build/dart/sdk/lib/_internal/pub/lib/src/barback/dependency_computer.dart 258   _PackageDependencyComputer._PackageDependencyComputer
    /Volumes/data/b/build/slave/dart-editor-mac-dev/build/dart/sdk/lib/_internal/pub/lib/src/barback/dependency_computer.dart 199   _loadPackageComputer
    dart:core                                                                                                                       List.forEach
    /Volumes/data/b/build/slave/dart-editor-mac-dev/build/dart/sdk/lib/_internal/pub/lib/src/barback/dependency_computer.dart 53    DependencyComputer.DependencyComputer
    /Volumes/data/b/build/slave/dart-editor-mac-dev/build/dart/sdk/lib/_internal/pub/lib/src/barback/load_all_transformers.dart 33  loadAllTransformers.<async>
    dart:isolate
    

    If I remove the dependency to your package the error is gone.

    opened by MikeMitterer 5
  • dnd-over class does not get removed when abort the dragging with esc-key

    dnd-over class does not get removed when abort the dragging with esc-key

    I've the issue, that the dnd-over class stays on the last dragged over element when i abort the dragging with esc-key.

    Is there a way to disable the abort with esc?

    opened by frickt 4
  • Please add drag&drop reordering

    Please add drag&drop reordering

    Wow, this must be one of the best drag&drop library ever! Only one request: can you support a drag&drop reordering of vertical (or horizontal) lists of elements? For example if I want to move an element from the position 4 of the list to the position 10, it should be able to do it in the following ways:

    • INSERT AFTER: shift all the elements > 10 down (or right) and put the 4 at the 11th position
    • INSERT BEFORE : shift all the elements > 9 down (or right) and put the 4 at the 10h position
    • SWITCH : put the element 4 in place of element 10, and element 10 in place of element 4, without moving any other elements
    • GROUP INSERT : shift a multiple selection of N elements from their original positions to the 11+N position, using the INSERT AFTER mode for the group of elements
    • GROUP SWITCH : put a multiple selection of N elements from their original position 4+N to 11+N, and the group of elements that was 11+N in place of the elements that were at the 4+N position.

    Also those features should be useful: REALTIME REORDERING WHILE WE DRAG: dragging an element or a group of elements above the list should animate the list showing the auto reordering of the list in case the element is dropped at the current point. MULTI-COLUMNS / ROWS SUPPORT : drag&drop reordering should work in multi columns or multi rows elements lists, with the possibility to drag&drop between different columns or rows. UNDO: an animation should undo the latest drag&drop reordering

    opened by Emasoft 4
  • Cannot initialize Dropzone with List<HtmlElement>

    Cannot initialize Dropzone with List

    Could we change the check in the constructor for Dropzone from:

        if (_elementOrElementList is ElementList) {
    

    to

       if (_elementOrElementList is List<Element>) {
    

    I would like to use the library together with angular dart's ViewChildren where i get a List.

    Or is there a reason for ElementList?

    opened by frickt 3
  • touch gesture interpreted by OS during drag

    touch gesture interpreted by OS during drag

    Firstly, thanks for a great library. I am trying to do DnD on touch devices. However, the drag gesture also has an effect on the whole page. Using your example: https://github.com/marcojakob/dart-dnd/tree/master/example/basic On an iPhone or iPad while dragging the paper (which becomes a face) the whole page moves.

    Do you know how to stop this?

    Finally, you library is the only one I could get to work with the Chrome Developer Tools Touch mode!! Cheers, Phil.

    opened by pslavers 3
  • Handle the edge case where destroy is called while dragging an avatar.

    Handle the edge case where destroy is called while dragging an avatar.

    This addresses https://github.com/marcojakob/dart-dnd/issues/17

    I tested it in our use case, and it worked. I didn't add unit tests, because it doesn't look like the repo has any setup for it, and I don't want to force my unit test tool opinions upon you.

    opened by tomconnell-wf 3
  • Scrollable areas and parent elements with margins

    Scrollable areas and parent elements with margins

    In an AngularDart app with a scrollable div, the positioning of the drag avatar is off when dragging inside the scrolled div. The following subclass of OriginalAvatarHandler fixed it for me - but I don't know if it'll break in other circumstances:

    class CustomAvatarHandler extends OriginalAvatarHandler {
      Point _delta;
    
      @override
      void dragStart(Element draggable, Point startPosition) {
        Point clientPos = draggable.getBoundingClientRect().topLeft;
        Point offsetPos = draggable.offset.topLeft;
        _delta = Point(offsetPos.x - clientPos.x, offsetPos.y - clientPos.y);
        super.dragStart(draggable, startPosition);
        avatar.style.position = 'fixed';
        setLeftTop(offsetPos);
      }
    
      @override
      void setLeftTop(Point position) {
        super.setLeftTop(Point(position.x - _delta.x, position.y - _delta.y));
      }
    }
    
    opened by erikhugintech 0
  • How to make new item also draggable?

    How to make new item also draggable?

    Initially I have a table of 4 rows, and I initialized Draggable once.

        Draggable(tableElement, avatarHandler: AvatarHandler.clone());
    
        Dropzone dropzone = Dropzone(stationListElement);
    
        dropzone.onDrop.listen((DropzoneEvent event) {
          _reorder(event.draggableElement, event.dropzoneElement);
        });
    

    Later the component added a new row after some user interaction.

    Problem is that new row isn't draggable. I tried initialize again but the drop event is listened twice.

    Do you have any suggestion how to handle it on my use case?

    opened by warenix 1
  • Not scrollable on mobile with handle

    Not scrollable on mobile with handle

    Hi!

    When filling a whole page with a list of list tiles with drag handles, when touching the non-handle part, the page is not able to scroll, whereas when touching outside of the tile it is possible.

        AvatarHandler avatar = AvatarHandler.clone();
    
        dropzone = Dropzone(querySelectorAll('.sortable-zone'));
    
        draggable = Draggable(querySelectorAll('.sortable'),
            avatarHandler: avatar, handle: '.handle');
    
    opened by martinory 3
  • Feature Request

    Feature Request

    Let me say your lib is great and easy to use. However, it is lacking one feature (and so is the native dart) that would ease development for many. That one feature would be the offset between the mouse pointer (position) and the upper left corner of the element being dragged. This would help in setting the position for the element being dragged.

    opened by Monotoba 4
Releases(v2.0.1)
  • v2.0.1(Oct 7, 2021)

  • v2.0.0(Mar 6, 2021)

  • v1.4.3(Dec 10, 2019)

  • v1.4.2(Feb 13, 2019)

  • v1.4.1(Feb 13, 2019)

  • v1.4.0(Oct 12, 2018)

    • Add an option minDragStartDistance on Draggable to define the minimum distance in pixels that is needed for a drag to start (#26). Default is 4 pixels. This allows for clicks with tiny movement. The option clickSuppression has been marked as DEPRECATED as it had the same goal but a misleading name.
    Source code(tar.gz)
    Source code(zip)
  • v1.3.0(Aug 15, 2018)

  • v1.2.0(Jun 21, 2018)

  • v1.1.0(Jun 21, 2018)

  • v1.0.0(Jun 13, 2018)

    • Migrate to Dart 2.
    • Since Chrome 56 touch event listeners are treated as passive by default. This disables the possibility to call preventDefault on an element which we must do to tell the browser not to scroll while dragging. To fix this in Chrome we set the touch-action css property. With this Chrome will not scroll (none) or only scroll in one direction (pan-y or pan-x).
    Source code(tar.gz)
    Source code(zip)
  • v0.4.0(Jun 27, 2017)

  • v0.3.6(Jun 5, 2017)

  • v0.3.5(Nov 22, 2016)

  • v0.3.4(Oct 19, 2016)

  • v0.3.3(Sep 22, 2016)

    • Allow a configurable clickSuppression distance (#13). We found that the click suppression was a little too aggressive for users with less mousing accuracy. They would attempt to click and trigger a small drag. Which then suppressed the click event and prevented the action they intended to complete.
    Source code(tar.gz)
    Source code(zip)
  • v0.3.1(Jul 25, 2016)

  • v0.3.0(Apr 18, 2015)

    • BREAKING CHANGE: Refactoring the AvatarHandler. Only if you've implemented a custom AvatarHandler you might need to do some changes:
      • setPointerEventsNone and resetPointerEvents were removed and don't need to be called any more. Pointer event styles are handled automatically.
    • Fix AvatarHandler margin caching: The AvatarHandler only cached the margins once for every Draggable. This caused problems when margins of elements in the same Draggable had different margins or the margins were changed. Now the margins are reset after every drag.
    Source code(tar.gz)
    Source code(zip)
  • v0.2.1(Mar 9, 2015)

  • v0.2.0(Mar 9, 2015)

    • Fix #3: Shadow DOM is now supported. A dnd-retarget attribute must be added to all custom elements where events should be forwarded to the Shadow DOM children.
    • Fix #7: Add a css class (dnd-invalid by default) to dropzones when a not-accepted draggable is dragged over.
    Source code(tar.gz)
    Source code(zip)
  • v0.1.4(Oct 20, 2014)

    • Add a sortable example.
    • Change comments according to new Dart Style Guide rule (/// instead of /** */).
    • Move event dispatching calls from EventManager to Draggable (refactoring).
    Source code(tar.gz)
    Source code(zip)
Widgets to support native drag and drop in Flutter.

Drag and Drop Flutter This is the repository for a plugin implementing drag and drop functionality for Flutter. This is a federated plugin. There is a

Jesse 0 Dec 29, 2021
Native Drag and Drop for Flutter on iOS and MacOS

native_draggable A new flutter plugin project. Getting Started This project is a starting point for a Flutter plug-in package, a specialized package t

Rody Davis 59 Dec 4, 2022
Drag and drop module for CITMATEL's 'strawberry' project

citmatel_strawberry_dnd Drag and drop module for CITMATEL's 'strawberry' project Getting Started This project is a starting point for a Flutter applic

null 2 Jan 6, 2023
Flutter package for drag-and-drop reordering of two-level lists

drag_and_drop_lists Two-level drag and drop reorderable lists. Features Reorder elements between multiple lists Reorder lists Drag and drop new elemen

Philip Brink 168 Dec 18, 2022
APP desenvolvido em flutter que se comunica com uma API desenvolvida em python para controlar o mouse e teclado da maquina onde a API roda.

INSTRUÇÕES PARA EXECUÇÃO DA API Para executar a api em python, é necessario instalar as bibliotecas pynput, uvicorn e starlette e pyqrcode. Basta exec

João Paulo Prata 66 Mar 2, 2022
Flutter package. A wrapper for scrollable widgets that enables smooth scrolling with a mouse on all platforms.

Dynamic Mouse Scroll A wrapper for scrollable widgets that enables smooth scrolling with a mouse on all platforms. First gif: Scrolling slowly. Second

null 3 Dec 15, 2022
A flutter deskstop package that allows you to drag the native file into app support.

FileDragAndDrop A flutter deskstop package that allows you to drag the native file into app support. Platform Support Now only support on macOS, if an

逸风 13 Oct 24, 2022
A flutter plugin to support drag-out functionality on native platforms

flutter_native_drag_n_drop A flutter plugin to support the native drag and drop, especially to drag files (only files) out of the application boundary

Skalio GmbH 5 Oct 28, 2022
ESP-Touch Dart API for Flutter. Platform-specific implementation for Android (Java) and iOS (Objective-C).

esptouch_flutter Flutter plugin for ESP-Touch to configure network for ESP-8266 and ESP-32 devices. Runs on iOS and Android. esptouch_flutter is Flutt

SMAHO Engineering OSS 86 Dec 10, 2022
An online Dart editor with support for console, web, and Flutter apps

DartPad DartPad is a free, open-source online editor to help developers learn about Dart and Flutter. You can access it at dartpad.dev. What is it? Wh

Dart 1.4k Jan 4, 2023
Flutter plugin that secures your secrets in keychain using biometric authentication (Fingerprint, Touch ID, Face ID...).

Flutter Locker ?? Flutter plugin that secures your secrets in keychain using biometric authentication (Fingerprint, Touch ID, Face ID...). It uses: Lo

Infinum 25 Nov 21, 2022
Alarm app where user setting with touch gesture by moving the hand clock

Alarm App Using Flutter Flutter alarm app where user setting with touch gesture by moving the hand clock How to run Clone this repository Run flutter

null 3 Sep 3, 2022
Parallax - A parallax package for touch-based devices, providing a visually appealing user experience

Parallax A parallax package for touch-based devices, providing a visually appeal

MEDAFOX 4 Sep 28, 2022
This app can solve your problem! Play with fluids with a touch of your fingers

Feel bored or anxious? This app can solve your problem! Play with fluids with a touch of your fingers. Play and experiment with these swirling substances. Gorgeous visuals will take your breath away and help you to relieve stress.

Naser 17 Dec 30, 2022
A zero-dependency web framework for writing web apps in plain Dart.

Rad Rad is a frontend framework for creating fast and interactive web apps using Dart. It's inspired from Flutter and shares same programming paradigm

null 70 Dec 13, 2022
Drop shadow effect for any widget in Flutter

DropShadow Drop shadow effect for any widget in flutter Parameters Widget child; // required double blurRadius; // default: 10.0 double borderRadius;

null 10 Nov 26, 2022
A flutter list view which can drag & move item to change order.

draggable_flutter_list A flutter list view which can drag & move item to change order. some codes come from flutter_list_drag_and_drop fix flutter_lis

刘彦博 40 Sep 22, 2022
A page transition which supports drag-down-to-pop gesture.

drag_down_to_pop A page transition which supports drag-down-to-pop gesture. The main source code is copied from the cupertino/route.dart in Flutter SD

nekocode 16 Aug 6, 2022
Flutter plugin, support android/ios.Support crop, flip, rotate, color martix, mix image, add text. merge multi images.

image_editor The version of readme pub and github may be inconsistent, please refer to github. Use native(objc,kotlin) code to handle image data, it i

FlutterCandies 317 Jan 3, 2023