Fabio Ebner
Fabio Ebner

Reputation: 2783

styling individual rows in a Vuetify data table

Can I apply different styling for a specific row in a data table?

This is my code:

<v-data-table
          :headers="headers"
          :items="items"
          v-model="selected"
          :search="search"
          :no-data-text="mensagem"
          select-all
          :rows-per-page-text="linhasPorPagina">
          <template slot="items" slot-scope="props">
            <td>
              <v-checkbox
                primary
                hide-details
                v-model="props.selected"
              ></v-checkbox>
            </td>
            <td class="text-xs-left">{{ props.item.id }}</td>
            <td class="text-xs-left">{{ props.item.apresentante }}</td>    
        </v-data-table>

For example, I want to apply a red line when the Id > 4

Upvotes: 20

Views: 49128

Answers (6)

Denis O.
Denis O.

Reputation: 1850

I'm facing a similar problem in Vuetify 3 - I need to style an entire row based on the data of an item. The proposed solutions with :row-props don't work, and overriding the whole row template doesn't work for me as I already have a lot of custom cell templates and the code would be bloated. The developers also seem to have no plans to make a solution for the issue.

In the end, I settled the problem in a slightly crutchy, but compact and quite flexible way. We simply add a hidden element with the custom class (ie, .highlight_parent_row) inside any cell in the row, and then use the tr:has() construct to set the styles we need.

<template>
  <VDataTable
      :headers="headers"
      :items="filteredLotsList"
  >
    <template #item.controls="{ item }">
        <div class="processed-item d-none" v-if="item.processed_time"><!-- just for flagging --></div>
  
        <VToolbar>
          <VBtn :icon="'tabler-clipboard-copy'" @click="copyToClipboard" />
          <VBtn :icon="'tabler-eye-off'" @click="markItemProcessed" />
        </VToolbar>
    </template>
    // rest of the code
  </VDataTable>
</template>

<style>
tr:has(.processed-item) {
  background-color: #e5f8e5;
}
</style>

Hopefully this necroposting will save someone some time and nerves :)

Upvotes: 0

Arctodus
Arctodus

Reputation: 5847

For Vuetify 3, item-class and item-style have been combined into row-props (changelog)

<v-data-table :row-props="row_classes">

methods: {
  row_classes ({item}) {
    if (item.calories < 200)
      return { class: "orange" }
    else
      return {}
  }
}

Upvotes: 3

LShapz
LShapz

Reputation: 1766

If you want the whole row to have a red line (or in my example a red background), you'll need to wrap the three td in a tr. If you just want it on the id cell, then you can add

<td class="text-xs-left" :style="{backgroundColor: (props.item.id > 4 ? 'red' : 'transparent' ) }">
 {{ props.item.id }}
</td>

Upvotes: 6

Soth
Soth

Reputation: 3045

You can now use vuetifys data table item-class property:

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  methods: {
    row_classes(item) {
        if (item.calories < 200) {
          return "orange"; //can also return multiple classes e.g ["orange","disabled"]
        } 
    }
  },
  data () {
    return {
      singleSelect: false,
      selected: [],
      headers: [{text: 'Dessert (100g serving)', value: 'name'},
                { text: 'Calories', value: 'calories' },
      ],
      desserts: [{name: 'Frozen Yogurt',calories: 159,},
                 {name: 'Ice cream sandwich',calories: 237,},
                 {name: 'Eclair',calories: 262,},
                 {name: 'Cupcake',calories: 305,},
      ],
    }
  },
})
.orange {
  background-color: orange;
}
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css'>

<div id="app">
  <v-app>
    <v-data-table
      v-model="selected"
      :headers="headers"
      :items="desserts"
      :item-class= "row_classes"                  
      class="elevation-1"
    >
    </v-data-table>
  </v-app>
</div>

<script src='https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js'></script>
<script src='https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.js'></script>

Upvotes: 27

Ju66ernaut
Ju66ernaut

Reputation: 2691

I was also trying to style rows in a vuetify data-table but the above answers didn't have everything I needed to make it work. Using Vuetify v2

I wanted to add a class to a row when a certain condition was met.

<v-data-table  
   :headers="myHeaders"
   :items="myItems"
>
  <template v-slot:item="props">
    <tr :class="{'my-class': props.item.current > props.item.total}">
      <td>{{props.item.current}}</td>
      <td>{{props.item.total}}</td>
    </tr>
  </template>
</v-data-table>

...
// js portion of the component (computed prop)

myItems() {
    return [
      {
        current: 101,
        total: 100
      },
      {
        current: 45,
        total: 100
      }
    ]
  }

Upvotes: 12

mellisdesigns
mellisdesigns

Reputation: 151

You can actually wrap your <td> elements within a <tr> element. Then you can use Vue style binding to determine whether you want classes applied or not.

<template>
  <tr v-bind:class="{'active-class-name': isActive(item)}">
    <td>Woo</td>
  </tr>
</template>

It renders out the tbody block with a row (tr) with applied class names and the child columns contained within.

Upvotes: 15

Related Questions