I have an array of objects, which contains menu's from a restaurant, where the user can choose a timeslot where the menu can be delivered.
here is an example of a menu object:
{
date: '2022-02-10',
slots: [
{
stock: 10,
start: '06:00',
end: '08:00',
},
{
stock: 8,
start: '10:00',
end: '12:00',
},
{
stock: 3,
start: '12:00',
end: '14:00',
},
{
stock: 3,
start: '14:00',
end: '16:00',
},
{
stock: 3,
start: '16:00',
end: '18:00',
},
{
stock: 20,
start: '18:00',
end: '20:00',
},
{
stock: 8,
start: '20:00',
end: '22:00',
},
],
},
and here is how I render them:
<div v-for="(slot, index) in slots" :key="index">
<input type="radio" :id="index" name="slot" />
<label :for="index">
{{ slot.start.slice(0, 2) }} - {{ slot.end.slice(0, 2) }}
</label>
</div>
so far so good. Now I want to group the timeslots into "morning", "afternoon" and "evening" based on the time and display them like this:
Morning
06 - 08 10 - 12
Afternoon
12 - 14 14 - 16 16 - 18
Evening
18 - 20 20 - 22
How can I achieve that??
Thanks in advance...
CodePudding user response:
Group the menu slots by the end time then render them using two v-for
:
Vue.config.devtools = false;
Vue.config.productionTip = false;
function pushToSlotTime(acc, slotTime, curr) {
if (acc[slotTime]) {
acc[slotTime].push(curr);
} else {
acc[slotTime] = [];
acc[slotTime].push(curr);
};
return acc;
}
new Vue({
el: '#app',
data() {
return {
menu: {
date: '2022-02-10',
slots: [{
stock: 10,
start: '06:00',
end: '08:00',
},
{
stock: 8,
start: '10:00',
end: '12:00',
},
{
stock: 3,
start: '12:00',
end: '14:00',
},
{
stock: 3,
start: '14:00',
end: '16:00',
},
{
stock: 3,
start: '16:00',
end: '18:00',
},
{
stock: 20,
start: '18:00',
end: '20:00',
},
{
stock: 8,
start: '20:00',
end: '22:00',
},
],
},
}
},
computed: {
groupedMenuSlots() {
return this.menu.slots.reduce((acc, curr) => {
let [end] = curr.end.split(':')
if ( end <= 12) {
return pushToSlotTime(acc, 'morning', curr)
} else if ( end > 12 && end <= 18) {
return pushToSlotTime(acc, 'afternoon', curr)
} else {
return pushToSlotTime(acc, 'evening', curr)
}
}, {})
}
}
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app" >
<div v-for="(slots,key, index) in groupedMenuSlots" :key="index">
<div>{{key}}</div>
<span v-for="slot in slots">
<input type="radio" :id="index" name="slot" />
<label :for="index">
{{ slot.start.slice(0, 2) }} - {{ slot.end.slice(0, 2) }}
</label>
</span>
</div>
</div>