免责声明:Ruby和Rails相对较新,因此我非常感谢您提供详尽的答案,以便我理解。 :)
我正在构建一个Rails(6.0.2)应用程序(带有webpack),使用simple_form(5.0.2)创建用于提交目的的表单,并使用Bootstrap(4.4.1)来设计UX的样式。
现在,我正在尝试制作一个单页的Rails应用程序,并且已经添加了 Next / Previous 按钮,其中使用jQuery进行了AJAX调用,到目前为止效果很好。我还有一个 Submit (提交)按钮,该按钮在输入上运行一堆验证,如果发现错误,则返回错误。使用常规的 Submit (提交)按钮f.submit
(由simple_form提供)时,URL更改为PUT / PATCH URL,而页面重新渲染并且错误显示为嵌入式(如预期的那样)。
用户流程是这样的:自动生成新患者(在JS中),以便将他们重定向到编辑URL,而无论如何,现有患者都将被定向到编辑URL。他们最终将从编辑URL更改表单字段,直到准备好提交。但是,这是我遇到问题的地方。
我希望拥有单页应用程序体验,所以我决定自己创建 Submit (提交AJAX PATCH请求)按钮,该按钮也将最终运行验证。网络活动(在Chrome开发者工具中)实际上揭示了响应,并且呈现了内联验证,但是我得到了 重定向回编辑页面,从而清除了这些错误。 此处未共享确保运行验证检查的逻辑,但我已经证实是 不是问题。
是否有一种简单的方法来利用AJAX调用中simple_form和Bootstrap之间存在的现有验证错误集成?
simple_form视图:
-# frozen_string_literal: true
= simple_form_for(@patient_intake_form) do |f|
= f.error_notification
= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present?
(...)
.form-actions
.form_prev
= link_to 'Previous','#',class: 'prev_section change_section btn btn-outline-prev'
.form_next
= link_to 'Next',class: 'next_section change_section btn btn-next'
.form_submit
= link_to 'Submit',class: 'submit_form change_section btn btn-submit'
在“下一个/上一个”和“提交”按钮上执行的javascript:
$(document).on('turbolinks:load',() => {
if ($('body.patient_intakes-new').length) {
$.post({url: "/patient_intakes/",data: $('.simple_form').serialize()});
};
$('.change_section').on('click',() => {
section_data = $('.simple_form').find('.active :input').serialize();
if (section_data.length) {
request = $.ajax({
type: "PATCH",url: '.',data: section_data
});
}
});
});
和控制器:
class PatientIntakesController < ApplicationController
load_and_authorize_resource :patient_intake_form
before_action :prepare_intake_form,only: [:edit,:update]
# GET /patient_intakes/new
def new
intake_form = IntakeForm.find_by(user_id: current_user.id)
if intake_form
redirect_to edit_patient_intake_path(intake_form.id)
return
end
@patient_intake_form = PatientIntakeForm.new
@patient_intake_form.prepopulate!(email: current_user.email)
end
# GET /patient_intakes/1/edit
def edit
end
# POST /patient_intakes
# POST /patient_intakes.json
def create
@patient_intake_form = PatientIntakeForm.new
respond_to do |format|
if @patient_intake_form.validate(patient_params)
@patient_intake_form.save
if @patient_intake_form.status == 'in_review'
format.html { redirect_to '/submission' }
else
format.html { redirect_to edit_patient_intake_path(@patient_intake_form.to_param) }
end
else
format.html { render :new }
format.json { render json: @patient_intake_form.errors,status: :unprocessable_entity }
end
end
end
# PATCH/PUT /patient_intakes/1
# PATCH/PUT /patient_intakes/1.json
def update
respond_to do |format|
if @patient_intake_form.validate(patient_params)
@patient_intake_form.save
if @patient_intake_form.status == 'in_review'
format.html { redirect_to '/submission' }
else
format.html { render :edit }
format.json { render json: @patient_intake_form }
end
else
format.html { render :edit }
format.json { render json: @patient_intake_form.errors,status: :unprocessable_entity }
end
end
end
private
# Use callbacks to share common setup or constraints between actions.
def prepare_intake_form
@patient_intake_form = PatientIntakeForm.find(params[:id])
end
# Never trust parameters from the scary internet,only allow the white list through.
def patient_params
params.require(:patient_intake).merge(user_id: current_user.id)
end
end
我发现我还可以通过将f.submit
设置为表单初始化,并向其中添加remote: true
,来使format.js {}
提交按钮运行AJAX POST调用创建/更新格式,从而使我的应用程序体验完全一页。
其他StackOverflow问题以某种方式解决了这个问题,但我无法使这些解决方案正常工作,例如:
AJAX form (using simple_form) with preserved error validation
任何指针,技巧都将不胜感激!!干杯! :)