5

私はここここで同様のStackOverflowの質問を見つけましたが、それでもこれを機能させることはできません。

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これがブートストラップモーダルです。これは、非モーダルバージョンで使用されているのと同じパーシャルを呼び出します。app / views / contacts / _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>

app / controllers / contacts_controller.rbformat.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

app / views / contacts / 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:予期しない文字」というメッセージが表示されます。これは、returnこのスニペットのステートメントであるjquery.jsの515行目からのものです。

// 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ページをJSON変数ではなくJavaScriptファイルとして処理するにはどうすればよいですか?または、これを完全に処理する簡単な方法はありますか?

4

2 に答える 2

2

ここでの主な問題は、でフォームを呼び出すことでしたdata-type => :json。つまり、JSON応答が必要ですが、JavaScriptを返したいのです。解決策は、次のように設定することですdata-type => :script(または、そのままにして、RailsにJavaScriptを推測させます)。

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

さまざまなデータ型を説明し、データ型がデータの送信ではなく応答を参照していることを明確にしてくれたこの記事に感謝します。

Rails 3リモートリンクとフォームパート2:データ型(jQueryを使用)

「jQueryのメソッドは、応答の目的のデータ型を指定するために.ajax()呼び出されるオプションのパラメーターを提供します。」dataType

@wanghqが指摘していたもう1つの問題は、JQueryのメソッドがオブジェクトのinnerHTML.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 / asset / javascripts/contacts.jsは必要ありません。

于 2012-11-17T04:46:30.337 に答える
0

フォームをリセットする必要がある理由がわかりません。必要ないと思います。

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

修正する必要があることの1つは、new_model_error.js.erbの行の下にあります。そうしないと、 id="new-contact-modal"でdivが重複することになります。

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

それでも問題が解決しない場合はお知らせください。

于 2012-11-16T06:38:58.850 に答える