1
  • I'm trying to color a row in a v-data-table based on the value of one of the fields in the table.
  • I've tried all the solutions offered here and elsewhere, and experimented with a few more.
  • I'm running the current version of Vuetify (2.3.9)
  • I've reloaded everything, cleared browser cache and cookies, etc.
  • I've tried with and without using slots.
  • My application is wrapped in v-app

== without slots ==

      <v-data-table 
        :items-per-page="50" 
        :headers="headers" 
        :items="jobs" 
        :height="600" 
        :search="search" 
        :hide-default-footer="true" 
        :item-key="jobs.JobID" 
        :item-class="row_class" 
        mobile-breakpoint="300"  
        no-data-text="No jobs today!" 
        dense 
        > 
      </v-data-table>  

methods: {
    row_class (item) { return "jobGreen" }
         } 

.jobGreen {  
   background-color: lightgreen;
          }

Result:

  • The class is not applied.
  • Using item-class="jobGreen" (i.e. not reactive) also fails
  • applying the jobGreen class to the v-data-table (i.e. class='jobGreen') works as expected

== using slot ==

(simplified)

<v-data-table>
   <template v-slot:item="{item}">
      <tr :class="row_class(item)">
         <td>
            {{ item.JobNumber }}
         </td>
      </tr>
   </template>
</v-data-table>

methods: {
    row_class (item) { return "jobGreen" }
      } 

OK, this works but the first row of the table never has a class applied! Sorting the table so that a different record is on top doesn't change things, so it's nothing to do with the data. The method is being called for each row of the table.

DucatiGuy
  • 21
  • 4

3 Answers3

0

Try this (This is the only thing that worked for me, but it breaks some of the tables base features):

<template v-slot:body="{ items }">
  <tbody>
    <tr :class="row_class(item)" v-for="item in items" :key="item.<name>">
      <td class="text-start">{{ item.<name> }}</td>
    </tr>
  </tbody>
</template>

tuffwes
  • 105
  • 8
0

I've had the same problem! This is what works around the not-working :item-class for me: (I only wanted to format the one defRow)

<template>
<v-data-table
  :headers="headersForTable"
  :items="chosenTableData"
>
<template v-slot:item="{item}">
  <tr :class="isDefRow(item) ? 'defRow' : ''" @click="rowInTableClicked(item) >
    <td v-for="(head,i) in headersForTable" :key="i">
      {{ item[head.value] }}
    </td>
  </tr>
</template>
</v-data-table>
</template>


<script lang="ts">

  isDefRow(row: any): boolean {
    // ...
  }

  get headersForTable() {
    // returns the array of header objects
  }

  get chosenTableData() {
    // returns the data array
  }

</script>

<style scoped>
.defRow {
  font-weight: bold;
}
</style>

Not that @click="rowInTableClicked(item) now has the same behaviour as otherwise @click:row="rowInTableClicked" would!

niko
  • 100
  • 4
0

:item-class should do what you need. You can use :item-class to specify a JavaScript function that will return the name of the class to apply.

I have attached a jsfiddle link with a simple working sample using :item-class.

https://jsfiddle.net/kug6xeLo/15/

You can alternatively use item-class to specify a property on the data that is backing that particular row. The data in a given row for that specified property would specify the name of a CSS class.

I found in my testing that this would not work if the specified css class is in a scoped style.

<style scoped> Did not work in my testing.

<style> Worked in my testing.

Markup:

<v-data-table
          :headers="headers"
            :items="contacts"
          :item-class="isHighlighted"
></v-data-table>

Script:

 methods: {
    isHighlighted(item) {
      return item.firstName === "Joe" ? "selectedColor" : "";
    }
  },

CSS


.selectedColor {
  background-color: blue;
}

Brian Gehrs
  • 41
  • 1
  • 4