DEV Community

Draggable table row with VueJS, Vuetify and SortableJS

Andrey Gaisinskii on June 21, 2020

TLDR At the bottom of the article you will find a link to the GitHub repo. Prologue Recently I have had to implement draggable rows for a vuetify...
Collapse
 
alvarocanepa profile image
Alvaro Cánepa

Great! this is what I was looking for...
Many thanks!

This is my implementation with dynamic columns:

<v-data-table
      :headers="headers"
      :items="arItems"
      :loading="loading"
      item-key="id"
      :show-select="false"
      :disable-pagination="true"
      :hide-default-footer="true"
    >
      <template #body="data">
        <draggable v-model="arItems" tag="tbody" @end="onReorder">
          <tr
            v-for="(item, index) in data.items"
            :key="`row.${index}`"
          >
            <template v-for="(col, idx) in data.headers">
              <td :key="`col.${index}.${idx}`">
                  <action-buttons
                    :path="path"
                    :item-id="item.id"
                    hide-view
                    @delete="deleteItem"
                    v-if="col.value == 'actions'"
                  />
                  <span v-else>{{ $_.get(item, col.value) }}</span>
              </td>
            </template>
          </tr>
        </draggable>
      </template>
    </v-data-table>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
giangola1 profile image
Giangola

I have to Login to say thanks <3

Collapse
 
lambertbeekhuis profile image
Lambert Beekhuis

Very interesting post. One question though: how to handle a 'drop'? What is triggered when you actually 'drop' something. If I make the list in a computed property with a getter and setter, no change is detected as the :list option using splice is used. When using the draggable :value option, it is not working...

So, how to handle it 'after the drop'?

Collapse
 
lambertbeekhuis profile image
Lambert Beekhuis

A solution that works for me is adding the event-handler
@end="endDrag(props.items)"
in the element

Thanks, great!

Collapse
 
eugenman profile image
Eugen

For example:
@end="isDragging = false"

Collapse
 
appurist profile image
Paul / Appurist

This post just saved my bacon on an important project. I had been back and forth on many alternatives, none of which was the combination needed, until I saw this article. Having the full source code example, especially PageTable.vue, along with your working example was instrumental and so extremely helpful. Very much appreciated that you took the time to document this solution here.

Collapse
 
gaisinskii profile image
Andrey Gaisinskii

I'm so glad that I could help you. Thanks for kind words!

Collapse
 
juretopolak profile image
juretopolak

Shouldn't be data reactive with that I mean that the order of data should also change in the array?
This is the case with vuedraggable when using div or ul/li tags, but is not with this example using v-data-table.

dev-to-uploads.s3.amazonaws.com/i/...

Collapse
 
gaisinskii profile image
Andrey Gaisinskii

I'm not an expert in Vue/VueDevTools/Vuetify nor VueDraggable, but my question is: Why should it be reactive ? Because what we are doing is that we are using a wrapper library of SortableJS inside vuetify table component, there are no direct binding between vue/vuetify table component and VueDraggable library. We pass our array or items into vuetify table and then VueDraggable does its magic. If you want to do something upon table change you can use update event of VueDraggable, something like this:

   <v-data-table
      :headers="tableHeaders"
      :items="homePage.coupons"
      :loading="loading"
      item-key="id"
      :show-select="false"
      :disable-pagination="true"
      :hide-default-footer="true"
      class="page__table"
    >
      <template v-slot:body="props">
        <draggable
          :list="props.items"
          :handle="'.handle'"
          tag="tbody"
          @update="handleTableUpdate(props.items)"
        >
          <!-- other html here -->
        </draggable>
      </template>
    </v-data-table>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
princesinghpnjr profile image
Prince kumar singh • Edited

I tried adding one more thing to your v-data-table but i won't able to do that.

  1. I want to edit this table cells on mouse double click without using v-edit-dialog. i want inline editing.

Please help me to do that

Collapse
 
jonmalave profile image
Jon Malave

Thanks so much! This was extremely helpful! I didn't think Vue Draggable was possible on Vuetify's Table Component until I found this.

Collapse
 
trimakas profile image
Trimakas

I created an account just to say thank you as well! Fantastic post..

Anyone here have any luck in using this to create parent/child relationships as well? That's next!

Collapse
 
skrface profile image
A. Juif

I also created an account to be able to thank you.
Good work and thanks for the time you spent sharing this with people.

Regards

Collapse
 
mena234 profile image
Mena Nasser

Great, Thank you.