Search code examples
ruby-on-railsvue.jsvue.draggable

Vue.draggable Get Dragged Item and List ID


I've read all the documentation and stackoverflow I can find, but still am having issues with this.

I'm building a Trello clone with Vue and Rails.

I have many draggable lists.

Each list has draggable cards.

When I drag a card from one list to a second list, how do I persist this to my ajax rails endpoint?

I've tried using the @end method and the :move prop, but have had zero luck.

#app.vue
<template>
  <draggable v-model="lists" group='lists' class="row dragArea" @end="listMoved">
    <div v-for="(list, index) in lists" class="col-3">
      <h6>{{ list.name }}</h6>
      <hr />

      <draggable v-model="list.cards" group='cards' class="dragArea" :move="cardMoved">
        <div v-for="(card, index) in list.cards" class="card card-body mb-3">
          {{ card.name }}
        </div>
      </draggable>

      <div class="card card-body">
        <input v-model="messages[list.id]" class="form-control" ></input>
        <button v-on:click="submitMessages(list.id)" class="btn btn-secondary">Add</button>
      </div>
    </div>
  </draggable>
</template>

<script>
import draggable from 'vuedraggable'

export default {
  components: { draggable },
  props: ["original_lists"],
  data: function() {
    return {
      messages: {},
      lists: this.original_lists
    }
  },
  methods: {
    cardMoved: function(event) {
      console.log(event)

      var data = new FormData
      data.append("card[list_id]", WHERE_DO_I_FIND_THIS_ID)
      data.append("card[position]", event.draggedContext.element.id)


      Rails.ajax({
        url: `/cards/${event.draggedContext.element.id}/move`,
        type: "PATCH",
        data: data,
        datatype: "json"
      })
    },
  }
}
</script>

Solution

  • Use the change event that contains all the dnd information you need and is called only once the drag operation is ended.

    As suggested by @sovalina you need to pass extra infomation linked to the list:

    :change="changed(list.id, $event)"
    

    Also your div should be keyed:

    <div v-for="(card, index) in list.cards" :key="card.name" class="card card-body mb-3">