Laravel Livewire按日期在表格中展示foreach循环数据问题
问题:Laravel Livewire考勤数据按日期表格展示格式错误
我尝试在Laravel Livewire中按日期将考勤数据展示为表格(预期每行对应一个学生,每列对应当月的每一天,单元格显示当天考勤状态),但当前输出的表格格式不符合预期,试过if条件和switch语句都无效。
数据库结构
id | name |student_id | date_of_attendance | attendance | 1 | john | STD_01 | 2024-01-01 | P | 2 | john | STD_01 | 2024-01-03 | P | 2 | john | STD_01 | 2024-01-04 | A | 3 | sean | STD_02 | 2024-01-01 | P | 4 | sean | STD_02 | 2024-01-03 | P | 2 | sean | STD_02 | 2024-01-04 | P |
控制器代码
public function AttendanceReport() { $this->validate(); // 从表单属性$this->ReportOfMonth获取月份请求 $MonthToNumber = Carbon::parse($this->ReportOfMonth)->month; $this->StudentListForAttendance = Attendance::whereMonth('date_of_attendance', '=', $MonthToNumber)->get(); $this->dateRange = CarbonPeriod::create(now()->startOfMonth(), now()->endOfMonth())->toArray(); $grouped = $this->StudentListForAttendance ->sortBy('date_of_attendance', SORT_NATURAL) ->groupBy(['student_registration_id']); $this->Attendance_Data = $grouped->all(); }
Blade视图代码
<table class="datatable table"> <thead> @if(!empty($this->dateRange)) <tr> <th>NAME</th> <th>IDNo</th> @foreach ($this->dateRange as $key=>$date) <th>{{$date->format('d')}}</th> @endforeach </tr> @endif </thead> <tbody> @if(!empty($this->Attendance_Data)) @foreach ($this->Attendance_Data as $key=>$Attendance_Datas) <tr> <td>{{$Attendance_Datas[0]->student_name}}</td> <td>{{$Attendance_Datas[0]->reg_id}}</td> @foreach ($Attendance_Datas as $key=>$Attendance) <td>{{$Attendance->attendance}}</td> @endforeach </tr> @endforeach @endif </tbody> </table>
尝试过的无效代码
@foreach ($Attendance_Datas as $key=>$Attendance) @if( \Carbon\Carbon::createFromFormat('Y-m-d', $Attendance->date_of_attendance)->format('d') == 1 ) // 我把这段复制了31次对应一个月的每一天 <td> {\Carbon\Carbon::createFromFormat('Y-m-d', $Attendance->date_of_attendance)->format('d')} {{$Attendance->attendance}} </td> @else - @endif @endforeach
解决方案
1. 优化控制器数据处理逻辑
问题出在数据分组后未按日期索引,且dateRange生成的是当前月份而非选中月份。修改控制器代码如下:
public function AttendanceReport() { $this->validate(); $selectedMonth = Carbon::parse($this->ReportOfMonth); $MonthToNumber = $selectedMonth->month; // 获取选中月份的所有考勤数据 $this->StudentListForAttendance = Attendance::whereMonth('date_of_attendance', '=', $MonthToNumber)->get(); // 生成选中月份的日期范围(而非当前月份) $this->dateRange = CarbonPeriod::create( $selectedMonth->startOfMonth(), $selectedMonth->endOfMonth() )->toArray(); // 按学生分组,并将每个学生的考勤数据按"日"作为键名索引 $grouped = $this->StudentListForAttendance ->sortBy('date_of_attendance') ->groupBy('student_registration_id') ->map(function ($attendances) { return $attendances->keyBy(function ($item) { return Carbon::parse($item->date_of_attendance)->format('d'); }); }); $this->Attendance_Data = $grouped->all(); }
2. 修改Blade视图渲染逻辑
之前的视图遍历学生的考勤记录,导致缺卡日期没有对应的<td>,列数和表头不匹配。现在改为遍历当月所有日期,每个日期对应一列,查找该学生当天的考勤状态:
<table class="datatable table"> <thead> @if(!empty($this->dateRange)) <tr> <th>NAME</th> <th>IDNo</th> @foreach ($this->dateRange as $date) <th>{{$date->format('d')}}</th> @endforeach </tr> @endif </thead> <tbody> @if(!empty($this->Attendance_Data)) @foreach ($this->Attendance_Data as $studentAttendances) <tr> <td>{{ $studentAttendances->first()->student_name }}</td> <td>{{ $studentAttendances->first()->reg_id }}</td> @foreach ($this->dateRange as $date) @php $day = $date->format('d'); // 根据日期的"日"查找对应考勤 $attendance = $studentAttendances->get($day); @endphp <td>{{ $attendance ? $attendance->attendance : '-' }}</td> @endforeach </tr> @endforeach @endif </tbody> </table>
说明
- 控制器中通过
keyBy将每个学生的考勤数据按日期的"日"作为键名,方便视图中快速查找。 - 视图遍历当月所有日期,每个日期生成一个
<td>,有考勤则显示状态,无考勤则显示-,保证表头和内容列数一致,格式符合预期。
内容的提问来源于stack exchange,提问作者p22222222
相关产品推荐
相关产品推荐

