The problem is the outer v-for
was put on <tbody>
, so each row was rendered with a new <tbody>
:
<table class="tbl">
<thead>
<tr><th>Field 1</th><th>Field 2</th></tr>
</thead>
<tbody> <!-- row -->
<tr><td>data11</td><td>data12</td></tr>
</tbody>
<tbody> <!-- row -->
<tr><td>data21</td><td>data22</td></tr>
</tbody>
</table>
So tbody tr:nth-child(even)
would never match because each <tbody>
has only one <tr>
.
Solution
Put the outer v-for
on the <tr>
instead of <tbody>
:
<table>
<tbody>
<tr v-for="row in tableData.rows">
<td v-for="colName in tableData.columnsNames">{{ row[Object.keys(colName)[0]] }}</td>
</tr>
</tbody>
</table>
demo
You can try with js instead of css:
new Vue({
el: "#demo",
data() {
return {
tableData: {'columnsNames': [{"field1": "Field 1"}, {"field2": "Field 2"}, {"field3": "Field 3"}, {"field4": "Field 4"}], 'rows': [{"field1": "data11", "field2":"data12", "field3":"data13", "field4":"data14"}, {"field1": "data21", "field2":"data22", "field3": "data23", "field4":"data24"},]}
}
},
methods: {
// find out if index of row is even
isEven(num) {
return (num % 2) == 0;
}
}
})
.tbl {
border-collapse: collapse;
margin: 20px 0 0 20px;
font-size: 1em;
font-family: Poppins;
min-width: 400px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
}
.tbl thead tr {
background-color: #980000;
color: #ffffff;
text-align: left;
}
.tbl th,
.tbl td {
padding: 6px 10px;
text-align: center;
}
.tbl tbody tr {
border-bottom: 1px solid #dddddd;
}
.even {
background-color: #f3f3f3;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<table class="tbl" ref="thisTable">
<thead>
<tr>
<th v-for="(columnName, i) in tableData.columnsNames" :key="i"> {{Object.values(columnName)[0]}} </th>
</tr>
</thead>
<tbody v-for="(row, idx) in tableData.rows" :key="idx">
<tr>
<!-- call method and attach class -->
<td :class="!isEven(idx) ? 'even' : ''" v-for="(colName, i) in tableData.columnsNames" :key="i">{{ row[Object.keys(colName)[0]] }}</td>
</tr>
</tbody>
</table>
</div>
I want to change the background color of even rows in a HTML table. This was working when I had a table with known column names and one v-for
for rows, but now I have unknown columns and rows so I have to do a double v-for
and I can’t get it done with my previous approach.
HTML:
<template>
<table class="tbl" ref="thisTable">
<thead>
<tr>
<th v-for="columnName in tableData.columnsNames"> {{Object.values(columnName)[0]}} </th>
</tr>
</thead>
<tbody v-for="row in tableData.rows">
<tr>
<td v-for="colName in tableData.columnsNames">{{ row[Object.keys(colName)[0]] }}</td>
</tr>
</tbody>
</table>
</template>
CSS
<style scoped>
.tbl {
border-collapse: collapse;
margin: 20px 0 0 20px;
font-size: 1em;
font-family: Poppins;
min-width: 400px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
}
.tbl thead tr {
background-color: #980000;
color: #ffffff;
text-align: left;
}
.tbl th,
.tbl td {
padding: 6px 10px;
text-align: center;
}
.tbl tbody tr {
border-bottom: 1px solid #dddddd;
}
.tbl tbody tr:nth-child(even) {
background-color: #f3f3f3;
}
</style>
tableData
structure:
{'columnsNames': [{"field1: "Field 1"}, {"field2: "Field 2"}], 'rows': [{"field1: "data11", "field2:"data12"}, {"field1: "data21", "field2:"data22"}]}
Marked as solution. Does the job without the need of extra javascript code.