Giter VIP home page Giter VIP logo

vue-smooth-dnd's Introduction

Vue Smooth DnD

A fast and lightweight drag&drop, sortable library for Vue.js with many configuration options covering many d&d scenarios.

This library consists wrapper Vue.js components over smooth-dnd library.

Demo

View the demo here:

Installation

npm i vue-smooth-dnd

Usage

Vue

<template>
  <div>
    <div class="simple-page">
        <Container @drop="onDrop">            
          <Draggable v-for="item in items" :key="item.id">
            <div class="draggable-item">
              {{item.data}}
            </div>
          </Draggable>
        </Container>
    </div>
  </div>
</template>

<script>
import { Container, Draggable } from "vue-smooth-dnd";
import { applyDrag, generateItems } from "./utils";
export default {
  name: "Simple",
  components: { Container, Draggable },
  data() {
    return {
      items: generateItems(50, i => ({ id: i, data: "Draggable " + i }))
    };
  },
  methods: {  
    onDrop(dropResult) {
      this.items = applyDrag(this.items, dropResult);
    }
  }
};
</script>

API: Container

Component that contains the draggable elements or components. Each of its children should be wrapped by Draggable component

Properties

Properties define the visual behaviour of the library:

Property Type Default Description
:orientation string vertical Orientation of the container. Can be horizontal or vertical.
:behaviour string move Property to describe weather the dragging item will be moved or copied to target container. Can be move or copy or drop-zone or contain.
:tag string or NodeDescription div See descriptions below
:group-name string undefined Draggables can be moved between the containers having the same group names. If not set container will not accept drags from outside. This behaviour can be overriden by shouldAcceptDrop function. See below.
:lock-axis string undefined Locks the movement axis of the dragging. Possible values are x, y or undefined.
:drag-handle-selector string undefined Css selector to test for enabling dragging. If not given item can be grabbed from anywhere in its boundaries.
:non-drag-area-selector string undefined Css selector to prevent dragging. Can be useful when you have form elements or selectable text somewhere inside your draggable item. It has a precedence over dragHandleSelector.
:drag-begin-delay number 0 (200 for touch devices) Time in milisecond. Delay to start dragging after item is pressed. Moving cursor before the delay more than 5px will cancel dragging.
:animation-duration number 250 Animation duration in milisecond. To be consistent this animation duration will be applied to both drop and reorder animations.
:auto-scroll-enabled boolean true First scrollable parent will scroll automatically if dragging item is close to boundaries.
:drag-class string undefined Class to be added to the ghost item being dragged. The class will be added after it's added to the DOM so any transition in the class will be applied as intended.
:drop-class string undefined Class to be added to the ghost item just before the drop animation begins.
:remove-on-drop-out boolean undefined When set true onDrop will be called with a removedIndex if you drop element out of any relevant container
:drop-placeholder boolean,object undefined Options for drop placeholder. className, animationDuration, showOnTop

tag

Tag name or the node definition to render the root element of the Container. Default value is 'div'.

:tag="{value: 'table', props: {class: 'my-table'}}"
tag="table"

possible values


Lifecycle

The lifecycle of a drag is both described, and can be controlled, by a series of callbacks and events, which are illustrated below for a example containing 3 containers:

Mouse     Calls  Callback / Event       Parameters              Notes

down   o                                                        Initial click

move   o                                                        Initial drag
       |
       |         get-child-payload()    index                   Function should return payload
       |
       |   3 x   should-accept-drop()   srcOptions, payload     Fired for all containers
       |
       |   3 x   drag-start             dragResult              Fired for all containers
       |
       |         drag-enter
       v

move   o                                                        Drag over containers
       |
       |   n x   drag-leave                                     Fired as draggable leaves container
       |   n x   drag-enter                                     Fired as draggable enters container
       v

up     o                                                        Finish drag

                 should-animate-drop()  srcOptions, payload     Fires once for dropped container

           3 x   drag-end               dragResult              Fired for all containers

           n x   drop                   dropResult              Fired only for droppable containers

Note that should-accept-drop is fired before every drag-start, and before every drag-end, but has been omitted here for clarity.

The dragResult parameter has the format:

dragResult: {
    payload,
    isSource,
    willAcceptDrop,
}

The dropResult parameter has the format:

dropResult: {
    addedIndex,
    removedIndex,
    payload,
    droppedElement,
}

Note that additional parameters can be passed to callbacks and event handlers by writing an interim handler inline in the markup:

<div v-for="(items, index) in groups"
  <Container group-name="column"
    :should-accept-drop="(src, payload) => getShouldAcceptDrop(index, src, payload)"
    >
    ...
  </Container>
</div>

This can provide handler functions context-sensitive data, such as the loop index or current item.

Callbacks

Callbacks provide additional logic and checks before and during user interaction.

get-child-payload()

The function to be called to get the payload object to be passed onDrop function.

<Container :get-child-payload="getChildPayload">
getChildPayload (index) {
  return {
    // generate custom payload data here
  }
}

Parameters

  • index : number : index of the child item

Returns

  • payload : object

should-accept-drop()

The function to be called by all containers before drag starts to determine the containers to which the drop is possible. Setting this function will override the group-name property and only the return value of this function will be taken into account.

<Container :should-accept-drop="shouldAcceptDrop">
shouldAcceptDrop (sourceContainerOptions, payload) {
  return true;
}

Parameters

  • sourceContainerOptions : object : options of the source container. (parent container of the dragged item)
  • payload : object : the payload object retrieved by calling get-child-payload function.

Returns

  • boolean : true / false

should-animate-drop()

The function to be called by the target container to which the dragged item will be dropped. Sometimes dragged item's dimensions are not suitable with the target container and dropping animation can be wierd. So it can be disabled by returning false. If not set drop animations are enabled.

<Container :should-animate-drop="shouldAnimateDrop">
shouldAnimateDrop (sourceContainerOptions, payload) {
  return false;
}

Parameters

  • sourceContainerOptions : object : options of the source container. (parent container of the dragged item)
  • payload : object : the payload object retrieved by calling get-child-payload function.

Returns

  • boolean : true / false

get-ghost-parent()

The function to be called to get the element that the dragged ghost will be appended. Default parent element is the container itself. The ghost element is positioned as 'fixed' and appended to given parent element. But if any anchestor of container has a transform property, ghost element will be positioned relative to that element which breaks the calculations. Thats why if you have any transformed parent element of Containers you should set this property so that it returns any element that has not transformed parent element.

<Container :get-ghost-parent="getGhostParent">
getGhostParent() {
  // i.e return document.body;
}

Returns

  • Element : Any DOM element that the ghost will be appended in

Events

Events may call user-defined handlers at particular points in the drag-and-drop lifecycle.

@drag-start

Event to be emitted by all containers on drag start.

<Container @drag-start="onDragStart">
onDragStart (dragResult) {
  const { isSource, payload, willAcceptDrop } = dragResult
}

Parameters

  • dragResult : object

    • payload : object : the payload object that is returned by get-child-payload. It will be undefined in case get-child-payload is not set.
    • isSource : boolean : true if it is called by the container which drag starts from otherwise false.
    • willAcceptDrop : boolean : true if the dragged item can be dropped into the container, otherwise false.

@drag-end

The function to be called by all containers on drag end. Called before drop event.

<Container @drag-end="onDragEnd">
onDragEnd (dragResult) {
  const { isSource, payload, willAcceptDrop } = dragResult
}

Parameters

  • dragResult : object

    • isSource : boolean : true if it is called by the container which drag starts from, otherwise false.
    • payload : object : the payload object that is returned by get-child-payload function. It will be undefined in case get-child-payload is not set.
    • willAcceptDrop : boolean : true if the dragged item can be dropped into the container, otherwise false.

@drag-enter

The event to be emitted by the relevant container whenever a dragged item enters its boundaries while dragging.

<Container @drag-enter="onDragEnter">
onDragEnter () {
  ...
}

@drag-leave

The event to be emitted by the relevant container whenever a dragged item leaves its boundaries while dragging.

<Container @drag-leave="onDragLeave">
onDragLeave () {
  ...
}

@drop-ready

The function to be called by the container which is being drag over, when the index of possible drop position changed in container. Basically it is called each time the draggables in a container slides for opening a space for dragged item. dropResult is the only parameter passed to the function which contains the following properties.

<Container @drop-ready="onDropReady">
onDropReady(dropResult) {
  const { removedIndex, addedIndex, payload, element } = dropResult;
  ...
}

Parameters

  • dropResult : object
    • removedIndex : number : index of the removed children. Will be null if no item is removed.
    • addedIndex : number : index to add droppped item. Will be null if no item is added.
    • payload : object : the payload object retrieved by calling getChildPayload function.
    • element : DOMElement : the DOM element that is moved

@drop

The event to be emitted by any relevant container when drop is over. (After drop animation ends). Source container and any container that could accept drop is considered relevant.

<Container @drop="onDrop">
onDrop (dropResult) {
  const { removedIndex, addedIndex, payload, element } = dropResult;
  ...
}

Parameters

  • dropResult : object

    • removedIndex : number : index of the removed child. Will be null if no item is removed.
    • addedIndex : number : index to add dropped item. Will be null if no item is added.
    • payload : object : the payload object retrieved by calling get-child-payload function.
    • droppedElement : DOMElement : the DOM element that is moved

API: Draggable

Wrapper component for Container's children. Every child element should be wrapped with Draggable component.

Properties

tag

Tag name or the node definition to render the root element of the Draggable. Default value is 'div'.

:tag="{value: 'tr', props: {class: 'my-table-row'}}"
tag="tr"

possible values

vue-smooth-dnd's People

Contributors

alexandredavid avatar davestewart avatar desm avatar kutlugsahin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-smooth-dnd's Issues

Issue dropping below last item

First, great project.

I have followed table demo to create a table that I can drop items from different container as well as move order around in table.

Issue I am having is that if I try drag and drop below last row it often fails and just 'bounces' back to original position.

I have attached screenshots attempting to show issue.

I am using bootstrap and don't know if this is somehow causing issue but initial thoughts are it isn't.
sshots-1

Example of how to isolate drop target handler

Hi again :)

As per my last issue, I have a layout with a master list of items with different types, and a number of target lists:

I want to add a new drop target, which will have special behaviour.

If I drag any item from any list to this new "New List" group, on drop, I will first create a new list, then move the dragged item (or its model) into it:

Turn  Master    List 1              New List    Notes

1     A B                                       Initial state
2     A ------> B                               Drag B to "List 1", moves as normal
3.1   A           ----------------> B           Drag B to "New List" ...
3.2                     * List 2 *              ...manually create "List 2"
3.3                       B                     Move B to "List 2"

The New List container has roughly this markup:

<Container @drop="event => onItemDrop(event, true)">
...
</Container>

When I drag an item from any other List to the "New List" container, it works as expected - I can get the target and the payload, create the list model, add the item, and everything is fine.

However, the problem I am having is that when I drag any other item to any other list, the handler on this last group fires as well, and seems to intercept the non-related move.

How do I isolate other drags from this list's handlers?

How to use `sourceContainerOptions` on `should-accept-drop` ?

The should-accept-drop callback states:

The function to be called by all containers before drag starts to determine the containers to which the drop is possible. Setting this function will override the group-name property and only the return value of this function will be taken into account.

The callback is of the form:

shouldAcceptDrop: function(sourceContainerOptions, payload) {
  return true;
}

Parameters

  • sourceContainerOptions : Object : options of the source container. (parent container of the dragged item)
  • payload : Object : the payload object retrieved by calling get-child-payload function.

The sourceContainerOptions parameter is:

{
    groupName : "column"
    orientation : "vertical"
    behaviour : "move"
    autoScrollEnabled : true
    animationDuration: 250
    getChildPayload : ƒ (itemIndex)
    onDragEnd : ƒ (params)
    onDragEnter : ƒ ()
    onDragLeave : ƒ ()
    onDragStart : ƒ (params)
    onDrop : ƒ (dragResult)
    shouldAcceptDrop : ƒ (src, payload)
    shouldAnimateDrop : ƒ (src, payload)
}

How should one use these values to determine whether the container should be droppable?

There doesn't seem to be any other way to identify the original column, for example, any custom user attributes.

Does it relate to any other reference?

Generally, using your library in Vue, I have to bind an additional parameter to the markup, and reference this in the callback:

<div v-for="(items, index) in groups" :key="index">
  <Container group-name="column"
    :data-index="index"
    :should-accept-drop="(src, payload) => getShouldAcceptDrop(index, src, payload)">
    ...
  </Container>
</div>
getShouldAcceptDrop: function (index, sourceContainerOptions, payload) {
  return this.flags[index].droppable
},

In what circumstances is the sourceContainerOptions useful, and how should one use it to help determine the return value?

drag n drop with replace

I was wondering if you could provide a working example or perhaps guidance on how to implement drag and drop between two containers with the ability to "swap" items when dropped on an existing draggable. I have tried creating a Container in the draggables but have not had success.

Thank you in advance for any help you can provide...

Item gets copied when it shouldn't when limiting "should-accept-drop"

Hi and thanks for this nice package,

I try to set up logic whereby a container does not accept a new list item if it has only 1 element in it.

The "should-accept-drop" function achieves this, but also produces the following bug:
If I want to take the last item out, it makes a copy, rather than emptying the container.

pls see here: codesandbox.io/s/wkpzqk4mmk

The use case I have is: A user fills a number of empty containers from a populated list. He can only put 1 item in the container, but he can also take it out and put another item in. (It's for a field mapping project where you allocate table columns to a template...)

License clarification

Hi, what is the license for this package? It seems to be missing license files and markers.

Descendant CSS selectors on draggable items

My draggable elements lose formatting while being dragged when I use a descendant CSS selector:

.card {...} // works

.admin .card {...} // does not work

I can't figure out a workaround. Any ideas?

Nice Library, but how would I .....

Hi Vue-smooth-dnd,

Very nice library you have created and some really good examples and documentation.

For my needs I'm looking at the Copy Draggable example and your API doco.
What I can't work out is how to control the 'dropzone' so that it is obvious to the 'dragger' that the 'dropzone' is a valid target. I can see from the Copy example that the target container sorts items to let me know the dragged item can be dropped. However, I'm actually just wanting to have the container change color or show a boarder.

Again, awesome job on this lib.

How could I do this?

  • James.

Example that supports placeholders / gaps / blank spaces in a draggable list

Basically I'm trying to create something like this rather crude jQuery UI example.

  • You can drag any of the words to a free gap in any order
  • You can override a word with another (which returns the overridden word back to the pool)
  • You can drag an allocated word back to the pool leaving the gap open as it was
  • You can remove a word once it is allocated to a gap using the close button

I've looked at the examples, but it seems like they don't allow "blank" items to exist.

Does anyone know of an example that supports this, or have an idea how it can be achieved with this library?

Use in conjunction with transition-group

<Container @drop="onDrop">
    <transition-group name="list">
        <Draggable v-for="(conn) in connections" :key="conn.id">
            <h1>{{conn.name}}</h1>
        </Draggable>
    </transition-group>
</Container>

That doesn't work. Is it possible to animate enter/leave as well as drag & drop using vue-smooth-dnd?

Speed Issue

Good job with the component, but on Fedora 27 with Version 65.0.3325.181 (Official Build) (64-bit) the speed is slow (card demo). Very slow, with substantial delay, "jumpy" effects and CPU spikes.

CPU jumps to 77%

see the CPU spike
image

Get $event on drag-enter/drag-leave

I am having an issue grabbing the event from these handlers. They fire okay but I am not sure how to get the event.

@drag-enter="onDragEnter($event)"

function onDragEnter(e) {
   console.log(e) //returns undefined
}

I've also tried adding vanilla events and they don't seem to work. Even a click handler does not work. Is there a way I can get the event from those two drag events?

Is there a way to make containers with same group the same height?

I am working on an application where it is needed to drag orders from one column to the other. If one column is very large and the target column is almost empty, the user will have to drag the order to the top of the screen before dropping. If the target column is empty, it is very hard to "find" the container (find the place where to drop, so the onDrop function will be called).

Is there a way to make all the columns equal in height? I didn't see it in the demo.

How prevent click after drag is done?

All browsers works fine but in Firefox click works incorrectly.

How to prevent click after drag is done? Or how to change click event on Draggable component

`should-accept-drop` appears to fires more times than expected

I've been building a "lifecycle" demo to fully understand how things work in Smooth DnD. (I'll submit this as a PR when done)

If I start with 3 columns of draggables, then drag item 1 from column 1 to column 3:

image

I get the following lifecycle events:

--> MOUSEDOWN + DRAG

    get-child-payload

3 x should-accept-drop

    should-accept-drop
    drag-start
    should-accept-drop
    drag-start
    should-accept-drop
    drag-start

    drag-enter

--> MOUSE MOVE

    drag-leave
    drag-enter
    drag-leave
    drag-enter

--> MOUSEUP

    should-animate-drop
    
    should-accept-drop
    drag-end
    should-accept-drop
    drag-end
    should-accept-drop
    drag-end
    
3 x drop

The docs for should-accept-dropstate it is: "the function to be called by all containers before drag starts to determine the containers to which the drop is possible".

Therefore, I don't understand why there appear to be two very similar executions of should-accept-drop at the start of the drag. The wording above suggests it should be the second set, though the first set seems more obvious:

  • the 3 x should-accept-drops before all drag-starts
  • the extra should-accept-drops before each of the drag-starts

Then, there is this additional set at the end of the drag:

  • the extra should-accept-drops before each of the drag-ends

I have the latest master, and have installed all the latest dependencies.

I've forked the repo and the demo is here:

Is this expected?

Thanks!

Example of how to prevent an item being dragged into another group

Hey, hey!

As per my last issue, I have a layout with a master list of items with different types, and a number of target lists:

I can drag items from the master to the targets, but only if the list is empty, or there if the list already contains items of the same type:

Turn  Master          List 1      List 2    Notes

1     A1 A2 B1 B2                           Initial state
2     A2 B1 B2 -----> A1                    Drag A1 to List 1, making it an A style list
3     A2 B2 --------------------> B1        Drag B1 to List 2, making it a B style list
4     B2 -----------------------x A2        Drag A2 to List 2, don't allow A's with B's!

I have to idea how to do this!

I presume I need to do some kind of check at some point, looping over the items of the target model (I am updating arrays, of course) but I don't know in which handlers or callbacks to do this.

Is there any example code using the handlers and callbacks?

It is very confusing to me I have to say :(

Inline-block layout style dragging possible?

I have a new project and am reaching for vue smooth dnd :)

We have a requirement to drag tags from a vertical master list on the left, to any number of horizontal target lists on the right:

image

Each target would comfortably take, say 10 or so tags, but would then "fill up". As such, we then want to wrap onto the next line, potentially expanding the target area vertically.

I'm not sure if this is even possible right now.

Can you advise?

Thanks.

flex wrap support

Hello.
The drag & drop looks nice and smooth. But looks like it does not support wrapped elements. Any plans to implement it in the future?

Use Original Element for Ghost

Currently the ghost is cloned from the dragged item, and the original is left in place with visibility:hidden applied. The ghost is then appended to the container.

There are a few issues with this that I've come across:

  • Jank when ghost is cloned from an element with a lot of child nodes. Honestly, not sure how much not cloning and using original would improve this.
  • Cloned ghost does not respect the scroll position of nested content. In these situations the drag becomes a bit jarring to look at.
  • Having the ghost inserted into the container as the last element makes for more annoying CSS selectors, since you can no longer use :last-child.

A look at how Trello handles it... they leave behind a simple div placeholder and move the original item out of the container into an upper level body div.

Typescript Definition files

Hi, do you have any plans to include Typescript Definition files in vue-smooth-dnd (and smooth-dnd would also need one)?

If not, I might investigate creating them, if I did that would you accept a pull request?

Right-click on an item selects it

First of all, great work on making a dragging library for Vue with a sane API. I think it could be made simpler in some ways (especially around the getChildPayload paradigm). But thats another topic!

I'm trying to improve the UX of the app I'm working on by allowing the user to right click an item to get access to "Open in New Tab/Window" etc..

But when I right click an item and the click away from the context menu, the library selects the item I right clicked for dragging.

kapture 2018-05-25 at 11 03 08

Reproducible in your docs : https://kutlugsahin.github.io/vue-smooth-dnd/

Determine Target onDrop

Great package! I am just struggling on finding which container an item is being dragged INTO. So the scenario is to drag from one list to another and post to server the change. HOW do I know which container received the item ... it isn't in the payload nor the props.

Thanks in advance!!!

How to make copy and cards together

I cannot make cards and copy together
I try to do:

<Container
    :group-name="column.id"
    @drop="(e) => onCardDrop(column.id, e)"
    @drag-start="(e) => log('drag start', e)"
    @drag-end="(e) => log('drag end', e)"
    :get-child-payload="getCardPayload(column.id)"
    drag-class="card-ghost"
    drop-class="card-ghost-drop"
    behaviour="copy"
>

Transform CSS property positions ghost element improperly

If there is a transform property on a containing element of the draggable items the ghost element will be shifted improperly, even if the transform doesn't actually move the element; e.g. translateX(0).

Demo:
https://codesandbox.io/s/6y0nl531or

I'm not sure if this is something you'd want to handle in the codebase or if it's expected for the user to just negate the offset by styling the ghost element with an opposite transform, but it took me a bit to figure out what was going on with my use case -- dragging copy elements out of a Vuetify side drawer positioned to the right of the screen.

Vue-js Nested component draggable

Hello!

I have a situation where I have a difficult scenario.
1- There are three separate components, which may be draggable within themselves
2- These three components may also be draggable in a single line

How can I do that?

vue-smooth-dnd integration with quasar ui framework broken on mobile platforms

I am trying to integrate the vue-smooth-dnd plugin (which I am generally loving, by the way) with the Quasar UI framework on top of vue.js. Things seems to work wonderfully with desktop browsers (Chrome and Safari), as well as mobile emulation in the desktop browser. However, when I test on real mobile devices (iOS 11+ in particular) with Chrome and Safari, it seems the "preventDefault" of the drag / mouse-move event does not function properly, and results in unusable drag/drop functionality. The window flickers terribly, and the window scrolling is not controllable, basically rendering the drag-and-drop unusable.

I have been able to test and use the vue-smooth-dnd without the Quasar framework, and the drag-and-drop works beautifully on mobile devices, so there is something in particular about using vue-smooth-dnd with Quasar that doesn't seem to work correctly. Hoping you can help identify a solution to get this working more smoothly.

NPMs:
[email protected]
[email protected]
[email protected]

I am new to this development space, so I appreciate the patience and help.

Multiple select drag & drop

Hi is there a way that I could select multiple cards and transfer it on another column at the same time ?

Nesting more than one deep gets events for all parent container

Hi

I have been trying to use your smooth-dnd for a hierarchical data set but if I have more than 1 deep nesting I get onDrop events for all containers and not just the source and destination.

I have modified your demo to include an extra nesting and this results in the following dropResults :

  1. container 3 : removedIndex: null, addedIndex: 0
  2. container 2 : removedIndex: null, addedIndex: 2
  3. container 1 : removedIndex: 4, addedIndex: 4

I would have expected

  1. container 3 : removedIndex: null, addedIndex: 0
  2. container 1 : removedIndex: 4, addedIndex: null

I have attached the modified file for clarification

Thanks

nested.zip

ps Works really nicely otherwise, great module

Rollup import

Error using rollup (webpack works):

import { Container, Draggable } from 'vue-smooth-dnd'

[!] Error: 'Container' is not exported by node_modules/vue-smooth-dnd/dist/vue-smooth-dnd.js
https://github.com/rollup/rollup/wiki/Troubleshooting#name-is-not-exported-by-module

add support for set tag

It would be nice to set a tag for container and draggable like:

<Container tag="table">
    <Draggable tag="tr>
        ...
    </Draggable>
</Container>

Feature Request: Option to remove item when dropped outside of container.

Maybe I missed something much simpler (I sure hope not...), but it took me quite a bit of playing around with the current API to make this work.

In case anyone needs this functionality too, here's how I did it:
I ended up tracking when the dragged item would leave its original container's bounds, and whether it moved back into it (dragEnter, dragLeave).

I also needed to track if the dragged item entered the bounds of any other containers that returned should-accept-drop as true, because onDrop fires too late for me to interrupt the drag end animation in case it wasn't dropped.

Then I had to implement a mouseup listener on an upper level container so it would catch the drag release (dragEnd fires too late) and modify the style attributes applied as follows:

// transitionProperty order: left, top, opacity, transform
ghostEl.style.transitionDelay = '5s, 5s, 0s, 0s'
ghostEl.style.transitionDuration = '0.25s'

I was unable to figure out a way to set the transition attributes beforehand, as doing so would affect the animation of dragging the ghost too. There is a position: left & top applied to the ghost item when it is released to simulate it "returning" to its original spot. The styles above combined with a scaling effect simulate a disappearing animation (it's the same one used when you drag items out of a smooth-dnd "copy" container and drop them in the middle of nowhere). shouldAnimateDrop cannot be used for any of this since it's technically not a drop to release outside of a container.

Originally I had considered wrapping all my drop containers with a "board" container which could then detect drops onto it... but I couldn't get that to work.

Body scroll while dragging?

Hi,

Just wanted to ask how the scroll works? I have checked the examples and if I remove overflow: auto from the demo (.demo), it stops working. I wonder if it's possible to make the whole page (body) to scroll while dragging?

Library doesn't build to es5?

Hi,

I use this awesome library and IE 10 gives error because of the const used in build version of this library. Is it possible to build (dist) this library to use ES5?

Some questions

Hey,

I tried to make dnd group only, the problem is that when I move my draggable, it can go out and I want to not able to do that. In Addition, I tried to make dropzone for only child elements inside the groups and I got some errors, can you help me and suggest how to do it?

Dragging does not work correctly with new data which are added after initial initialization

Hi.
First of all thank you for this library and your work.
Unfortunately I have one thing, which does not work.

In your demos and in my code below we have initial data, which works ok from the beginning, but I have a problem when data changes dynamically.

In the demo below there are 2 playlists (one empty - Electro and Slow - with 3 nested tracks).
I need to copy these 3 tracks to the empty playlist. Once tracks are copied to the empty playlist (Electro), there is no smooth 'sliding' effect when you drag any track in this Electro playlist and tracks not always change its position, however dragging continues to be ok in the Slow playlist.

Demo\Sandbox
https://codesandbox.io/s/zqv9m19v8l

I found that the problem is with the first :key (for playlists). If replace :key="playlistObj.playlistTitle" by :key="Math.floor(Math.random() * (100 - 1)) + 1" it starts to work. Any ideas?

Thanks a lot!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.