2013-03-18 253 views
2

编辑:我忘了提及我在模型级别使用验证,并且工作正常。所以验证是阻止提交模态窗体(和ajax:错误被调用),但我没有运气处理结果错误对象和正确显示错误。现在我只使用占位符文本(“FORM HAS ERRORS”)。同样,验证和显示错误对我的非模态(非Ajax)表单(我使用部分错误消息的地方)正常工作。我真的希望我可以在我的模式对话框中渲染那个部分,你会认为这很简单。Rails Modal窗体 - 无法获取验证错误以Modal显示

我把我的头发拉出来。

我有一个“添加游览”的形式,并在该表单中,您可以从数据库中选择建筑物添加到游览中(我使用jquery tokeninput来搜索和选择建筑物)。所有这一切都很好。

我添加了用户添加新建筑的功能,方法是提供一个“添加建筑物”链接,该链接显示一个模态窗体。我处理的结果和一切工作很好(建设得到保存,模态被解雇,令牌被添加等)。

除了模式形式的验证外,一切都很好。 。 。这根本不起作用。我已经尝试过client_side_validations,我已经尝试写咖啡脚本来遍历控制器返回的错误对象等。

无论如何,我已经尝试了所有我知道的尝试,所以现在我要来找你家伙寻求帮助。现在我只在coffeescript文件中有占位符错误处理代码(它只是以非常基本的方式显示“FORM HAS ERRORS”)。我拿出了以前所有尝试做这项工作的尝试,因为它变得越来越丑陋,我真的只是寻找最好的方法来做到这一点。

下面是相关的文件。

building.js.coffee

$()-> 
    $("form.new_building").on "ajax:success", (event, data, status, xhr) -> 
    $("form.new_building")[0].reset() 
    $('#new-building-modal').modal('hide') 
    fulladdress = "#{data.address} (#{data.name}, #{data.city}, #{data.zip})" 
    $('#tour_building_tokens').tokenInput("add", {id: data.id, address: fulladdress}) 

    $("form.new_building").on "ajax:error", (event, xhr, status, error) -> 
    $('#display_errors').append('<font color="red"><strong>FORM HAS ERRORS</strong></font><br><br>') 
    $('#display_errors').show() 

buildings_controller.rb

.... 

def create 
    @building = Building.new(params[:building]) 

    respond_to do |format| 
     if @building.save 
     format.html { redirect_to @building, notice: 'Building Created!' } 
     format.json { render json: @building, status: :created, location: @building } 
     else 
     format.html { render 'new' } 
     format.json { render json: @building.errors, status: :unprocessable_entity } 
     end 
    end 
end 

new.html.erb

<% provide(:title, 'Add Tour') %> 

<h1>Add Tour</h1> 

<div class="row"> 
    <div class="span6 offset3"> 
     <%= form_for(@tour) do |f| %> 

      <%= render 'fields', f: f %> 

      <%= link_to 'Add Building', '#new-building-modal', 'data-toggle' => "modal" %> 

      </br> 
      </br> 

      <%= f.submit "Add Tour", class: "btn btn-large btn-primary" %> 
     <% end %> 
    </div> 
</div> 


<div id='new-building-modal' class='modal hide fade'> 


      <div class = "modal-body"> 

       <%= form_for(Building.new, remote:true, html: {"data-type" => :json}) do |f| %> 

        <div id="display_errors" style="display:none;"> 
        </div> 

        <%= f.label :name %> 
        <%= f.text_field :name %> 

        <%= f.label :address %> 
        <%= f.text_field :address %> 

        <%= f.label :city %> 
        <%= f.text_field :city %> 

        <%= f.label :zip %> 
        <%= f.text_field :zip %> 

      </div> 

      <div class = "modal-footer"> 

        <%= f.submit "Add Building", class: "btn btn-large btn-primary" %> 
      </div> 

       <% end %> 
</div> 

哦,我也有一个共享错误消息部分即我现在不使用这种模式(因为我无法让模式“刷新”来显示错误)。在一个完美的世界中,我会使用与模态相同的部分,因为它与我的其他非模态形式很好。

这里是局部的(再次,目前没有在上面的代码中进行渲染)。

<% if object.errors.any? %> 
<div id="error_explanation"> 
    <div class="alert alert-error"> 
     The form contains <%= pluralize(object.errors.count, "error") %>. 
    </div> 
    <ul> 
     <% object.errors.full_messages.each do |msg| %> 
      <% if msg != "Password digest can't be blank" %> 
       <li>* <%= msg %></li> 
      <% end %> 
     <% end %> 
    </ul> 
</div> 

预先感谢任何帮助任何人都可以提供。我需要尽可能多的细节。我研究了堆栈溢出的相关问题,每次我认为我离得很近时,我都会空着。

回答

2

感谢muttonlamb指引我在正确的方向。我50%肯定它必须做一些解析JSON的工作,并且他说服我继续走这条道路。讽刺的是,这是帮助我得到最终答案的this SO question。这个问题的答案涉及将错误输出到控制台,这正是我所寻找的。事实证明,这不是我解析错误的错误。 。 。我正在解析错误的对象。这是最后的实现。 。 。

新的CoffeeScript(注意我是如何显示,隐藏,并清除DIV必要):

$()-> 
    $("form.new_building").on "ajax:success", (event, data, status, xhr) -> 
    $("form.new_building")[0].reset() 
    $('#new-building-modal').modal('hide') 
    fulladdress = "#{data.address} (#{data.name}, #{data.city}, #{data.zip})" 
    $('#tour_building_tokens').tokenInput("add", {id: data.id, address: fulladdress}) 
    $('#error_explanation').hide() 

    $("form.new_building").on "ajax:error", (event, xhr, status, error) -> 
    errors = jQuery.parseJSON(xhr.responseText) 
    errorcount = errors.length 
    $('#error_explanation').empty() 
    if errorcount > 1 
     $('#error_explanation').append('<div class="alert alert-error">The form contains ' + errorcount + ' errors.</div>') 
    else 
     $('#error_explanation').append('<div class="alert alert-error">The form contains 1 error</div>') 
    $('#error_explanation').append('<ul>') 
    for e in errors 
     $('#error_explanation').append('<li>' + e + '</li>') 
    $('#error_explanation').append('</ul>') 
    $('#error_explanation').show() 

新观点:

<% provide(:title, 'Add Tour') %> 

<h1>Add Tour</h1> 

<div class="row"> 
    <div class="span6 offset3"> 
     <%= form_for(@tour) do |f| %> 

      <%= render 'fields', f: f %> 

      <%= link_to 'New Building', '#new-building-modal', 'data-toggle' => "modal" %> 

      </br> 
      </br> 

      <%= f.submit "Add Tour", class: "btn btn-large btn-primary" %> 
     <% end %> 
    </div> 
</div> 


<div id='new-building-modal' class='modal hide fade'> 

      <div class = "modal-header"> 
       <div id="error_explanation" style="display:none;"> 
       </div> 
      </div> 

      <div class = "modal-body"> 

       <%= form_for(Building.new, remote:true, html: {"data-type" => :json}) do |f| %> 

        <%= f.label :name %> 
        <%= f.text_field :name %> 

        <%= f.label :address %> 
        <%= f.text_field :address %> 

        <%= f.label :city %> 
        <%= f.text_field :city %> 

        <%= f.label :zip %> 
        <%= f.text_field :zip %> 

      </div> 

      <div class = "modal-footer"> 

        <%= f.submit "Add Building", class: "btn btn-large btn-primary" %> 
      </div> 

       <% end %> 
</div> 

新的控制器:

def create 
    @building = Building.new(params[:building]) 

    respond_to do |format| 
     if @building.save 
     format.html { redirect_to @building, notice: 'Building Created!' } 
     format.json { render json: @building, status: :created, location: @building } 
     else 
     format.html { render 'new' } 
     format.json { render json: @building.errors.full_messages, status: :unprocessable_entity } 
     end 
    end 
    end 

最后,以防止添加错误时滚动的模式(我希望它自动调整大小),我添加了这个CSS:

#new-building-modal { 
    max-height: 600px; 
} 

希望所有这些细节可以防止其他人在愚蠢的模式验证错误上浪费近一周的时间。

0

该问题看起来像您的ajax请求错误部分不运行。

原因是这样的,你正在寻找的错误就像'页面未找到'或其他一些HTTP错误。

在您的控制器中,HTTP请求仍然会成功,即它仍会返回数据。

处理错误是否存在的逻辑应该位于ajax成功块中。

希望这是有道理

$()-> 
    $("form.new_building").on "ajax:success", (event, data, status, xhr) -> 
    $("form.new_building")[0].reset() 
    $('#new-building-modal').modal('hide') 
    fulladdress = "#{data.address} (#{data.name}, #{data.city}, #{data.zip})" 
    $('#tour_building_tokens').tokenInput("add", {id: data.id, address: fulladdress}) 

需要首先检查本节中的错误变量。

+0

这就是我最初的想法,但我添加了“FORM HAS ERRORS”通用错误消息,并在验证触发错误时调用它。所以,正在调用ajax错误部分。然而,我没有运气与控制器返回的错误对象(我猜会包含JSON?)。 – bcb 2013-03-18 20:12:48

+1

http://api.jquery.com/jQuery.getJSON/在实际更新基于返回的JSON的视图方面有一些很好的信息。 – muttonlamb 2013-03-19 00:15:41

+0

谢谢,这指出我在正确的方向! – bcb 2013-03-19 03:24:44