Laravel表单验证失败时恢复jQuery动态添加输入字段的方法
解决Laravel非Ajax表单提交验证错误后动态字段丢失问题
核心思路
利用Laravel的old()函数获取提交的动态字段数据,在页面加载时通过JavaScript重新渲染这些字段,同时同步更新计数器,确保后续添加新字段的序号正确。
步骤1:修改HTML与Blade模板逻辑
在表格tbody中,保留默认第一行的同时,根据old('expense_details')的数据循环生成验证错误前添加的动态行,并填充用户之前输入的值:
<div class="table-responsive-sm"> <button type="button" id="addRow" class="btn btn-success btn-sm mt-3 mb-2 float-right"><i class="fas fa-plus"></i> Add Row</button> <table class="table table-bordered align-middle table-hover text-center align-middle detail-table" id="Add_Expense_Table_id"> <thead> <tr> <th>name</th> <th>value</th> <th>Action</th> </tr> </thead> <tbody id="Add_Expense_Table_id_tbody"> <!-- 默认第一行 --> <tr> <td><input type="text" id="name1" class="form-control" name="expense_details[1][name]" value="{{ old('expense_details.1.name') }}"></td> <td><input type="number" id="value1" class="form-control" name="expense_details[1][value]" value="{{ old('expense_details.1.value') }}"></td> <td><button type="button" onclick="DeleteRow(this);" class="btn btn-danger btn-sm"><i class="fas fa-ban"></i></button></td> </tr> <!-- 渲染验证错误前添加的动态行 --> @if(old('expense_details')) @foreach(old('expense_details') as $index => $detail) @if($index > 1) <!-- 跳过默认的第一行 --> <tr> <td><input type="text" id="name{{ $index }}" class="form-control" name="expense_details[{{ $index }}][name]" value="{{ $detail['name'] }}"></td> <td><input type="number" id="value{{ $index }}" class="form-control" name="expense_details[{{ $index }}][value]" value="{{ $detail['value'] }}"></td> <td><button type="button" onclick="DeleteRow(this);" class="btn btn-danger btn-sm"><i class="fas fa-minus"></i></button></td> </tr> @endif @endforeach @endif </tbody> </table> </div>
步骤2:修正JavaScript逻辑
调整计数器初始化逻辑,优先基于old('expense_details')的长度设置初始值,同时修正原代码中value输入框id重复的问题:
<script> // 初始化计数器:优先使用old数据的长度,无old数据则用页面现有行数 let oldExpenses = {!! json_encode(old('expense_details') ?: []) !!}; let counter = oldExpenses.length > 0 ? oldExpenses.length + 1 : $("#Add_Expense_Table_id_tbody tr").length + 1; $("#addRow").on('click', function () { let dataToAppend = ` <tr> <td><input type="text" id="name${counter}" class="form-control" name="expense_details[${counter}][name]" value="{{ old('expense_details.${counter}.name') }}"></td> <td><input type="number" id="value${counter}" class="form-control" name="expense_details[${counter}][value]" value="{{ old('expense_details.${counter}.value') }}"></td> <td><button type="button" onclick="DeleteRow(this);" class="btn btn-danger btn-sm"><i class="fas fa-minus"></i></button></td> </tr> `; $('#Add_Expense_Table_id_tbody').append(dataToAppend); counter++; }); function DeleteRow(that) { $(that).closest('tr').remove(); counter--; // 可选:若需要字段索引连续,可在此遍历所有行重新设置name属性的索引值 // Laravel支持非连续索引的数组,若无特殊需求可忽略此步骤 } </script>
关键细节说明
- 计数器同步:通过
old('expense_details')的长度初始化计数器,避免新增字段序号与已恢复字段重复。 - 旧值回填:动态生成的行同样使用
old()函数填充用户之前的输入,保证表单数据连贯性。 - 唯一id修正:将原代码中固定的
value1id改为value${counter},避免多个元素id重复导致的DOM问题。
内容的提问来源于stack exchange,提问作者Khayam Khan
相关产品推荐
相关产品推荐

