在Bootstrap Ajax模态中使用simple_form显示内联错误 [英] Display inline errors with simple_form in a Bootstrap Ajax modal
问题描述
我在此处和
I've found similar StackOverflow questions here and here but still can't get this to work.
我正在使用Rails 3.2.8,SimpleForm 2.0.4和Twitter Bootstrap 2.1.1(通过bootstrap-sass gem 2.1.1.0).
I'm using Rails 3.2.8, SimpleForm 2.0.4, and Twitter Bootstrap 2.1.1 (via the bootstrap-sass gem 2.1.1.0).
用户应该能够从模式弹出窗口中添加联系人.如果存在验证错误,它们应该以行内显示,就像用户使用的是表格的非模式版本一样(字段周围为红色边框,字段旁边为错误消息).
The user should be able to add a contact from a modal popup window. If there are validation errors, they should appear inline, just as if the user were using a non-modal version of the form (red border around field, error message next to field).
我这样加载模态:
<a data-toggle="modal" data-target="#new-contact-modal">Go modal!</a>
这里是Bootstrap模态,它调用在非模态版本中使用的相同的contacts/contact_fields
部分. app/views/contacts/_new_modal.html.erb :
Here is the Bootstrap modal, which calls the same contacts/contact_fields
partial used in the non-modal version. app/views/contacts/_new_modal.html.erb:
<div id="new-contact-modal" class="modal hide fade" tabindex="-1"
role="dialog" aria-labelledby="new-contact-modal-label"
aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-hidden="true">×</button>
<h3 id="new-contact-modal-label"><%= t("contacts.new.header") %></h3>
</div>
<%= simple_form_for(@contact,
:remote => true,
:html => {:class => "form-horizontal",
"data-type" => :json }) do |contact_form| %>
<div id="new-contact-body" class="modal-body">
<%= render 'contacts/contact_fields', :f => contact_form %>
</div>
<div class="modal-footer">
<%= contact_form.submit :class => "btn btn-primary",
:"data-loading-text"=> ('simple_form.creating') %>
<%= t('simple_form.buttons.or') %>
<a data-dismiss="modal" aria-hidden="true">
<%= t('simple_form.buttons.cancel') %>
</a>
</div>
<% end %>
</div>
app/controllers/contacts_controller.rb (有意注释掉了format.json
行,因为我正尝试使用JavaScript将整个模式发送回去)
app/controllers/contacts_controller.rb (intentionally commented out the format.json
line since I'm trying to send the whole modal back using JavaScript):
def create
@contact = Contact.new(params[:contact])
<...some additional processing...>
respond_to do |format|
if @contact.save
format.html { flash[:success] = "Contact added."
redirect_to @contact }
format.json { render json: @contact, status: :created, location: @contact}
else
format.html { render action: "new" }
#format.json { render json: @contact.errors, status: :unprocessable_entity }
format.js { render 'new_modal_error' }
end
app/views/contacts/new_modal_error.js.erb
var modal = "<%= escape_javascript(render :partial => 'contacts/new_modal', :locals => { :contact => @contact.errors }) %>";
$("#new-contact-modal").html($(modal));
app/assets/javascripts/contacts.js 一些JQuery可以重置表单并在成功时关闭模式.
app/assets/javascripts/contacts.js Some JQuery to reset the form and close the modal on success.
$(function($) {
$("#new_contact")
.bind("ajax:success", function(event, data, status, xhr) {
// http://simple.procoding.net/2008/11/22/how-to-reset-form-with-jquery :
$(this).each(function(){
this.reset();
});
$("#new-contact-modal").modal("hide");
})
});
好消息是,当表单没有错误时,此方法有效:添加了联系人,并且隐藏了模式.但是,如果存在 验证错误,我会收到消息"JSON.parse:意外字符".这来自jquery.js,第515行,这是此代码段中的return
语句:
The good news is, this works when the form has no errors: the contact is added and the modal is hidden. However if there are validation errors, I get the message "JSON.parse: unexpected character". This comes from jquery.js, line 515, which is the return
statement in this snippet:
// Attempt to parse using the native JSON parser first
if ( window.JSON && window.JSON.parse ) {
return window.JSON.parse( data );
}
如果我检查data
,我会发现这是我的new_modal_error.js
文件的内容,由于格式错误而完全展开,并针对JavaScript进行了转义.但这不是JSON.
If I inspect data
, I see that is is the content of my new_modal_error.js
file, fully expanded with the form errors, and escaped for JavaScript. But it's not JSON.
我想念什么?如何使页面将new_modal_error.js
作为JavaScript文件而不是JSON变量进行处理?还是有一种更简单的方法来完全解决这个问题?
What am I missing? How do I get the page to process new_modal_error.js
as a JavaScript file, not a JSON variable? Or is there an easier way to handle this altogether?
推荐答案
此处的主要问题是使用data-type => :json
调用表单.这意味着它将期望一个JSON响应,但是我希望它传递回JavaScript.解决方案是设置data-type => :script
(或将其保留,然后让Rails推断JavaScript):
The main issue here was calling the form with data-type => :json
. That means it will expect a JSON response, but I want it to pass back JavaScript. The solution is to set data-type => :script
(or just leave it off and let Rails infer JavaScript):
:html => {:class => "form-horizontal",
"data-type" => :script }) do |contact_form| %>
感谢本文解释了各种数据类型,并阐明了数据类型是指响应,而不是数据提交:
Thanks to this article for explaining the various data-types, and clarifying that data-type refers to the response, not the submission of data:
Rails 3 Remote链接和表单第2部分:数据类型(使用jQuery)
"jQuery的.ajax()
方法提供了一个名为dataType
的可选参数,用于指定所需的响应数据类型."
"jQuery’s .ajax()
method provides an optional parameter called dataType
to specify the desired data-type of the response."
我认为@wanghq指向的另一个问题是JQuery的.html()
方法更新了对象的 innerHTML .我最终创建了一个仅包含表单的部分,在<div id="new-contact-form-wrapper">
包装器内调用该部分,然后将 wrapper 定位为替换表单:
Another issue that I think @wanghq was pointing to is that JQuery's .html()
method updates the innerHTML of an object. I wound up creating a partial containing only the form, calling the partial inside a <div id="new-contact-form-wrapper">
wrapper, then targeting the wrapper to replace the form:
var myForm = "<%= escape_javascript(render :partial => 'contacts/new_modal_form', :locals => { :contact => @contact.errors }) %>";
$("#new-contact-form-wrapper").html(myForm);
我仍在努力传递变量,成功清除表单等.由于我正在使用控制器中的部分控件,因此我可能会继续进行所有的JQuery(无论成功还是失败)在那里,因此我不需要 app/assets/javascripts/contacts.js .
I am still working on getting variables passed, the form cleared on success, etc. Since I'm using a partial from the controller, I'll probably just go ahead and put all the JQuery (for both success and failure) in there so I won't need app/assets/javascripts/contacts.js.
这篇关于在Bootstrap Ajax模态中使用simple_form显示内联错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!