Reputation: 2783
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
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
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
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
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
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
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