Vue drag-and-drop component based on Sortable.js

Related tags

component vue drag-and-drop
Overview

Vue.Draggable

CircleCI Coverage codebeat badge GitHub open issues npm download npm download per month npm version MIT License

Vue component (Vue.js 2.0) or directive (Vue.js 1.0) allowing drag-and-drop and synchronization with view model array.

Based on and offering all features of Sortable.js

For Vue 3

See vue.draggable.next

Demo

demo gif

Live Demos

https://sortablejs.github.io/Vue.Draggable/

https://david-desmaisons.github.io/draggable-example/

Features

  • Full support of Sortable.js features:
    • Supports touch devices
    • Supports drag handles and selectable text
    • Smart auto-scrolling
    • Support drag and drop between different lists
    • No jQuery dependency
  • Keeps in sync HTML and view model list
  • Compatible with Vue.js 2.0 transition-group
  • Cancellation support
  • Events reporting any changes when full control is needed
  • Reuse existing UI library components (such as vuetify, element, or vue material etc...) and make them draggable using tag and componentData props

Backers

Admin Dashboard Templates made with Vue, React and Angular.

Donate

Find this project useful? You can buy me a or a 🍺

paypal

Installation

With npm or yarn

yarn add vuedraggable

npm i -S vuedraggable

Beware it is vuedraggable for Vue 2.0 and not vue-draggable which is for version 1.0

with direct link

<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.5.2/vue.min.js"></script>
<!-- CDNJS :: Sortable (https://cdnjs.com/) -->
<script src="//cdn.jsdelivr.net/npm/[email protected]/Sortable.min.js"></script>
<!-- CDNJS :: Vue.Draggable (https://cdnjs.com/) -->
<script src="//cdnjs.cloudflare.com/ajax/libs/Vue.Draggable/2.20.0/vuedraggable.umd.min.js"></script>

cf example section

For Vue.js 2.0

Use draggable component:

Typical use:

<draggable v-model="myArray" group="people" @start="drag=true" @end="drag=false">
   <div v-for="element in myArray" :key="element.id">{{element.name}}</div>
</draggable>

.vue file:

  import draggable from 'vuedraggable'
  ...
  export default {
        components: {
            draggable,
        },
  ...

With transition-group:

<draggable v-model="myArray">
    <transition-group>
        <div v-for="element in myArray" :key="element.id">
            {{element.name}}
        </div>
    </transition-group>
</draggable>

Draggable component should directly wrap the draggable elements, or a transition-component containing the draggable elements.

With footer slot:

<draggable v-model="myArray" draggable=".item">
    <div v-for="element in myArray" :key="element.id" class="item">
        {{element.name}}
    </div>
    <button slot="footer" @click="addPeople">Add</button>
</draggable>

With header slot:

<draggable v-model="myArray" draggable=".item">
    <div v-for="element in myArray" :key="element.id" class="item">
        {{element.name}}
    </div>
    <button slot="header" @click="addPeople">Add</button>
</draggable>

With Vuex:

<draggable v-model='myList'>
computed: {
    myList: {
        get() {
            return this.$store.state.myList
        },
        set(value) {
            this.$store.commit('updateList', value)
        }
    }
}

Props

value

Type: Array
Required: false
Default: null

Input array to draggable component. Typically same array as referenced by inner element v-for directive.
This is the preferred way to use Vue.draggable as it is compatible with Vuex.
It should not be used directly but only though the v-model directive:

<draggable v-model="myArray">

list

Type: Array
Required: false
Default: null

Alternative to the value prop, list is an array to be synchronized with drag-and-drop.
The main difference is that list prop is updated by draggable component using splice method, whereas value is immutable.
Do not use in conjunction with value prop.

All sortable options

New in version 2.19

Sortable options can be set directly as vue.draggable props since version 2.19.

This means that all sortable option are valid sortable props with the notable exception of all the method starting by "on" as draggable component expose the same API via events.

kebab-case propery are supported: for example ghost-class props will be converted to ghostClass sortable option.

Example setting handle, sortable and a group option:

<draggable
        v-model="list"
        handle=".handle"
        :group="{ name: 'people', pull: 'clone', put: false }"
        ghost-class="ghost"
        :sort="false"
        @change="log"
      >
      <!-- -->
</draggable>

tag

Type: String
Default: 'div'

HTML node type of the element that draggable component create as outer element for the included slot.
It is also possible to pass the name of vue component as element. In this case, draggable attribute will be passed to the create component.
See also componentData if you need to set props or event to the created component.

clone

Type: Function
Required: false
Default: (original) => { return original;}

Function called on the source component to clone element when clone option is true. The unique argument is the viewModel element to be cloned and the returned value is its cloned version.
By default vue.draggable reuses the viewModel element, so you have to use this hook if you want to clone or deep clone it.

move

Type: Function
Required: false
Default: null

If not null this function will be called in a similar way as Sortable onMove callback. Returning false will cancel the drag operation.

function onMoveCallback(evt, originalEvent){
   ...
    // return false; — for cancel
}

evt object has same property as Sortable onMove event, and 3 additional properties:

  • draggedContext: context linked to dragged element
    • index: dragged element index
    • element: dragged element underlying view model element
    • futureIndex: potential index of the dragged element if the drop operation is accepted
  • relatedContext: context linked to current drag operation
    • index: target element index
    • element: target element view model element
    • list: target list
    • component: target VueComponent

HTML:

<draggable :list="list" :move="checkMove">

javascript:

checkMove: function(evt){
    return (evt.draggedContext.element.name!=='apple');
}

See complete example: Cancel.html, cancel.js

componentData

Type: Object
Required: false
Default: null

This props is used to pass additional information to child component declared by tag props.
Value:

  • props: props to be passed to the child component
  • attrs: attrs to be passed to the child component
  • on: events to be subscribe in the child component

Example (using element UI library):

<draggable tag="el-collapse" :list="list" :component-data="getComponentData()">
    <el-collapse-item v-for="e in list" :title="e.title" :name="e.name" :key="e.name">
        <div>{{e.description}}</div>
     </el-collapse-item>
</draggable>
methods: {
    handleChange() {
      console.log('changed');
    },
    inputChanged(value) {
      this.activeNames = value;
    },
    getComponentData() {
      return {
        on: {
          change: this.handleChange,
          input: this.inputChanged
        },
        attrs:{
          wrap: true
        },
        props: {
          value: this.activeNames
        }
      };
    }
  }

Events

  • Support for Sortable events:

    start, add, remove, update, end, choose, unchoose, sort, filter, clone
    Events are called whenever onStart, onAdd, onRemove, onUpdate, onEnd, onChoose, onUnchoose, onSort, onClone are fired by Sortable.js with the same argument.
    See here for reference

    Note that SortableJS OnMove callback is mapped with the move prop

HTML:

<draggable :list="list" @end="onEnd">
  • change event

    change event is triggered when list prop is not null and the corresponding array is altered due to drag-and-drop operation.
    This event is called with one argument containing one of the following properties:

    • added: contains information of an element added to the array
      • newIndex: the index of the added element
      • element: the added element
    • removed: contains information of an element removed from to the array
      • oldIndex: the index of the element before remove
      • element: the removed element
    • moved: contains information of an element moved within the array
      • newIndex: the current index of the moved element
      • oldIndex: the old index of the moved element
      • element: the moved element

Slots

Limitation: neither header or footer slot works in conjunction with transition-group.

Header

Use the header slot to add none-draggable element inside the vuedraggable component. Important: it should be used in conjunction with draggable option to tag draggable element. Note that header slot will always be added before the default slot regardless its position in the template. Ex:

<draggable v-model="myArray" draggable=".item">
    <div v-for="element in myArray" :key="element.id" class="item">
        {{element.name}}
    </div>
    <button slot="header" @click="addPeople">Add</button>
</draggable>

Footer

Use the footer slot to add none-draggable element inside the vuedraggable component. Important: it should be used in conjunction with draggable option to tag draggable elements. Note that footer slot will always be added after the default slot regardless its position in the template. Ex:

<draggable v-model="myArray" draggable=".item">
    <div v-for="element in myArray" :key="element.id" class="item">
        {{element.name}}
    </div>
    <button slot="footer" @click="addPeople">Add</button>
</draggable>

Gotchas

  • Vue.draggable children should always map the list or value prop using a v-for directive

    • You may use header and footer slot to by-pass this limitation.
  • Children elements inside v-for should be keyed as any element in Vue.js. Be carefull to provide revelant key values in particular:

    • typically providing array index as keys won't work as key should be linked to the items content
    • cloned elements should provide updated keys, it is doable using the clone props for example

Example

Full demo example

draggable-example

For Vue.js 1.0

See here

Issues
  • Integrate MultiDrag plugin.

    Integrate MultiDrag plugin.

    I got some work... releated #104, #536, #649 :rocket:

    • Example included.
    • Unit test not written.
    • With my bad english, you should update README with good language.
    opened by divinespear 55
  • problems with nesting

    problems with nesting

    update

    • items cant be moved under eachother, only be moved outside.

    • using v-model="childs" which is the same array that is used in the v-for gives error that its an object not array, shouldn't the same item that works for v-for also works for the v-model ?

    • when moving an item from the nested menu to the parent, the parent list doesnt get updated, even though that both are under the same group name, also tried to use :list="$parent.pages" but doesnt work

    • trying to add an item under nest, makes it disappear

    • when an item is re-dragged after it was moved out of the nested menu, we get an error and everything stops working

    help wanted question 
    opened by ctf0 38
  • transition groups on sorting table rows

    transition groups on sorting table rows

    Is it possible to add a transition group on sorting table rows?

    <table>
      <draggable :element="'tbody'">
        <transition-group><!-- create a span tag by default -->
          <tr v-for="person in people" v-bind:key="person">
          </tr>
        </transition-group>
      </draggable>
    </table>
    

    Currently the above fails because the HTML output is:

    <table>
      <tbody>
        <span><!-- having the span here messes up rendering -->
          <tr></tr>
          <tr></tr>
        </span>
      </tbody>
    </table>
    
    question 
    opened by daveroberts 26
  • related not consistent?

    related not consistent?

    I'm trying to determine the desired dropped position of an element in the destination list using the move callback. I was going to check the index of the related entry, and therefore add 1 to the index position so I know where the desired dropped item would be. However I seem to be getting different results. Is the related element always the item before where it is being dropped?

    For context I'm building a report builder, you drag items from one list into your page. The items will either be 1/4 of the page, 1/2 of the page, or a full page... and I need to ensure certain conditions are met.

    Thanks,

    • Vince
    opened by vmitchell85 24
  • Nested dragging may cause unexpected DOM change

    Nested dragging may cause unexpected DOM change

    Our app has two-level nested draggable items and has list defined/mapped.

    When dragging an item in the inner list, sometimes the DOM may update incorrectly, and when it happens, the item being dragged will jump to the beginning of the list. The vue data, however, is correct/as expected. So it seems like the DOM is updated inconsistently w.r.t. the event, whereas the vue data is fine.

    We tried to make a reproducible demo: https://jsfiddle.net/6sha4vv6/1/

    Dragging Wildcard Courses x to the place of Multiple Courses x and release can cause the former to jump to the first position.

    opened by nivekz 20
  • this.context == null because of hitting the edge case

    this.context == null because of hitting the edge case

    Just want to note - in my setup I'm hitting the edge case in getUnderlyingVm method. Somehow the index is -1 and the code returnes null but you aren't checking anywhere to catch this edge case again, see the methods:

    • onDragStart
    • onDragRemove
    • onDragUpdate

    Because of this I'm not able to work with multiple, dynamic updating arrays of arrays - draggable is pointed at a sub-array. I have to unshift and push to the array -> unshifting on the array - adding a new array at the beginning of the array causes the index to become -1 - maybe looking at a old version of the array?

    opened by ThaDaVos 20
  • webpack error

    webpack error

    ERROR in ./~/vuedraggable/dist/vuedraggable.js
    Module not found: Error: Cannot resolve module 'Sortable' in /Users/lzxb/Documents/zhima-admin-webapp/node_modules/vuedraggable/dist
     @ ./~/vuedraggable/dist/vuedraggable.js 202:4-204:6
    
    opened by lzxb 19
  • TypeScript: Added types in 2.24.0 causing issues

    TypeScript: Added types in 2.24.0 causing issues

    Since release v2.24.0, vuedraggable includes typing information for the package. While this is generally super useful to have included out of the box, it's causing a bit of a problem for me currently:

    I'm getting an error from TypeScript originating in vuedraggable when trying to compile my app after updating to v2.24.0:

    ERROR in /Users/rijk/[redacted]/node_modules/vuedraggable/src/vuedraggable.d.ts(8,5):
    8:5 Property 'element' in type 'Draggable' is not assignable to the same property in base type 'object & Record<never, any> & Vue'.
      Type 'string' is not assignable to type 'Element | null'.
         6 |     noTransitionOnDrag: boolean;
         7 |
      >  8 |     element: string;
           |     ^
         9 |
        10 |     tag: string;
        11 |
    

    Next to this, TypeScript keeps complaining that the Draggable class can't be used in components as Draggable can't be assigned to VueConstructor<Vue>*:

    No overload matches this call.
      Overload 3 of 3, '(options: ComponentOptionsWithProps<{ collection: { type: StringConstructor; required: true; }; }, Data, Data, {}, {}, { collection: string; } & {}>): VueProxy<...>', gave the following error.
        Type 'typeof Draggable' is not assignable to type 'VueConstructor<Vue> | FunctionalComponentOptions<any, PropsDefinition<any>> | ComponentOptions<never, any, any, any, any, Record<...>> | AsyncComponentPromise<...> | AsyncComponentFactory<...>'.
          Type 'typeof Draggable' is not assignable to type 'VueConstructor<Vue>'.
    

    * This is when using @vue/composition-api

    opened by rijkvanzanten 18
  • Broken on Chrome 62

    Broken on Chrome 62

    This appears to no longer work in Chrome 62 (beta still, I think). This chrome bug impacts a lot of libraries.

    The original sortable.js also suffers, https://github.com/SortableJS/Vue.Draggable/issues

    Not sure the cause, will check it out if I get a chance.

    Sortable.js 
    opened by lmiller1990 18
  • Slot Footer Not Working with Transition Group

    Slot Footer Not Working with Transition Group

    Everything works, except when I try to add a non-draggable item with footer within a transition-group like this:

          <draggable v-model="myList" :options="{draggable:'.item'}">
            <transition-group name="animated-list">
              <div v-for="element in myList" :key="element" class="animated-list-item item">
                  <book :beat.sync="books[element]"></book>
              </div>
              <button slot="footer" key="button">Add Another Book</button>
            </transition-group>
          </draggable>
    

    If I remove transition-group it works as expected.

    opened by jhull 17
  • Can not drag inside iframe on mobile

    Can not drag inside iframe on mobile

    When the list stay inside an iFrame we can not drag it on mobile with Vue.Draggable. I have try it with Sortable.js already and it works fine.

    opened by Uysim 0
  • Only drag inside parent container - With overflow hidden

    Only drag inside parent container - With overflow hidden

    I guess this is more of a question, than an actual bug.

    Is it possible to make it so that it's only possible to drag items within a parent container with "overflow:hidden", like this: https://jmp.sh/K8bAP8c

    Even if i have overflow:hidden on my parent container, it still seems like when im dragging it's placing the dragged item on top of the page, instead when it should be hidden when dragging it outside the container, due to the overflow:hidden on my parent container?

    Is there anyway this is possible to achieve? I haven't found any way so far :(

    opened by nickycdk 0
  • Recursive rendering weird dragging behavior for nested elements

    Recursive rendering weird dragging behavior for nested elements

    EDIT: One more layer to this issue I noticed, The lowest level children when I try to drag it somewhere else it doesn't work, acts like it will but goes back where it was (i.e it's children are empty). But when I drag the parent of a child somewhere else it does one of the following:

    1. Moves the parent and it's parent somewhere else where I drag it, but leaves the child where it was i.e image Initial state on a refresh

    image After I drag col-2 to container-1

    or

    1. Moves the child into the container where I dragged the parent to but leaves the parent where it was i.e image Initial state on a refresh

    image After dragging col-2 into col-1

    Original Post

    Hey guys, been building a landing page builder and decided vue-draggable would be a nice addition. That said after 3 days of headaches trying to make this work I'm at a loss. So far I've followed the nested example guide which has been KINDA working, in addition I followed an issue about the nested guide on here adding an emitter to the children for proper updates. Now my getters and setters are firing BUT I'm still having a problem dragging elements(see the video)

    http://www.giphy.com/gifs/ZMiyi8LEcI73nye1ZN

    As you can see when I drag stuff around it's strange behavior:

    Example cases: When I drag col 2 label into col 1 it moves the children inside into col one, does not change col 2s place When I drag paragraph label anywhere it will not move, shows like it will but when I release nothing happens If I drag row 1 from the original starting state you saw in the gif into the paragraph I end up with the following: image

    Just 3 sample cases, references: https://sortablejs.github.io/Vue.Draggable/#/nested-with-vmodel https://github.com/SortableJS/Vue.Draggable/issues/701#issuecomment-686187071

    my code creating these results:

    component-renderer.vue (THERE'S A NOTE IN HERE TO READ)

      <draggable
        v-bind="dragOptions"
        :list="list"
        :value="value"
        style="position: relative; border: 1px solid red"
        :tag="data.tagName"
        :class="data.attributes.class + ` border border-danger p-3`"
        @input="emitter"
        @change="onChange" //NOTE: I've tried setting the group here to row instead of in the computed prop below, didn't work
      >
        <slot></slot>
    
        <component-renderer
          v-for="el in realValue"
          :key="el.attributes.id"
          :list="el.children"
          :data="el"
          :child="true"
          @change="onChange"
        >
          <span style="position: absolute; top: 0; left: 0; background: red">{{
            `${el.tagName} - ${el.attributes.id}`
          }}</span>
    
          {{ el.textNode }}
        </component-renderer>
      </draggable>
    </template>
    
    <script>
    import draggable from "vuedraggable";
    
    export default {
      name: "ComponentRenderer",
      components: {
        draggable,
      },
      props: {
        data: {
          required: false,
          type: Object,
          default: null,
        },
        value: {
          required: false,
          type: Array,
          default: null,
        },
        list: {
          required: false,
          type: Array,
          default: null,
        },
        child: {
          type: Boolean,
          default: false,
          required: false,
        },
      },
      computed: {
        dragOptions() {
          return {
            animation: 0,
            disabled: false,
            ghostClass: "row",
            group: "row",
          };
        },
        realValue() {
          return this.value ? this.value : this.list;
        },
      },
      methods: {
        emitter(value) {
          this.$emit("input", value);
        },
        onChange: function () {
          if (this.child === true) {
            this.$emit("change");
          } else {
            this.emitter(this.value);
          }
        },
      },
    };
    </script>
    
    <style scoped></style>
    

    PageEditor.vue:

      <div id="wysiwyg-page-editor">
        <ChargeOverNavBar />
        <div class="editor">
          <ComponentRenderer v-model="elements" :data="elements[0]" />
        </div>
        <ChargeOverFooter />
      </div>
    </template>
    
    <script>
    import ChargeOverNavBar from "@/components/ChargeOverNavBar";
    import ChargeOverFooter from "@/components/ChargeOverFooter";
    import InlineEditor from "@ckeditor/ckeditor5-build-inline";
    import ComponentRenderer from "@/components/module-editor/ComponentRenderer";
    
    export default {
      name: "PageEditor",
      components: {
        ComponentRenderer,
        ChargeOverFooter,
        ChargeOverNavBar,
      },
      data() {
        return {
          editor: InlineEditor,
          editorConfig: {},
    
          activeSection: null,
    
          page: {},
    
          panels: {
            pageProperties: true,
            seoProperties: true,
            sectionProperties: false,
          },
        };
      },
      computed: {
        elements: {
          get() {
            console.log("getter");
    
            return JSON.parse(JSON.stringify(this.$store.state.editor.editorData));
          },
          set(value) {
            console.log("setter");
            this.$store.dispatch("setEditor", value);
          },
        },
      },
    };
    </script>
    
    <style lang="scss" scoped>
    @use "../assets/scss/components/PageEditor";
    </style>
    

    editor.js(store module):

      state: {
        editorData: [],
        editorLoading: false,
      },
      mutations: {
        SAVE_EDITOR(state, data) {
          state.editorData = data;
        },
        TOGGLE_EDITOR_LOAD(state, busy) {
          state.editorLoading = busy;
        },
      },
      actions: {
        setEditor({ commit }, data) {
          commit("SAVE_EDITOR", data);
        },
        loadEditor({ commit }) {
          commit("TOGGLE_EDITOR_LOAD", true);
    
          //TODO: Change me to read API DATA
          let fakeData = [
            {
              tagName: "section",
              attributes: {
                id: "section-1",
                class: "test",
              },
              children: [
                {
                  tagName: "div",
                  attributes: {
                    id: "container-1",
                    class: "container",
                  },
                  children: [
                    {
                      tagName: "div",
                      attributes: {
                        id: "row-1",
                        class: "row",
                      },
                      children: [
                        {
                          tagName: "div",
                          attributes: {
                            id: "col-1",
                            class: "col",
                          },
                          children: [],
                        },
                        {
                          tagName: "div",
                          attributes: {
                            id: "col-2",
                            class: "col",
                          },
                          children: [
                            {
                              tagName: "p",
                              attributes: {
                                id: "p-1",
                                class: "p",
                              },
                              textNode: "This is my paragraph",
                              children: [],
                            },
                          ],
                        },
                      ],
                    },
                  ],
                },
              ],
            },
          ];
          commit("SAVE_EDITOR", fakeData);
          commit("TOGGLE_EDITOR_LOAD", false);
        },
      },
      getters: {
        getEditorData: (state) => state.editorData,
        getEditorLoading: (state) => state.editorLoading,
      },
    };
    

    It seems only dragging labels works for moving stuff around but not like i'd expect. I think this makes sense but why can't I drag the body anywhere? It's not slotted in header or footer and the docs says that's the onlytime it wouldn't be? Can I not use as the tag itself and drag it?

    One more note, as far as draggable goes, I can't render the tags inside of draggable as draggable wraps the tags in a div or a span which sucks because if you wrap a col in a div that's inside a row it breaks bootstrap :(

    As I'm sure all of you can deduce the behavior I'm expecting, anything should be draggable into any section(in the future I want this to change so only cols can be dragged into rows, rows can only be dragged into sections etc(but for now I'm not sure how to do this so we start at the beginning :D)).

    Also yes I know those components are kinda messy atm, until I fix this I'm not cleaning them up as I keep drastically changing the contents of these files trying to make it work, sorry its hacky atm!

    Any help or ideas would be amazing!

    Thanks guys!

    opened by Celtech 0
  • How to update sortable.js library?

    How to update sortable.js library?

    I used this plugin and found that it used sortable js old version. Sortable js fixed some Safari issue in their latest version. How to update?

    opened by animeshsa 6
  • Integrate MultiDrag plugin

    Integrate MultiDrag plugin

    For #104, #536, and #649 :rocket:

    #744 is superseded by this with:

    • Example included
    • Unit test included :tada:
    • implementation is more clearer then #744
    opened by divinespear 7
  • Why can't I use ES6's Array. from after this project is packaged

    Why can't I use ES6's Array. from after this project is packaged

    My Google browser version is 44 Shouldn't all packaging policies be converted to Es5? error message:

    TypeError: Array.from is not a function at _iterableToArray (webpack-internal:///./node_modules/vuedraggable/dist/vuedraggable.umd.js:2023:86) at _toConsumableArray (webpack-internal:///./node_modules/vuedraggable/dist/vuedraggable.umd.js:2035:37) at _computeIndexes (webpack-internal:///./node_modules/vuedraggable/dist/vuedraggable.umd.js:2083:20) at VueComponent.eval (webpack-internal:///./node_modules/vuedraggable/dist/vuedraggable.umd.js:2356:33) at Array.eval (webpack-internal:///./node_modules/vue/dist/vue.esm.js:1997:12) at flushCallbacks (webpack-internal:///./node_modules/vue/dist/vue.esm.js:1923:14)

    image

    image

    opened by huangwenboha563 0
  • How can i set a selected value without using the mouse (programmatically,  on init) ?

    How can i set a selected value without using the mouse (programmatically, on init) ?

    Currently, i am trying to select an item of the draggable-list programmatically / manually (without the usage of the mouse).

    This behaviour is important, because i want to make a pre-selection when the draggable-component is loaded. I wanted to use the "vuedraggable-multi" Fork (check #744 or https://github.com/divinespear/Vue.Draggable ) as well, which is based on this repository. This feature would allow me to select multiple elements for the drag-and-drop feature. I already tested the #744 and it works for me very well - sad to see that it is not merged yet.

    I have read, that the "MultiDrag.singleton.utils.select()"-Method is the way to go for this, but my current Implementation does not contain this singleton (MultiDrag.singleton is undefined when i am importing MultiDrag). This link describes how it should have worked: https://www.fabiofranchino.com/log/add-programmatically-a-draggable-element-in-vuedraggable-with-sortable/

    I can set the styling/css-class for the selected element manually, but this has no effect on the internal selection of the vueDraggable-component.

    Jsfiddle link

    N/A, since the feature does not exist yet afaik.

    Relevant code-parts:

    import { defineComponent, onMounted } from '@vue/composition-api';
    import VueDraggable from 'vuedraggable';
    import {Sortable, MultiDrag} from "sortablejs"; 
    
    if (!MultiDrag.singleton) {
       console.log("singleton should exist, when using vuedraggable - but it doesn't");
       MultiDrag.singleton = new MultiDrag();
       Sortable.mount(MultiDrag.singleton);
    }
    
    export default defineComponent({
        name: 'MyPage',
        components: {
             draggable: VueDraggable
         },
        setup(_, ctx) {
      ... 
      onMounted(async () => { 
         // try to select a vuedraggable-item, when the items are loaded via API-call
          const el = ctx.refs.draggablelist.$el.querySelector(".selected");
         // the following line doesn't change the internal state of the draggable-list 
          MultiDrag.singleton.utils.select(el);
        }
      }
    });
    

    Step by step scenario

    1. Open up VueDraggable and try to set the list-selection via javascript.

    Current Solution

    N/A - no method currently available to select items programmatically. When importing MultiDrag from SortableJS ( import {Sortable, MultiDrag } from "sortablejs";), then the MultiDrag.singleton-field is undefined.

    Expected Solution

    1. Expose the "MultiDrag.singleton.utils"-Methods from within VueDraggable, so that the selection can be done programmatically.
    2. If there are other methods for the item-selection, then expose these as well.
    3. Ideally, i can pass an Index/key of the listitem and the corresponding element is then added to the selection

    Can you help me with this? That would be great :-) If you can point me to the solution, i also can do a PR if desired.

    fyi @David-Desmaisons @divinespear

    opened by edvinkuric 0
  • How do I get the Element that an element enters after the move is complete?

    How do I get the Element that an element enters after the move is complete?

    I want to get the element entered after the move is complete

    opened by Edison-Ma 0
  • Flickering on nested list

    Flickering on nested list

    Elements started flickering... And when I increate empty-insert-treshold (to increase precision), it start flickering even faster.

    https://user-images.githubusercontent.com/33714934/120461335-36668380-c39a-11eb-9965-b837c7f9e824.mp4

    My example when I increased empty-insert-treshold to 15 to increase precision:

    https://user-images.githubusercontent.com/33714934/120461843-a96ffa00-c39a-11eb-8a2a-28f93a6e8501.mp4

    offical example of nested list: https://sortablejs.github.io/Vue.Draggable/#/nested-with-vmodel

    Did someone solved this problem or does someone have a good working example or maybe good alternative?

    opened by tilenpirih 1
Releases(v2.24.3)
Owner
SortableJS
A JavaScript library for reorderable drag-and-drop lists on modern browsers and touch devices
SortableJS
A simple kanban board where the items can be dragged and dropped from the list. This is a hybrid implementation of vue-smooth-dnd.

A simple kanban board where the items can be dragged and dropped from the list. This is a hybrid implementation of vue-smooth-dnd. Demo Usage Installa

Sujil Maharjan 109 Jul 18, 2021
Vue wrapper components for smooth-dnd

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

Kutlu Sahin 1.2k Jul 19, 2021
Vue drag-and-drop component based on Sortable.js

Vue.Draggable Vue component (Vue.js 2.0) or directive (Vue.js 1.0) allowing drag-and-drop and synchronization with view model array. Based on and offe

SortableJS 15.5k Jul 23, 2021
A set of vue mixins to turn any list into an animated, touch-friendly, sortable list ✌️

Vue Slicksort ?? A set of component mixins to turn any list into an animated, touch-friendly, sortable list. Based on react-sortable-hoc by [@clauderi

A Jordan Simonds 1.1k Jul 21, 2021
Vue Component for resize and drag elements

Vue-drag-resize Vue Component for draggable and resizable elements. Table of Contents Features Install and basic usage Props Events Contributing Licen

null 1.2k Jul 24, 2021
Vue2 component, that allows you to drag object wherever you want

vue-drag-it-dude Vue2 component, that allows you to drag object wherever you want What this can do Drag and drop DOM elements inside parent (or docume

Max Novikov 71 Jun 21, 2021
:ok_hand: Drag and drop so simple it hurts http://astray-git.github.io/vue-dragula

vue2-dragula ?? Drag and drop so simple it hurts Vue wrapper for dragula drag'n drop library, based on vue-dragula by @Astray-git. This library has be

Kristian Mandrup 209 May 7, 2021
Vue Drag and Drop library without any dependency 👌

Description Vue Drag and Drop library without any dependency. Native HTML5 drag and drop implementation made for Vue. Examples ?? Installation npm ins

Vivify Ideas 268 Jul 28, 2021
Drag And Drop functionality for Vue.js - written in Vue.js

vue-dnd-zone is a vue.js plugin for drag and drop functionality. It is not a wrapper for an external js library, but a set of vue components managing the drag and drop event and data model state

Yair Levy 89 Jul 24, 2021
🦄 Vue components for modifying lists with the HTML5 drag & drop API.

Vue components for modifying lists with the HTML5 drag & drop API. ?? Warning ?? Don't set index to the :key, it will cause dragging confusion. <vddl-

Hejx 405 Jul 27, 2021
Vue2 Component for draggable and resizable elements.

VueDraggableResizable 2 Vue2 Component for draggable and resizable elements. If you are looking for the version 1 of the component, it is available on

Maurizio 2.2k Jul 23, 2021
null 106 Jul 26, 2021
Vue2 directive that handles drag & drop

draggable-vue-directive Vue directive (Vue.js 2.x) for handling element drag & drop. Installation npm install draggable-vue-directive --save Demo You

Israel Zablianov 295 Jul 24, 2021
A simple drag & drop hierarchical list made as a vue component.

vue-nestable Drag & drop hierarchical list made as a vue component. Goals A simple vue component to create a draggable list to customizable items Reor

Ralph Huwiler 238 Jul 18, 2021