Rails模式表单 - 无法获取在模态中显示的验证错误

时间:2013-03-18 05:09:52

标签: ruby-on-rails validation modal-dialog

编辑:我忘了提到我在模型级别使用验证,并且工作正常。所以验证是阻止提交模态形式(并且ajax:错误被调用),但我没有运气处理生成的错误对象并正确显示错误。现在我只使用占位符文本(“FORM HAS ERRORS”)。再次,验证和显示错误与我的非模态(非ajax)表单(我正在使用错误消息部分)工作正常。我真的希望我可以在我的模态对话框中渲染那个部分,你会认为这很简单。

我把头发拉过来。

我有一个“添加游览”表单,在该表单中,您可以从数据库中选择要添加到游览中的建筑物(我使用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>

提前感谢任何人都可以提供的帮助。我需要尽可能多的细节。我已经研究了Stack Overflow上的相关问题,每当我认为我很接近时,我就会空洞。

2 个答案:

答案 0 :(得分: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;
}

希望所有这些细节都能阻止其他人浪费近一周时间来处理愚蠢的模态验证错误。

答案 1 :(得分: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} )

您需要在本节中检查错误变量。