Implementing drag and drop

Dragging and dropping elements on the page has become a common user experience nowadays. There are many libraries to help developers implement this feature with ease. We will use Vue.Draggable (https://github.com/SortableJS/Vue.Draggable), which is a Vue component based on the Sortable.js library (https://github.com/RubaXa/Sortable).

After installing it via the npm install vuedraggable --save command, we will need to import it into BoardPage.vue, as follows:

    <script>
import draggable from 'vuedraggable'
...
export default {
name: 'BoardPage',
...
components: {
...
draggable
},
...
}
</script>

To make the card lists support drag and drop, we will need to wrap the .list-wrapper elements as follows:

<div class="board-body">
<draggable v-model="cardLists" class="list-container"
@end="onCardListDragEnded" :options="{handle: '.list-header',
...}">
<div class="list-wrapper" v-for="cardList in cardLists" v-
bind:key="cardList.id">
<div class="list">
<div class="list-header">{{ cardList.name }}</div>
...
</div>
</div>
...
</draggable>
</div>

As you can see, the <draggable> component has a v-model attribute that binds to cardLists, which is defined in the data properties. In this way, the changes to the card lists after dragging and dropping will be synced to the cardLists data model automatically. It will emit an end event once the drag ends. In our code, we use the onCardListDragEnded(event) handler to listen to that event and save the changes to the card list positions on the server side. In its :options property, we specify that the dragging can only be triggered by the .list-header element. With this <draggable> component, all .list-wrappers inside it can be dragged and dropped.

The following is how to make .card-items draggable:

<div class="list">
<div class="list-header">{{ cardList.name }}</div>
<draggable class="cards" v-model="cardList.cards"
@end="onCardDragEnded" :options="{draggable: '.card-item', group:
'cards', ghostClass: 'ghost-card', ...}" ...>
<div class="card-item" v-for="card in cardList.cards" ...>
<div class="card-title">{{ card.title }}</div>
</div>
<div class="add-card-form-wrapper">
...
</div>
</draggable>
...
</div>

As you can see, we wrap .card-items as well as .add-card-form-wrapper inside another <draggable> component, which is nested inside the <draggable> component that makes the card list draggable. We also define an event listener onCardDragEnded(event) method to save the card position changes to the server. In the value of the options property, we use the draggable option to specify that only the elements with the .card-item class can be dragged. In this way, the .add-card-form-wrapper won't be draggable, which is what we want. We use the option group from Sortable.js so that a .card-item element can be dragged from one .cards element to another .cards element. In this way, we can move one card between card lists. The ghostClass option is used to define the CSS class of the drop placeholder.

We won't discuss the other details of the implementation of the UI for BoardPage.vue in this book. You can find all of the details in the commit record on GitHub.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.79.176