I've got a nested array that I would like to display in a table. However, I can't get my nested array to show correctly.
My data set looks like this:
[
{
"dd":"February",
"md":[
{ "dag":"2020-02-01" },
{ "dag":"2020-02-02" },
{ "dag":"2020-02-03" }
]
},
{
"dd":"March",
"md":[
{ "dag":"2020-03-01" },
{ "dag":"2020-03-02" },
{ "dag":"2020-03-03" }
]
}
]
I would like a table which look like this.
| February | March |
| 2020-02-01 | 2020-03-01 |
| 2020-02-02 | 2020-03-02 |
| 2020-02-03 | 2020-03-03 |
I got this working, but it gives me 2 tables instead of one.
<template v-for="(md2, index) in md2s">
<table :key=index >
<thead >
<tr align="center">
<th style="width: 80px">{{md2}}</th>
</tr>
</thead>
<tr v-for="(date, index) in md2.md" :key=index>
<td align="center" >{{date.dag }}</td>
</tr>
</table>
</template>
All help is appreciated.
br. Erik
What you need is two diferent iterations. One for the header and another for the table body. For the header, all you need is to add the month name on order. The snippet shows with the computed property months
how to do it. This completes the header iteration and the first.
The second one is a little more complex. You need to know beforehand how many lines there will be, for that I made a computed property maxLength
that searches over each md
and gives the greater one. Then for each row iterate over each month and then verify if the month has enough dates with v-if
and if it does look up the desired date from the index and the nested data sctructure. That resumes the second iteration.
The below snippet is a working example with a more complex data showing what could happen with different md
sizes and automatic month ordering.
var app = new Vue({
el: '#app',
data: () => ({
nested: [
{ "dd": "February",
"md": [{ "dag": "2020-02-01" },{ "dag": "2020-02-02" },{ "dag": "2020-02-03" },{ "dag": "2020-03-04" }]
},
{ "dd": "March",
"md": [{ "dag": "2020-03-01" },{ "dag": "2020-03-02" },{ "dag": "2020-03-03" }]
},
{ "dd": "January",
"md": [{ "dag": "2020-01-01" }]
}
]
}),
computed: {
staticMonths() {
return Array.from(Array(12),(e,i)=>new Date(25e8*++i).toLocaleString('en-US',{month: 'long'}));
},
months() {
return this.nested.map(item => item.dd).sort((a, b) => {
const A = this.staticMonths.indexOf(a);
const B = this.staticMonths.indexOf(b);
return A-B;
});
},
maxLength() {
return this.nested.reduce((accum, curr) => accum > curr.md.length ? accum : curr.md.length, 0);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<table>
<thead>
<tr>
<th v-for="(item, index) in months">{{ item }}</th>
</tr>
</thead>
<tbody>
<tr v-for="index in maxLength">
<td v-for="item in months">
<span v-if="nested.find(nest => nest.dd === item).md.length > index-1">
{{nested.find(nest=>nest.dd===item).md[index-1].dag}}
</span>
</td>
</tr>
</tbody>
</table>
</div>