title: vuedraggable is triggered under the modal window and breaks the list
body: <ul>
  <li>Rails 6
  
  <ul>
  <li>Vue 2.6.10</li>
  <li>vuedraggable 2.23.0</li>
  </ul></li>
  </ul>
  
  <p>The problem is the following, there is a list with Cards inside, when you click on Card, a modal window with Card pops up, after that if you hold down the left mouse button on the modal window and hold the mouse, the vuedraggable event will work which closes the modal window and break the Cards list, how can I avoid this draggable behavior when a modal window is open?</p>
  
  <p>The code can be downloaded completely from GoRails, I did it by video
  <a href="https://github.com/gorails-screencasts/vuejs-trello-clone" rel="nofollow noreferrer">https://github.com/gorails-screencasts/vuejs-trello-clone</a></p>
  
  <p>Playback method - open the modal window by clicking on the Card, in the open modal window, press the left mouse button and hold the mouse button, at this moment the modal window will close and the list will break</p>
  
  <p>application.js</p>
  
  <pre><code>/* eslint no-console:0 */
  // This file is automatically compiled by Webpack, along with any other files
  // present in this directory. You're encouraged to place your actual application logic in
  // a relevant structure within app/javascript and only use these pack files to reference
  // that code so it'll be compiled.
  //
  // To reference this file, add &lt;%= javascript_pack_tag 'application' %&gt; to the appropriate
  // layout file, like app/views/layouts/application.html.erb
  
  import Vue from 'vue/dist/vue.esm'
  import Vuex from 'vuex'
  import App from '../app.vue'
  import TurbolinksAdapter from 'vue-turbolinks'
  
  Vue.use(Vuex)
  Vue.use(TurbolinksAdapter)
  
  window.store = new Vuex.Store({
    state: {
      lists: []
    },
  
    mutations: {
      addList(state, data) {
        state.lists.push(data)
      },
      moveList(state, data) {
        const index = state.lists.findIndex(item =&gt; item.id == data.id)
        state.lists.splice(index, 1)
        state.lists.splice(data.position - 1, 0, data)
      },
      addCard(state, data) {
        const index = state.lists.findIndex(item =&gt; item.id == data.list_id)
        state.lists[index].cards.push(data)
      },
      editCard(state, data) {
        const list_index = state.lists.findIndex((item) =&gt; item.id == data.list_id)
        const card_index = state.lists[list_index].cards.findIndex((item) =&gt; item.id == data.id)
        state.lists[list_index].cards.splice(card_index, 1, data)
      },
  
      moveCard(state, data) {
        const old_list_index = state.lists.findIndex((list) =&gt; {
          return list.cards.find((card) =&gt; {
            return card.id === data.id
          })
        })
        const old_card_index = state.lists[old_list_index].cards.findIndex((item) =&gt; item.id == data.id)
        const new_list_index = state.lists.findIndex((item) =&gt; item.id == data.list_id)
  
        if (old_list_index != new_list_index) {
          // Remove card from old list, add to new one
          state.lists[old_list_index].cards.splice(old_card_index, 1)
          state.lists[new_list_index].cards.splice(data.position - 1, 0, data)
        } else {
          state.lists[new_list_index].cards.splice(old_card_index, 1)
          state.lists[new_list_index].cards.splice(data.position - 1, 0, data)
        }
      }
    }
  })
  
  document.addEventListener("turbolinks:load", function() {
    var element = document.querySelector("#boards")
    if (element != undefined) {
      window.store.state.lists = JSON.parse(element.dataset.lists)
  
      const app = new Vue({
        el: element,
        store: window.store,
        template: "&lt;App /&gt;",
        components: { App }
      })
    }
  });
  </code></pre>
  
  <p>app.vue</p>
  
  <pre><code>&lt;template&gt;
    &lt;div class="board"&gt;
      &lt;draggable v-model="lists" :options="{group: 'lists'}" class="dragArea d-inline-block" @end="listMoved"&gt;
        &lt;list v-for="(list, index) in lists" :list="list"&gt;&lt;/list&gt;
      &lt;/draggable&gt;
  
      &lt;div class="list"&gt;
        &lt;a v-if="!editing" v-on:click="startEditing"&gt;Add a List&lt;/a&gt;
        &lt;textarea v-if="editing" ref="message" v-model="message" class="form-control mb-1"&gt;&lt;/textarea&gt;
        &lt;button v-if="editing" v-on:click="createList" class="btn btn-secondary"&gt;Add&lt;/button&gt;
        &lt;a v-if="editing" v-on:click="editing=false"&gt;Cancel&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  import draggable from 'vuedraggable'
  import list from 'components/list'
  
  export default {
    components: { draggable, list },
  
    data: function() {
      return {
        editing: false,
        message: "",
      }
    },
  
    computed: {
      lists: {
        get() {
          return this.$store.state.lists
        },
        set(value) {
          this.$store.state.lists = value
        },
      },
    },
  
    methods: {
      startEditing: function() {
        this.editing = true
        this.$nextTick(() =&gt; { this.$refs.message.focus() })
      },
  
      listMoved: function(event) {
        var data = new FormData
        data.append("list[position]", event.newIndex + 1)
  
        Rails.ajax({
          beforeSend: () =&gt; true,
          url: `/lists/${this.lists[event.newIndex].id}/move`,
          type: "PATCH",
          data: data,
          dataType: "json",
        })
      },
  
      createList: function() {
        var data = new FormData
        data.append("list[name]", this.message)
  
        Rails.ajax({
          beforeSend: () =&gt; true,
          url: "/lists",
          type: "POST",
          data: data,
          dataType: "json",
          success: (data) =&gt; {
            this.message = ""
            this.editing = false
          }
        })
      }
    }
  }
  &lt;/script&gt;
  
  &lt;style scoped&gt;
  .dragArea {
    min-height: 10px;
  }
  
  .board {
    overflow-x: auto;
    white-space: nowrap;
  }
  
  .list {
    background: #E2E4E6;
    border-radius: 3px;
    display: inline-block;
    margin-right: 20px;
    padding: 10px;
    vertical-align: top;
    width: 270px;
  }
  &lt;/style&gt;
  </code></pre>
  
  <p>list.vue</p>
  
  <pre><code>&lt;template&gt;
    &lt;div class="list"&gt;
      &lt;h6&gt;{{ list.name }}&lt;/h6&gt;
  
      &lt;draggable v-model="list.cards" :options="{group: 'cards'}" class="dragArea" @change="cardMoved"&gt;
        &lt;card v-for="card in list.cards" :key="card.id" :card="card" :list="list"&gt;&lt;/card&gt;
      &lt;/draggable&gt;
  
      &lt;a v-if="!editing" v-on:click="startEditing"&gt;Add a card&lt;/a&gt;
      &lt;textarea v-if="editing" ref="message" v-model="message" class="form-control mb-1"&gt;&lt;/textarea&gt;
      &lt;button v-if="editing" v-on:click="createCard" class="btn btn-secondary"&gt;Add&lt;/button&gt;
      &lt;a v-if="editing" v-on:click="editing=false"&gt;Cancel&lt;/a&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  import draggable from 'vuedraggable'
  import card from 'components/card'
  
  export default {
    components: { card, draggable },
    props: ["list"],
  
    data: function() {
      return {
        editing: false,
        message: ""
      }
    },
  
    methods: {
      startEditing: function() {
        this.editing = true
        this.$nextTick(() =&gt; { this.$refs.message.focus() })
      },
  
      cardMoved: function(event) {
        const evt = event.added || event.moved
        if (evt == undefined) { return }
  
        const element = evt.element
        const list_index = window.store.state.lists.findIndex((list) =&gt; {
          return list.cards.find((card) =&gt; {
            return card.id === element.id
          })
        })
  
        var data = new FormData
        data.append("card[list_id]", window.store.state.lists[list_index].id)
        data.append("card[position]", evt.newIndex + 1)
  
        Rails.ajax({
          beforeSend: () =&gt; true,
          url: `/cards/${element.id}/move`,
          type: "PATCH",
          data: data,
          dataType: "json"
        })
      },
  
      createCard: function() {
        var data = new FormData
        data.append("card[list_id]", this.list.id)
        data.append("card[name]", this.message)
  
        Rails.ajax({
          beforeSend: () =&gt; true,
          url: "/cards",
          type: "POST",
          data: data,
          dataType: "json",
          success: (data) =&gt; {
            this.message = ""
            this.$nextTick(() =&gt; { this.$refs.message.focus() })
          }
        })
      }
    }
  }
  &lt;/script&gt;
  
  &lt;style scoped&gt;
  .dragArea {
    min-height: 10px;
  }
  
  &lt;/style&gt;
  </code></pre>
  
  <p>card.vue</p>
  
  <pre><code>&lt;template&gt;
    &lt;div&gt;
      &lt;div @click="editing=true" class="card card-body mb-3"&gt;
        {{card.name}}
      &lt;/div&gt;
  
      &lt;div v-if='editing' class="modal-backdrop show"&gt;&lt;/div&gt;
  
      &lt;div v-if='editing' @click="closeModal" class="modal show" style="display: block"&gt;
        &lt;div class="modal-dialog"&gt;
          &lt;div class="modal-content"&gt;
            &lt;div class="modal-header"&gt;
              &lt;h5 class="modal-title"&gt;{{ card.name }}&lt;/h5&gt;
            &lt;/div&gt;
            &lt;div class="modal-body"&gt;
              &lt;input v-model="name" class="form-control"&gt;&lt;/input&gt;
            &lt;/div&gt;
            &lt;div class="modal-footer"&gt;
              &lt;button @click="save" type="button" class="btn btn-primary"&gt;Save changes&lt;/button&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/template&gt;
  
  &lt;script&gt;
  export default {
    props: ['card', 'list'],
    data: function() {
      return {
        editing: false,
        name: this.card.name,
      }
    },
  
    methods: {
      closeModal: function(event) {
        if (event.target.classList.contains("modal")) { this.editing = false }
      },
  
      save: function() {
        var data = new FormData
        data.append("card[name]", this.name)
  
        Rails.ajax({
          beforeSend: () =&gt; true,
          url: `/cards/${this.card.id}`,
          type: "PATCH",
          data: data,
          dataType: "json",
          success: (data) =&gt; {
            this.editing = false
          }
        })
      },
    }
  }
  &lt;/script&gt;
  
  &lt;style scoped&gt;
  &lt;/style&gt;
  </code></pre>
  
  <p>what happens before and after</p>
  
  <p><a href="https://i.stack.imgur.com/jKhtf.png" rel="nofollow noreferrer">enter image description here</a></p>
  
  <p><a href="https://i.stack.imgur.com/ru69f.png" rel="nofollow noreferrer">enter image description here</a></p>