Laravel批量更新仅首行生效问题求助
问题:循环渲染的5个表单仅第一行数据能更新
问题代码
Blade 视图代码
@php $no = 1; @endphp @forelse ($permintaans as $b) <tr> <td>{{ $no ++ }}</td> <td> {{ $b->nama_kategori }} {{ $b->nama_atk }} </td> <td> <form action="{{ route('detilpermintaan.update') }}" name="Patk" id="Patk" method="POST" style="display: inline-block;" class="was-validated"> @csrf @method('PUT') <div class="input-group input-group-sm mb-3"> <input type="number" name="id[]" value="{{ $b->id }}" hidden> <input type="number" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-sm" name="satuan_permintaan[]" value="{{ $b->satuan_permintaan }}" min="1" max={{ $b->stok }} required> <span class="input-group-text" id="inputGroup-sizing-sm">{{ $b->subsatuan_atk }}</span> </div> </form> </td> <td> <form action="{{ route('detilpermintaan.destroy', $b->id) }}" method="POST" style="display: inline-block;"> @csrf @method('DELETE') <button type="submit" class="btn custom2-btn"></button> </form> </td> </tr> @empty @endforelse </tbody> </table> </div> <div class="card-footer text-muted"> @if ($permintaans->isEmpty()) @else <div class="alert alert-warning" role="alert"> <h6><b> jenis barang dengan quantity sebanyak item </b></h6> <button type="submit" value="Update" class="btn btn-success btn-sm" onclick="submitForms()"><i class="bi bi-floppy2-fill"></i> Simpan </button> </div> @endif <script> function submitForms() { var forms = document.getElementsByName("Patk"); forms.forEach(function (form) { form.submit(); }); document.getElementById('Patk').submit(); } </script>
控制器代码
public function update(Request $request) { try { DB::beginTransaction(); for ($i = 0; $i < count($request->input('id')); $i++) { $id = $request->id[$i]; Detilpermintaan::where('id', $id)->update([ 'satuan_permintaan' => $request->satuan_permintaan[$i], 'permintaan_id' => $id_permintaan, // Add other fields as needed ]); } DB::commit(); } catch (\Exception $e) { DB::rollback(); // Handle the exception dd($e->getMessage()); // Output the error message for debugging return response()->json(['error' => 'Error updating records.']); } return redirect()->route('detilpermintaan.index'); }
问题原因
- 重复ID冲突:HTML要求ID全局唯一,但循环中每个表单都使用
id="Patk",document.getElementById('Patk')只会获取第一个表单,同时重复ID会导致DOM解析异常。 - 多表单提交中断:调用
form.submit()会触发页面跳转,第一个表单提交后页面刷新,后续表单的提交请求会被中断,只有第一个请求能完成。 - 变量未定义:控制器中
$id_permintaan未赋值,会直接抛出错误,导致更新流程失败。 - 单表单仅传单条数据:每个独立表单只能提交当前行的一组数据,控制器中的循环逻辑针对单请求数组设计,但每次请求仅含一组数据,循环冗余且无效。
解决方案
方案1:合并为单个表单(推荐,高效简洁)
将所有输入项放入同一个表单,一次提交所有数据,避免多次请求的问题:
修改后的Blade视图
@php $no = 1; @endphp <form action="{{ route('detilpermintaan.update') }}" method="POST" class="was-validated"> @csrf @method('PUT') <table> <tbody> @forelse ($permintaans as $b) <tr> <td>{{ $no ++ }}</td> <td> {{ $b->nama_kategori }} {{ $b->nama_atk }} </td> <td> <div class="input-group input-group-sm mb-3"> <input type="number" name="id[]" value="{{ $b->id }}" hidden> <input type="number" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-sm" name="satuan_permintaan[]" value="{{ $b->satuan_permintaan }}" min="1" max="{{ $b->stok }}" required> <span class="input-group-text" id="inputGroup-sizing-sm">{{ $b->subsatuan_atk }}</span> </div> </td> <td> <form action="{{ route('detilpermintaan.destroy', $b->id) }}" method="POST" style="display: inline-block;"> @csrf @method('DELETE') <button type="submit" class="btn custom2-btn"></button> </form> </td> </tr> @empty @endforelse </tbody> </table> <div class="card-footer text-muted"> @if (!$permintaans->isEmpty()) <div class="alert alert-warning" role="alert"> <h6><b> jenis barang dengan quantity sebanyak item </b></h6> <button type="submit" class="btn btn-success btn-sm"><i class="bi bi-floppy2-fill"></i> Simpan</button> </div> @endif </div> </form>
修改后的控制器(补充$id_permintaan赋值逻辑)
public function update(Request $request) { try { DB::beginTransaction(); // 根据实际业务逻辑赋值$id_permintaan,示例从请求或用户关联数据获取 $id_permintaan = $request->input('permintaan_id') ?? auth()->user()->active_permintaan->id; foreach ($request->input('id') as $index => $id) { Detilpermintaan::where('id', $id)->update([ 'satuan_permintaan' => $request->satuan_permintaan[$index], 'permintaan_id' => $id_permintaan, ]); } DB::commit(); return redirect()->route('detilpermintaan.index')->with('success', '所有数据更新成功'); } catch (\Exception $e) { DB::rollback(); return redirect()->back()->with('error', '更新失败:'.$e->getMessage()); } }
方案2:保留多表单,用AJAX异步提交
若需保留独立表单,使用AJAX提交避免页面跳转,同时修正ID问题:
修改Blade视图(添加唯一标识,移除重复ID)
@php $no = 1; @endphp @forelse ($permintaans as $b) <tr> <td>{{ $no ++ }}</td> <td> {{ $b->nama_kategori }} {{ $b->nama_atk }} </td> <td> <form action="{{ route('detilpermintaan.update') }}" name="Patk-{{ $b->id }}" class="was-validated patk-form"> @csrf @method('PUT') <div class="input-group input-group-sm mb-3"> <input type="number" name="id[]" value="{{ $b->id }}" hidden> <input type="number" class="form-control" aria-label="Sizing example input" aria-describedby="inputGroup-sizing-sm" name="satuan_permintaan[]" value="{{ $b->satuan_permintaan }}" min="1" max="{{ $b->stok }}" required> <span class="input-group-text" id="inputGroup-sizing-sm">{{ $b->subsatuan_atk }}</span> </div> </form> </td> <td> <form action="{{ route('detilpermintaan.destroy', $b->id) }}" method="POST" style="display: inline-block;"> @csrf @method('DELETE') <button type="submit" class="btn custom2-btn"></button> </form> </td> </tr> @empty @endforelse </tbody> </table> </div> <div class="card-footer text-muted"> @if (!$permintaans->isEmpty()) <div class="alert alert-warning" role="alert"> <h6><b> jenis barang dengan quantity sebanyak item </b></h6> <button type="button" class="btn btn-success btn-sm" onclick="submitForms()"><i class="bi bi-floppy2-fill"></i> Simpan</button> </div> @endif </div> <script> function submitForms() { const forms = document.querySelectorAll('.patk-form'); let successCount = 0; const totalForms = forms.length; forms.forEach(form => { fetch(form.action, { method: form.method, body: new FormData(form), headers: { 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content } }) .then(response => response.json()) .then(data => { successCount++; if (successCount === totalForms) { alert('所有数据更新成功'); window.location.href = "{{ route('detilpermintaan.index') }}"; } }) .catch(error => { console.error('更新失败:', error); alert('部分数据更新失败,请检查'); }); }); } </script>
控制器调整为返回JSON响应
public function update(Request $request) { try { DB::beginTransaction(); $id_permintaan = $request->input('permintaan_id') ?? auth()->user()->active_permintaan->id; foreach ($request->input('id') as $index => $id) { Detilpermintaan::where('id', $id)->update([ 'satuan_permintaan' => $request->satuan_permintaan[$index], 'permintaan_id' => $id_permintaan, ]); } DB::commit(); return response()->json(['success' => true]); } catch (\Exception $e) { DB::rollback(); return response()->json(['error' => $e->getMessage()], 500); } }
内容的提问来源于stack exchange,提问作者Kknida
相关产品推荐
相关产品推荐

