I wanted to create team calendar of absences. Each user can define more than one absence in specific month.
Then I want to print it for each in table like this (example for 10 days):
Day | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
-----------------------------------------------|
User1 | o | o | x | x | x | x | o | o | o | x |
-----------------------------------------------|
User2 | x | o | o | o | x | x | o | x | o | x |
-----------------------------------------------|
Where the "o" is for normal day and "x" is defined as absence.
I got Users table and Absences table:
Users
id | name
Absences
id | user_id | start | end
I get the current month day value and iterate through all Users and then through the days in blade like that:
@foreach ($users as $user )
<tr>
<td> {{ $user->name }} </td>
@if($user->absences != null)
@foreach($days as $day)
@foreach ($user->absences as $absence)
@if($day >= $absence->start->format('d') && $day <= $absence->end->format('d'))
<td style="background: red"> x </td>
@else
<td style="background: blue"> o </td>
@endif
@endforeach
@endforeach
@endif
</tr>
@endforeach
The problem is that, If user have more than one absence defined, the days in his column are doubled and whole table is being crashed. When User has only 1 absence, it works OK.
Do you have any idea how do achieve that easier?
CodePudding user response:
Your problem lies in @foreach ($user->absences as $absence)
loop. You're checking all the absences for one day.
Instead, you should use a function to get all the absense days of users. I think keeping such functionality in controller is a better idea.
$users = $users->map(function ($user) {
$user['absenseDays'] = $user->absences->reduce(function ($carry, $item) {
return [...$carry, ...range($item['start'], $item['end'])];
}, []);
return $user;
});
This should create a new entry of absenseDays on each user, and the values should be an array of absense days. Let's say a user has 2 records 5-8 and 12-14, absenseDays should be [5,6,7,8,12,13,14].
In blade you need only:
@if (in_array($day, $user->absenseDays))
<td style="background: red"> x </td>
@else
<td style="background: blue"> o </td>
@endif
I wrote the function here directly. So it might not work, or can be a better way to produce the same output. But I can say that for sure, producing absenseDays array is the best approach that I can come up with.