2

編集:私はモデルレベルで検証を使用していることを言及するのを忘れました、そしてそれはうまくいきます。そのため、検証によってモーダルフォームの送信が妨げられています(そしてajax:errorが呼び出されています)が、結果のエラーオブジェクトを処理してエラーを適切に表示することができません。今のところ、プレースホルダーテキスト(「FORMHASERRORS」)を使用しています。繰り返しますが、検証とエラーの表示は、私の非モーダル(非ajax)フォーム(エラーメッセージを部分的に使用している)で正常に機能しています。モーダルダイアログボックスでその部分をレンダリングできればと思います。これは簡単だと思います。

これで髪を抜いています。

「ツアーの追加」フォームがあり、そのフォーム内でデータベースから建物を選択してツアーに追加できます(jquery tokeninputを使用して建物を検索および選択しています)。それはすべてうまくいきます。

モーダルフォームを表示する[建物の追加]リンクを提供することで、ユーザーが新しい建物を追加できる機能を追加しました。結果を処理すると、すべてがうまく機能します(建物が保存される、モーダルが却下される、トークンが追加されるなど)。

モーダル形式での検証を除いて、すべてがうまく機能します。。。これはまったく機能しません。client_side_validationsを試したり、コントローラーから返されたエラーオブジェクトを反復処理するコーヒースクリプトを記述したりしました。

とにかく、私は私が試すことを知っているすべてを試したので、今私はあなたたちに助けを求めに来ています。今のところ、私はコーヒースクリプトファイルにプレースホルダーエラー処理コードを持っています(これは非常に基本的な方法で「FORMHASERRORS」を表示するだけです)。醜くなってきたので、これまでの試みをすべてやめました。本当にこれを行うための最良の方法を探しています。

関連するファイルは次のとおりです。

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()

building_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に関する関連する質問を調査しましたが、近くにいると思うたびに空っぽになります。

4

2 に答える 2

2

私を正しい方向に向けてくれたmuttonlambに感謝します。JSON の解析で何かをしなければならないことは 50% 確信していました。皮肉なことに、最終的な答えにたどり着くのに役立ったのは、このSOの質問でした。エラーをコンソールに出力することを含むその質問に対する答えは、私が探していたものでした。エラーを間違って解析していたほどではなかったことがわかりました。. . 間違ったオブジェクトを解析していました。これが機能する最終的な実装です。. .

新しい 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 週間近く無駄にする必要がなくなることを願っています。

于 2013-03-19T03:48:37.613 に答える
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} )

このセクションでエラー変数を確認する必要があります。

于 2013-03-18T05:49:13.770 に答える