q-table rows drag and drop



  • q-table rows drag and drop? I’m trying without success so far. Has anyone ever got it?



  • I once tried it with q-table without success and would like to know if it’s possible, too.

    My plan-b was to use a standard <table> and https://www.npmjs.com/package/vuedraggable to wrap the <tr> elements.
    That was before Quasar v1, so nowadays I would use QMarkupTable.

    But it would be nicer to be able to use it in a QTable, of course.

    I’m not saying it is impossible - I just gave up quickly…



  • I just tried again and I still can’t do it. I think I have an explanation why it doesn’t work… Let me show you my approach:

    As a starting point I looked at the example at: https://quasar.dev/vue-components/table#Body-slots

    <q-table ... >
       <template v-slot:body="props">
          <q-tr :props="props">
             <q-td key="name" :props="props"> ...  </q-td>
             ...
          </q-tr>
       </template>
    </q-table>
    

    So I thought I could just replace the <q-tr> with the <draggable> tag from the Drag&Drop-library and configure it to render as a <q-tr>. Like this:

    <q-table ... >
       <template v-slot:body="props">
          <draggable
            :props="props"
            tag="q-tr"
            ...>
             <q-td key="name" :props="props"> ... </q-td>
             ...
          </draggable>
       </template>
    </q-table>
    

    Now here is why this won’t work:
    The <q-tr> and the body-slot don’t correspond to the <tr> and <tbody> elements that are rendered in the DOM in the end.
    The drag-functionality actually gets attached to the cells instead of the rows!

    The only way I see that this could work is if we somehow can render the individual rows (the actual <tr> elements) with a v-for by ourself.



  • This is a bummer - any thoughts on this from the quasar folks?



  • What about the @chyde90 code but with QMarkupTable?



  • I need the features of QTable



  • There is a way, but it requires some work…
    The library I like to use for drag & drop (vuedraggable) is actually just a wrapper for Sortable.js to make it work with vue.js.
    You could simply use Sortable.js (or something similar) and make it work with vue.js in your own way.

    <q-table
        ...
        id="myTable"
    >
    
    import Sortable from "sortablejs";
    
    mounted() {
       const element = document.querySelector("#myTable tbody"); // grab the element containing the <tr> elements
       const sortable = Sortable.create(element, {
          onEnd(event) { // gets called when dragging ended
             // Sortable.js only swaps the elements in the DOM,
             // so we need to swap the elements in the table data using the indexes (event.oldIndex and event.newIndex) or probably better by using ids if you have pagination
          }
       });
    }
    

    And then you also need to somehow notify Sortable.js when your data changes (after sorting, on pagination, etc.).
    I don’t see an update() or refresh() function in the documentation, so you might have to call destroy() and re-initialize Sortable again every time, but idk.

    … something like that.


Log in to reply