2013-03-18 41 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