Reputation: 6025
Currently I have this list:
As you can see these items have the same date, 21/09
. And when a list item has the same date (yyyy/mm/dd
) I want it to look like this:
(sorry for my drawing)
I want to group items that has the same date under a header that tells their common date.
I've been trying to tackle this idea for a while now, but I can't get started. Every time I come up with something it doesn't work (sad I know).
I think I first need to get all events items date in the format yyyy/mm/dd
and then somehow check if evens on that date contains one or more events. And if they do, they'll get a header with their date and all of the events will be displayed below. Otherwise nothing will be shown.
If you have any tips please let me know!!
Thanks for reading.
So the parent component that hold all these list is dash.js:
events
.slice(-this.state.showCount)
.reverse()
.map((event, i) => {
var driver = event.driver ? keyedDrivers[event.driver] : false
var carrier = driver ? keyedCarriers[driver.carrier] : false
var customer = event.customer
? keyedCustomers[event.customer]
: false
return (
<div key={i}>
<EventItem // This is the list item
event={event}
customer={customer}
carrier={carrier}
driver={driver}
lock={keyedLocks[event.unit] || { address: {} }}
/>
</div>
)
})
And inside of EventItem
I simply use all of the props I passed to EventItem
to display a list.
Also, it's the event object that contains the date:
_id: ObjectId("12345")
customer: ObjectId("54321")
timestamp: 2017-08-25T12:04:14.001Z
Upvotes: 1
Views: 351
Reputation: 24660
Lodash has a method called groupBy
. I think you can make use of it. There are also methods you can use without a third party library.
Example
let eventsGroups = _.groupBy(events, (event) => moment(event.timestamp).format('YYYY/MM/DD'))
renderEvents() {
return Object.keys(eventsGroups).map((groupName) => {
return (
<div>
{ renderHeader(groupName) }
{ renderEvents(eventsGroups[groupName]) }
</div>
)
});
}
renderHeader(groupName) {
return <h1>{groupName}</h1>
}
renderEvents(events) {
return events.map((event) => {
return <EventItem event={event} />
})
}
Upvotes: 1
Reputation: 972
The best way to do this is probably to convert your one input list into a list of groups (by date)
const input = [{date: '21/09'}, {date: '21/09'},
{date: '22/09'}, {date: '23/09'},
{date: '24/09'}, {date: '24/09'}]
Now you can reduce
this from a list, into an objet keyed by dates
const output = input.reduce((dates, item) => {
if (dates[item.date]) {
dates[item.date].push(item)
} else {
dates[item.date] = [item]
}
return dates
}, {})
// returns
{
'21/09': [
{ date: '21/09' },
{ date: '21/09' },
],
'22/09': [{ date: '22/09' }],
'23/09': [{ date: '23/09' }],
'24/09': [
{ date: '24/09' },
{ date: '24/09' },
]
}
You can then do
Object.keys(output).map(date => (
<div key={date}>
<Heading>{date}</Heading>
{output[date].map(item => (
<Item>
...
</Item>
))}
</div>
))
There's plenty you can to do tidy up that code, but hopefully it's enough to get started
Upvotes: 1