You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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');
}

问题原因

  1. 重复ID冲突:HTML要求ID全局唯一,但循环中每个表单都使用id="Patk",document.getElementById('Patk')只会获取第一个表单,同时重复ID会导致DOM解析异常。
  2. 多表单提交中断:调用form.submit()会触发页面跳转,第一个表单提交后页面刷新,后续表单的提交请求会被中断,只有第一个请求能完成。
  3. 变量未定义:控制器中$id_permintaan未赋值,会直接抛出错误,导致更新流程失败。
  4. 单表单仅传单条数据:每个独立表单只能提交当前行的一组数据,控制器中的循环逻辑针对单请求数组设计,但每次请求仅含一组数据,循环冗余且无效。

解决方案

方案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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 13:47:01