Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vuetify Data Tables: Fetch data when expanding a row

I have a Vuetify data table with expandable rows. Each row correlates with a customer's order which consists of samples they want to be tested.

Currently, I'm retrieving all the orders with all the samples but it takes too long to load all the information.

So instead of retrieving all the samples for every order, when I expand a row I want to be able to perform an API call to retrieve the samples that should be displayed in the expanded section for that particular order.

I've researched all I can and have come to a dead-end. Here's where I'm at currently:

<v-data-table
  :headers="orders_headers"
  :items="orders"
  show-expand
  :single-expand="true"
  :expanded.sync="expanded"
>

  <!-- Expand Buttons -->
  <template v-slot:item.data-table-expand="{ item, isExpanded, expand }">
    <v-btn @click="expand(true)" v-if="!isExpanded">Expand</v-btn>
    <v-btn @click="expand(false)" v-if="isExpanded">close</v-btn>
  </template>

  <!-- Expanded Data -->
  <template v-slot:expanded-item="{ headers, item }">
    <td :colspan="headers.length">

      <table v-for="(sample, index) in item.samples" :key="index">
        <tr>
          <th>Sample Acc</th>
          <td>{{ sample.sample_accession }}</td>
        </tr>
        <tr>
          <th>Sample Status</th>
          <td>{{ sample.sample_status }}</td>
        </tr>
      </table>

    </td>
  </template>
</v-data-table>

I think I may have figured it while writing this

As I was typing this out, I realized what I possibly need to do. I need to add a method call to the expand button, then in that method set the results to expandedSamples and replace item.samples with it.

In the meantime, if anyone has any better solution I'd love to hear. Otherwise, I'll post my solution in case anyone else is trying to attempt something similar to this.

Bonus

Anyone know if there's a way to tap into the expand event without replacing the default icons/functionality or a way to include the original icons/functionality when using v-slot:item.data-table-expand?

Currently when I'm using v-slot:item.data-table-expand, I have to add the buttons back in and I lose the chevrons and the animations.

like image 767
Josh Avatar asked Apr 02 '20 14:04

Josh


1 Answers

For the benefit of future readers facing the same issue, use the @item-expanded event of the data-table to lazy load the item details (or child data) on demand. Hook the item-expanded event to a method (e.g. loadDetails) that loads the data, and then merges the response into the original items array.

Here's an example...

  <v-data-table
    :headers="headers"
    :items="items"
    show-expand
    single-expand
    item-key="name"
    :search="search"
    @item-expanded="loadDetails">
    <template v-slot:expanded-item="{ headers, item }">
        <td :colspan="headers.length">
           <table v-for="(sample, index) in items.samples" :key="index">
            <tr>
              <th>Sample Acc</th>
              <td>{{ sample.sample_accession }}</td>
            </tr>
           </table>
        </td>
    </template>
  </v-data-table>

  methods: {
    loadDetails({item}) {
        axios.get('http.../' + item.id)
            .then(response => {
              item.samples = response.data[0]
        })
    }
  }

https://codeply.com/p/d5XibmqjUh

like image 103
Zim Avatar answered Oct 08 '22 01:10

Zim