Git Product home page Git Product logo

vue-dragula's People

Contributors

amcsi avatar astray-git avatar paddingme 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

vue-dragula's Issues

Is it posible to cancel the drag n drop operation

Hi,

In my drag n drop operation, when released, I make an AJAX request.

If AJAX Fails, I will need to get my item back to where it was.

Is there any available cancel() method to achieve that???

Wrong dragIndex if used within v-for.

This is some jade code iterating through an array of objects which themselves contain arrays that are to be used as source model.

.NewElements(v-dragula='elementGroup.elements' bag='content' v-for='elementGroup in elements')
  h3 {{elementGroup.
  .Element(v-for='element in elementGroup.elements')

When I am dragging this to another container, with the copy option enabled, the data that is inserted in the targetModel equals the correct array entry in the sourceModel + 1.

Changing line dist/vue-dragula.js:1186 from

var dropElmModel = notCopy ? sourceModel[dragIndex] : JSON.parse(JSON.stringify(sourceModel[dragIndex]));

to

var dropElmModel = notCopy ? sourceModel[dragIndex] : JSON.parse(JSON.stringify(sourceModel[dragIndex - 1]));

fixes it for me, but I guess is breaking things at some other point.

Vue.VueDragula not available

In order to define Dragula options, I added a created function to my Vue instance. However, Vue.VueDragula is not available like shown in the docs.

So the example below does not work:

...
new Vue({
  ...
  created: function () {
    Vue.VueDragula.options('my-bag', {
      direction: 'vertical'
    })
  }
})

How can I configure dragula now?

2.0 changes

2.0 Changes

Plugin API

  • rename plugin to Vue.dragula #6
  • install plugin to instance, vm.$dragula #7 #11
  • options set no longer limited in created hook

Model data flow

To follow one-way data flow in Vuejs 2, model value will not be updated automatically on drake events inside the directive. Updated model will be emitted with events.

Using event bus allow us handle events directly in other components. And we need to update models manually.

For "in component" drag&drop we just update model, but for "cross-component" drop&drop(or copy) actions, target and source needs to be update separately.
Currently a dropTarget is exposed in event payload:

eventTarget = {
  el: target, // Target element
  model: targetModel, // updated model of target component
  expression: targetExpression // the expression for directive
}

Here's a simple example:

function updateModel (vm, dropTarget, dropSource) {
  vm[dropSource.expression] = dropSource.model
  if (dropTarget.el === dropSource.el) { return }
  vm[dropTarget.expression] = dropTarget.model
}

Please try with the new version and leave feedbacks

Configuration global

I think changing Vue.vueDragula to Vue.dragula for to global settings object would be a nice tweak as it is more readable.

Super minor detail but am a fan of clean readable code.

All items in one array, bucket/column set with property

As Vuejs is data based, it would be more apropriate to store all items in one array, and specify the bucket (column) they are in with a property. It's the same direction as vuelidate took over vee-validate. This has to be two-way synced, so if I set the .bucket property of an item, it should be moved to the apropriate bucket/column in the interface, and if I drag them around, the .bucket property shall be updated. Is this possible or planned? The current setup makes this compplicated.

Destroy is not working (Remove event listeners)

Hi,
I created the listeners for drop events :
Vue.vueDragula.eventBus.$on("drop", function (args) {...

I add the listener when the component is mounted, now I want to remove the listener when its destroyed.
How can I remove the listeners.
drake.destroy is the original method, I tried the following, but it didnt work:
Vue.vueDragula.destroy()
or
var bag = Vue.vueDragula.find("questions-bag"); bag.drake.destroy();

Appropriate value for 'v-dragula' binding?

Sorry if this is another noob question, but I'm really struggling to piece this together from your example page, docs, and example files.

Same demo

Notice that if you collapse / expand groups after dragging, the components are effectively reset -- the data isn't actually changed. I assume that this is because I don't have the v-dragula binding set correctly. I've tried a number of different values for this including:

  • A unique identifier for each row (almost certain this is wrong)
  • The property on the element being updates (group.items in my example)
  • A global variable for the items being modified

In this case, I would expect the second item there to be the correct one, as the code seems to be doing some splicing logic (which I was keyed into by incorrectly using a string identifier as mentioned). It seems that this library is attempting to manipulate the data array backing it, but perhaps this doesn't work in the case that you have a multi-level component or something?

Hopefully my sample makes sense to demonstrate the issue, if not I can try to make it more clear.

setting method overrides in options being ignored

If I try and set any of the options such as moves or invalid the functions are not working.
I noticed when debugging the vue-dragula code the option gets removed before it makes it in as an option to the dragula function. Example Code:

Vue.vueDragula.options('my-bag', { moves: function (el, container, handle) { return handle.classList.contains('dragHandle'); }, direction: 'vertical' })

msg is not defined.

vue-dragula.js?c9f2:1448 Uncaught ReferenceError: msg is not defined

	      if (this.find(name)) {
	        this.log('existing drakes', this.drakeNames);
	        var errMsg = 'Drake named: "' + name + '" already exists for this service [' + this.name + ']. \n      Most likely this error in cause by a race condition evaluating multiple template elements with \n      the v-dragula directive having the same drake name. Please initialise the drake in the created() life cycle hook of the VM to fix this problem.';
	        this.error(msg);<<<<<<<<<<<<
	      }

Drake/Dragula API inaccessible

Is there a way to access the Dragula API directly? I need to cancel a drop when certain conditions are met and can't find a way currently.

Thanks!

How do you use canMove?

I am trying to figure out how to access the canMove method from Dragula. https://github.com/bevacqua/dragula#drakecanmoveitem

I would like to define a condition to determine if an element is allowed to be moved. I have tried the following:

            Vue.vueDragula.find('rules').drake.canMove((item) => {
                return false;
            });

Any idea how this would be done in Vue? Thank you.

Bag already exists

When creating multiple directives with the same bag, the following error is thrown...

<div class="wrapper">
  <div class="container" v-dragula="colOne" bag="first-bag">
    <div v-for="text in colOne" @click="onClick">{{text}} [click me]</div>
  </div>
  <div class="container" v-dragula="colTwo" bag="first-bag">
    <div v-for="text in colTwo">{{text}}</div>
  </div>
</div>

Uncaught Error: Bag named: "test" already exists.

copy: true behavior is buggy.

I encountered a bug when using copy: true. If you drop something, it will be created twice.
I think this is because the model is changed and the gu-transit element is inserted as well. That's why we then have two occurences of the same object, while only one of them is linked to the model

demo:
http://46bb3f4c.ngrok.io/

If you point me in the right direction, that would be great and I will submit a PR. Thanks ahead.

"require is not defined"

This script fails with an error:

var Vue = require('vue');
var VueDragula = require('vue-dragula');

Vue.use(VueDragula);

Therefore, can't get vue-dragula running.

Please update dragula to 3.7.3

A new version of Dragula got released, which enabled settings for drag detection offset (slideFactorX, slideFactorY)

If the dependency could get updated to the latest version, that would be nice.

Cannot reorder within the same bag in Vue 2.0

Based on #19 (comment), indeed you cannot seem to reorder properly within the same bag.

I'm not yet sure if this is a Vue 2.0 issue or a vue-dragula issue. I'm trying to investigate, but I'm not that familiar with either projects.
I'm also having trouble creating a small example, so please help me out @Astray-git if you can

DOM would never be removed with vue transition

When I drag into another container, the HTML element will be added class scale-leave but never be removed.

<template>
  <div class="page-test">
    <div v-for="c in categories">
      <p>{{c.name}}</p>
      <ul v-dragula="c.list">
        <li v-for="item in c.list" transition="scale">{{item}}</li>
      </ul>
    </div>
  </div>
</template>

<script>
  export default {
    data () {
      return {
        categories: [{
          _id: '0000000001',
          name: 'in progress',
          list: ['111', '222']
        }, {
          _id: '0000000002',
          name: 'plan',
          list: ['333']
        }]
      }
    }
  }
</script>

<style lang="stylus">
  .page-test
    .scale-transition
      overflow: hidden
      height: 38px
      transition: height .2s
    .scale-enter,.scale-leave
      height: 0
</style>

Dynamic options

I have a slightly more complex use case where i am passing functions to some of the dragula options which requires knowledge of the container elements.

Normally you would define options globally for plugins in Vue but when faced with this use case, it is not possible anywhere other than in the component using this directive.

To gain access to Vue.vueDragula, i needed to make the following tweak to my code...

Vue.prototype.vueDragula = Vue.vueDragula;

Allowing access to the plugin within components which was previously not possible. Then i could define the options for a container as per usual.

let filterContainer = this.$els.filters;
let activeContainer = this.$els.attached;

this.vueDragula.options('filters', {

    removeOnSpill: true,
    revertOnSpill: true,
    direction: 'vertical',

    copy: (element, origin) => {
        return origin === filterContainer;
    },

    accepts: (element, target) => {
        return target === activeContainer;
    }
});

What is not mentioned in the documentation is this creates a new dragula instance under the hood and as a result doesn't carry over any containers should the service already exist.

let filterContainer = this.$els.filters;
let activeContainer = this.$els.attached;

this.vueDragula.options('filters', {

    containers: [
        filterContainer,
        activeContainer
    ],

    removeOnSpill: true,
    revertOnSpill: true,
    direction: 'vertical',

    copy: (element, origin) => {
        return origin === filterContainer;
    },

    accepts: (element, target) => {
        return target === activeContainer;
    }
});

After adding those in, it was using my options finally but now the library started falling apart and becoming almost unusable.

TL;DR - the library is hard to use for these kinds of use cases not to mention buggy which is a real shame.

Failed to resolve directive: dragula - 2.2.4

Just tested a basic setup with vue 2.2.4 and webpack and gives me failed to resolve directive. Is this supported in 2.2.4 or am I missing something? Thanks

<template>
  <div>
    <div class="wrapper">
      <div class="container" v-dragula="colOne" bag="first-bag">
        <div v-for="text in colOne" :key="text">{{text}}</div>
      </div>
      <div class="container" v-dragula="colTwo" bag="first-bag">
        <div v-for="text in colTwo" :key="text">{{text}}</div>
      </div>
    </div>
  </div>
</template>

<script>

import Vue from 'Vue'
import VueDragula from 'vue-dragula'

Vue.use(VueDragula)

export default {
  name: 'index',
  data: () => {
    return {
      colOne: [
        'You can move these elements between these two containers',
        'Moving them anywhere else isn"t quite possible',
        'There"s also the possibility of moving elements around in the same container, changing their position'
      ],
      colTwo: [
        'This is the default use case. You only need to specify the containers you want to use',
        'More interactive use cases lie ahead',
        'Another message'
      ],
      categories: [
        [1, 2, 3],
        [4, 5, 6]
      ],
      copyOne: [
        'Lorem ipsum dolor sit amet, consectetuer adipiscing elit.',
        'Aenean commodo ligula eget dolor. Aenean massa.'
      ],
      copyTwo: [
        'Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.',
        'Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.'
      ]
    }
  },
  created: function () {
    Vue.vueDragula.options('third-bag', {
      copy: true
    })
  },
  ready: function () {
    var _this = this
    Vue.vueDragula.eventBus.$on(
      'drop',
      function (args) {
        console.log('drop: ' + args[0])
        console.log(_this.categories)
      }
    )
    Vue.vueDragula.eventBus.$on(
      'dropModel',
      function (args) {
        console.log('dropModel: ' + args)
        console.log(_this.categories)
      }
    )
  }
}
</script>

input loses focus

I found that when using <input>, the focus is lost on model update. On every key stroke the focus is lost and I have to click back into the input for every subsequent keystroke.

It doesn't happen on native Dragula from what I can tell.

<div class="container" v-dragula="colOne" bag="first-bag">
     <div v-for="(i, text) in colOne" >
        {{text}}[click me] 
        <input v-model="colOne[i]"/>
     </div>
</div>

Re-initialize after updating containers

Currently I'm settings options for vue-dragula in the ready callback of the main Vue file, like so:

var Vue = require('vue');

Vue.use(require('vue-dragula'));

new Vue({

    el: '#app',

    components: {
        'categories': require('./components/categories.vue'),
    }

    data: {
        // some data...
    },

    created: function () {

        Vue.vueDragula.options('categories', {
            // options...
        });

    }
});

But in another component, I have an update function for the categories, which requires me to re-initialize vue-dragula so new (or removed) containers are taken into account. In this case the categories are the bags/containers.

export default {

    data: function () {
        return {
            // some data...
        };
    },

    methods: {

        saveCategories: function () {

            // save categories to database
            // use this.$set('categories', response.data.categories); so update categories data of Vue instance
            // dragging doesn't anymore, re-init?

            Vue.vueDragula.options('categories', function () {
                // options again...
            });
        }
    }
}

How can I access Vue.vueDragula.options inside of a components method? this doesn't work, and I can't find anything related on Vue itself or vue-dragula.

This is probably not really an issue, but maybe the docs can be updated if you know how to do something like this.

Error in directive dragula update hook: "TypeError: Cannot read property 'drake' of undefined"

I used vue-dragula in my project for the drag & drop list requirement.

It's worked perfect. But I have the below error at that hold element remove time.

Error in directive dragula update hook: "TypeError: Cannot read property 'drake' of undefined"

My code sample below

(template HTML code)

<ul v-dragula="dragDatas" bag="action-bag">
    <li v-for="(drDatas, drIndex) in dragDatas" :key="drDatas.id">{{drDatas.name}}</li>
</ul>

(Script code)

import 'vue-dragula/styles/dragula.css';

created () {
  Vue.vueDragula.options('action-bag', {
    invalid: function (el, handle) {
      return // CONDITION BASED
    }
  });
},

mounted () {
  const self = this;
  Vue.vueDragula.eventBus.$on('drop', async function ([bag, curElmt, allElmts]) {
    // drop event based functionalities
  })
}

I think this error is Vue.vueDragula.eventBus.$on event listener error.
If anyone have this solution Kindly share me

Issue with Mirror element

I'm new to both Vue and (Vue-)Dragula, so maybe I'm missing something obvious here. I've created a structure with container components that contain headers and then a list of draggable item components.

Vue.component('container', {
    props: [ 'group' ],
    data: function() {
        return {
            expanded: false
        }
    },
    methods: {
        onClick: function() {
            this.expanded = !this.expanded;
        }
    },
    template: '\
        <div class="group-container" @click="onClick"> \
            <div class="group-container-header">+ {{group.description}}</div> \
            <div class="group-container-rows" v-if="expanded" v-dragula="group.items" bag="items-bag"> \
                <row \
                    v-for="item in group.items" \
                    :item="item" \
                    :key="item.id" /> \
            </div> \
        </div>'
});

When I drag, I'm seeing the element I'm dragging end up at the bottom of the list outside of a container, which isn't desirable, but seems to be consistent with the dragula documentation mentioning the default behavior is document.body. I assume this is because I have something misconfigured... am I missing something in my simple example here?

Here's a runnable sample -- https://jsfiddle.net/shortstuffsushi/a8k941xm/

Moving from a list to another

Hi, I'm using this in a project and it's cool - thanks! I'm having a problem though when moving an item from a list to another where the drag and drop works fine, but the underlying Vue data is not updated accordingly. If I reorder items within the same list instead, the Vue data is updated automatically as I can see with the Chrome dev tools.

Any idea? Thanks in advance.

Vue 2.0 support

Is there any plan on supporting new version 2.0 of Vue.js ?

Any way to get the new index I dragged to

I am using dropModel event but there is no argument about the index.

I am trying to get the index like that:

Vue.vueDragula.eventBus.$on('dropModel', ([bag, el, target, source]) => {
  const index = Array.prototype.indexOf.call(target.children[i], el)
})

But the index always is -1, because the new element from target is not equal to the old element from source (More than 2 containers), it's a new object.

BTW, Is there any way to get the item from v-for array? Not the HTML element.

Copy doesn't work when model contains cyclic refs

On drop when copy is "on" a TypeError is thrown in case the source model contains cyclic references. (My model is a tree structure where the nodes have a "parent" reference.)

When vue-dragula builds the target model for the drop-model event it clones the source model by executing:

JSON.parse(JSON.stringify(sourceModel[dragIndex]))

The TypeError is thrown by JSON.stringify. By default JSON.stringify does not support cyclic references.

A solution would be if vue-dragula would offer an option to let the user configure the "replacer function" (resp. the whitelist array) to be passed as the 2nd argument to JSON.stringify.
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

This way the user would get an opportunity to strip the problematic (= cyclic) model properties for stringification.

I'm using Vuejs 2 and vue-dragula 2.0.0-alpha.1 which worked fine until I added the cyclic model reference.

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.