2012-11-16 53 views
5

我发现了类似的StackOverflow问题herehere,但仍无法使其工作。使用simple_form在Bootstrap Ajax模式中显示内联错误

我使用Rails 3.2.8,SimpleForm 2.0.4和Twitter Bootstrap 2.1.1(通过bootstrap-sass gem 2.1.1.0)。

用户应该能够从模态弹出窗口添加联系人。如果存在验证错误,则应该以内联方式显示,就好像用户使用表单的非模式版本(字段周围为红色边框,字段旁边为错误消息)。

我加载模态是这样的:

<a data-toggle="modal" data-target="#new-contact-modal">Go modal!</a> 

这里是自举模式,它调用相同contacts/contact_fields部分在非模态版本中使用。 应用程序/视图/联系人/ _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> 

应用程序/控制器/ contacts_controller.rb(故意注释掉format.json行,因为我想整个模式发送回使用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 

应用/视图/联系人/ 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重置表单并关闭成功的模式。

$(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:unexpected character”。这个来自的jquery.js,线515,这是return声明在这个片断:

// 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。

我错过了什么?如何让页面将new_modal_error.js作为JavaScript文件处理,而不是JSON变量?还是有更简单的方法来处理这一切?

回答

2

这里的主要问题是用data-type => :json调用窗体。这意味着它会期待JSON响应,但我希望它能够传回JavaScript。解决的办法是设置data-type => :script(或刚刚离开其关闭,并让Rails的推断的JavaScript):

:html => {:class => "form-horizontal", 
      "data-type" => :script }) do |contact_form| %> 

由于本文用于说明各种数据类型,以及澄清数据型是指响应 ,未提交数据:

Rails 3 Remote Links and Forms Part 2: Data-type (with jQuery)

“ jQuery的.ajax()方法提供了一种称为dataType来指定所需的数据类型的响应的可选参数”

我认为@wanghq指出的另一个问题是JQuery的.html()方法更新了对象的一个​​对象。我结束了创建一个只包含一种形式的局部,称部分一<div id="new-contact-form-wrapper">包装袋中,然后瞄准包装替换形式:

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

0

我不明白你为什么需要重置表单。我认为这不是必要的。你需要修复

$(function($) { 
    $("#new_contact") 
    .bind("ajax:success", function(event, data, status, xhr) { 
     ... 
    }) 
}); 

一件事是低于你的new_model_error.js.erb行,否则就会有重复的div ID =“新的接触模式”

old: 
$("#new-contact-modal").html($(modal)); 
new: 
$("#new-contact-modal").html($(modal).html()); 

让我知道你是否仍然有问题。

+0

想法是在成功时重置表单,以便在用户想要打开(取消隐藏)它并添加另一个联系人时清除它。现在我想起来了,如果以前的表单有错误消息,这可能是一个问题 - 我可能需要从服务器重新加载表单。无论如何,无法使用错误消息呈现表单的问题是不同的 - 它永远不会执行我的contacts.js代码。我会再做一些。您的其他建议并发回。 –

+0

我承认我对$('#signin-modal')。html($(modal));'[gist](https://gist.github.com/4070421)有点困惑。如果'modal'是一个包含HTML的变量字符串(我们想要注入的部分),为什么它需要被称为'$(modal)'?我认为这个符号是为了让JQuery从DOM选择器创建一个包装的集合。不应该只是'$(“#new-contact-modal”)。html(模态);'?在任何情况下,我的“JSON.parse:unexpected character”错误都是在这之前发生的:它正在尝试加载'app/views/contacts/new_modal_error.js.erb'的内容。 –