Laravel中Ajax提交后模态框内表单无法重置问题求助
问题:Ajax提交模态框表单时第二次提交重复发送首次数据
我用Tailwind和Laravel构建了一个嵌入模态框的表单,通过Ajax实现提交功能。表单首次提交成功,但第二次提交时会同时发送第一次和第二次的数据。尝试了多种表单重置方法均无效,希望表单提交后能完全重置。
Ajax代码
$('#appointmentForm').on('submit', function(e) { $("#save").attr("disabled", true); e.preventDefault(); var form = new FormData(); var patientId = $('#patient').val(); var doctor_id = $('#doctor_id').val(); if (patientId == 0 || doctor_id == 0) { displayErrorMessage("Please select doctor and patient."); } else { var title = $('#title').val(); var status = $('#status').val(); var start1 = jQuery.fullCalendar.formatDate(start, "YYYY-MM-DD HH:mm:ss"); var end1 = jQuery.fullCalendar.formatDate(end, "YYYY-MM-DD HH:mm:ss"); var appointment_description = $('#appointment_description').val(); var source1 = $('#source').val(); var source = source1 != '' ? source1 : 0; var appointment_type = $('#appointment_type').val(); var new_patient_timeslot1 = $('#new_patient_timeslot1').val(); var followup_patient_timeslot1 = $('#followup_patient_timeslot1').val(); var procedure_timeslot1 = $('#procedure_timeslot1').val(); var location_id = $('#location_id').val(); var t1 = new Date(start1).getTime(); form.append('provider_id', eId); form.append('patientId', patientId); form.append('title', title); form.append('status', status); form.append('start', start1); form.append('end', end1); form.append('appointment_description', appointment_description); form.append('source', source); form.append('appointment_type', appointment_type); form.append('doctor_id', doctor_id); form.append('location_id', location_id); form.append('type', 'add'); if (appointment_type == 1) { form.append('timeslot', new_patient_timeslot1); jQuery.ajax({ url: "{{ url('/fullcalenderAjax') }}", headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }, data: form, type: "POST", cache: false, processData: false, contentType: false, beforeSend: function() { $('.loader').css("display", "block"); }, complete: function() { $('.loader').css("display", "none"); }, success: function(data) { $('#save').removeAttr("disabled"); jQuery("#appointmentForm").trigger("reset"); if (data == 0) { displayErrorMessage("Doctor is not available on that time."); } else { displayMessage("Appointment Created Successfully"); calendar.fullCalendar('renderEvent', { id: data.id, title: data.title, start: data.start, end: data.end, allDay: allDay, backgroundColor: '#1BA41D' }, false); } calendar.fullCalendar('unselect'); } }); } } });
已尝试的重置方法
试过以下几种方式重置表单,但都无效:
- 自定义重置函数:
function resetModalData() { console.log('resetting...'); // $('#patient').val("0"); // $('#patient').val(null).trigger('change'); $('#title').val(''); // $('#appointment_description').val(''); jQuery('#appointment_description').summernote('code', ''); $('#source').val(''); $('#appointment_type').val(''); $('#new_patient_timeslot1').val(''); $('#followup_patient_timeslot1').val(''); $('#procedure_timeslot1').val(''); }
- 原生表单重置:
$("#static-backdrop-modal-preview").find("form")[0].reset();
- jQuery触发重置事件:
jQuery("#appointmentForm").trigger("reset");
问题原因与解决方案
核心原因
问题大概率是表单提交事件被重复绑定:如果模态框是动态渲染(比如每次打开时重新生成),或者绑定事件的代码被多次执行,会导致submit事件被绑定多次。每次提交时,多个事件回调会同时触发,各自发送一次请求,最终出现第二次提交包含两次数据的情况。
另外,部分特殊控件(如Summernote编辑器)无法通过原生reset事件完全清空,也是表单残留旧数据的原因之一。
解决方案
1. 避免事件重复绑定
在绑定submit事件前,先解除之前的绑定,确保每次只有一个回调生效:
// 先解绑再绑定,防止重复绑定 $('#appointmentForm').off('submit').on('submit', function(e) { // 原有的事件处理代码 });
2. 完善表单重置逻辑
覆盖所有控件的重置,包括第三方编辑器和下拉选择框:
function resetModalData() { // 重置原生表单控件 $("#appointmentForm")[0].reset(); // 重置Summernote编辑器 jQuery('#appointment_description').summernote('code', ''); // 重置下拉选择框(如果用了Select2等插件,需额外触发change事件) $('#patient').val(0).trigger('change'); $('#doctor_id').val(0).trigger('change'); $('#appointment_type').val('').trigger('change'); // 清空自定义输入框 $('#new_patient_timeslot1').val(''); $('#followup_patient_timeslot1').val(''); $('#procedure_timeslot1').val(''); }
然后在Ajax的success回调中调用该函数,同时在模态框关闭时也执行重置,避免下次打开残留数据:
// Ajax成功回调中替换原重置代码 success: function(data) { $('#save').removeAttr("disabled"); resetModalData(); // 调用自定义重置函数 // 后续逻辑不变 } // 模态框关闭时重置(以Bootstrap模态框为例) $('#static-backdrop-modal-preview').on('hidden.bs.modal', function () { resetModalData(); });
3. 确保FormData每次都是全新实例
虽然你的代码已经在事件内部创建FormData,但可以将其移到else块开头,确保只有在提交条件满足时才创建全新实例:
else { var form = new FormData(); // 移至此处,确保每次提交用新实例 var title = $('#title').val(); // 后续append代码不变 }
验证步骤
- 先添加
off('submit')解除重复绑定,测试是否还会重复提交 - 替换重置逻辑为完善后的
resetModalData函数 - 测试模态框关闭后重新打开,表单是否完全清空
内容的提问来源于stack exchange,提问作者Mohammad Ali Khan
相关产品推荐
相关产品推荐

