单表单多提交按钮异常:实现不同Action及DELETE请求(含SweetAlert)
问题
我有一个表单包含两个提交按钮,分别对应不同的表单action和method:
- 一个用于提交表单更换图片
- 另一个用于删除操作
执行删除操作时,希望通过SweetAlert弹窗确认后,向DELETE路由发送DELETE请求,但当前实现无法正常工作。请问如何在同一个表单中实现两个提交按钮对应不同的表单action?
现有代码
HTML表单代码
<tbody> <form method="POST" enctype="multipart/form-data"> @csrf <input type="hidden" name="old_image" value="{{$products->product_thumbnail}}"> @foreach ($multiImages as $key => $item) <tr> <th scope="row">{{$key+1}}</th> <td><img src="{{asset($item->photo_name)}}" alt="" style="width: 70px;height: 40px;"></td> <td><input type="file" class="form-group" name="multi_img[{{$item->id}}]"></td> <td> <input type="submit" formaction="{{route('vendor.update.product.multiImage',$item->id)}}" class="btn btn-primary px-4" value="Save Product"> </td> <td> <input id="delete" onclick="submitResult(event)" data-method="delete" data-action="{{route('vendor.delete.product.multiimage',$item->id)}}" value="Delete Product" class="form-group btn-danger"> </td> </tr> @endforeach </form> </tbody>
路由信息
Route::delete('vendor/delete/product/multiimage/{id}','vendorDeleteMultiImage')->name('vendor.delete.product.multiimage');
SweetAlert JS代码
function submitResult(e) { let btn = e; e.preventDefault(); Swal.fire({ title: 'Are you sure?', text: "You won't be able to revert this!", icon: 'warning', showCancelButton: true, confirmButtonColor: '#3085d6', cancelButtonColor: '#d33', confirmButtonText: 'Yes, delete it!' }).then((result,e) => { if (result.isConfirmed) { btn.target.form.action = btn.target.getAttribute('data-action'); btn.target.form.method = btn.target.getAttribute('data-method'); var input = document.createElement("input"); input.setAttribute("type", "hidden"); input.setAttribute("name", "_method"); input.setAttribute("value", "DELETE"); btn.target.form.appendChild(input); btn.target.form.submit(); Swal.fire( 'Deleted!', 'Your file has been deleted.', 'success' ) } }) }
解决方案
当前代码失效的核心问题:
- 删除按钮未指定
type,默认会被识别为submit类型,和更新按钮的表单提交逻辑冲突 - 直接修改原表单的
action和method会污染原表单状态,影响后续更新操作 - JS中事件对象处理混乱,导致获取元素时出错
修正方案
1. 调整删除按钮类型
将删除按钮改为button类型,避免触发表单默认提交:
<td> <button type="button" onclick="submitResult(this)" data-action="{{route('vendor.delete.product.multiimage',$item->id)}}" class="btn btn-danger">Delete Product</button> </td>
2. 重写JS逻辑(创建独立表单提交)
直接创建临时表单处理删除请求,不修改原表单状态,避免冲突:
function submitResult(btn) { Swal.fire({ title: '确定要删除吗?', text: "删除后无法恢复!", icon: 'warning', showCancelButton: true, confirmButtonColor: '#3085d6', cancelButtonColor: '#d33', confirmButtonText: '是的,删除它!' }).then((result) => { if (result.isConfirmed) { // 创建临时表单 const deleteForm = document.createElement('form'); deleteForm.method = 'POST'; deleteForm.action = btn.getAttribute('data-action'); // 添加CSRF令牌 const csrfInput = document.createElement('input'); csrfInput.type = 'hidden'; csrfInput.name = '_token'; csrfInput.value = document.querySelector('input[name="_token"]').value; deleteForm.appendChild(csrfInput); // 添加DELETE方法伪装字段(Laravel要求) const methodInput = document.createElement('input'); methodInput.type = 'hidden'; methodInput.name = '_method'; methodInput.value = 'DELETE'; deleteForm.appendChild(methodInput); // 提交表单并添加到DOM(部分浏览器要求表单在DOM内才能提交) document.body.appendChild(deleteForm); deleteForm.submit(); Swal.fire( '已删除!', '你的文件已被删除。', 'success' ) } }) }
额外说明
- 原表单中更新按钮的
formaction逻辑是正常的,无需修改,它会自动覆盖表单的默认action提交到对应路由 - 临时表单提交后,浏览器会自动跳转/刷新,DOM残留的临时表单会被自动清理,无需额外处理
内容的提问来源于stack exchange,提问作者Persian
相关产品推荐
相关产品推荐

