2012-11-16 6 views
5

Ich habe ähnliche StackOverflow Fragen here und here gefunden, aber immer noch nicht zum Funktionieren bringen.Anzeige Inline-Fehler mit Simple_form in einem Bootstrap Ajax modal

Ich verwende Rails 3.2.8, SimpleForm 2.0.4 und Twitter Bootstrap 2.1.1 (über das Bootstrap-Sass-Juwel 2.1.1.0).

Der Benutzer sollte einen Kontakt aus einem modalen Popup-Fenster hinzufügen können. Wenn Validierungsfehler auftreten, sollten sie inline angezeigt werden, so als ob der Benutzer eine nicht-modale Version des Formulars verwenden würde (roter Rand um das Feld, Fehlermeldung neben dem Feld).

lade ich die modale wie folgt aus:

<a data-toggle="modal" data-target="#new-contact-modal">Go modal!</a> 

Hier ist die Bootstrap modal, die die gleiche contacts/contact_fields teilweise gebrauchte in der nicht-modal-Version aufruft. app/views/Kontakte/_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.rb (absichtlich kommentiert aus der format.json Linie, da ich versuche, die ganze modal zurück zu senden mit Hilfe von 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/Kontakte/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 Einige JQuery, um das Formular zurückzusetzen und das Modal auf Erfolg zu schließen.

Die gute Nachricht ist, das funktioniert, wenn das Formular keine Fehler enthält: Der Kontakt wird hinzugefügt und das Modal ist ausgeblendet. Wenn jedoch Validierungsfehler sind, erhalte ich die Meldung "JSON.parse: unerwartetes Zeichen". Dies ergibt sich aus jquery.js, Linie 515, die die return Aussage in dieser Schnipsel ist:

// Attempt to parse using the native JSON parser first 
if (window.JSON && window.JSON.parse) { 
    return window.JSON.parse(data); 
} 

Wenn ich inspizieren data, ich sehe, dass der Inhalt meiner new_modal_error.js Datei ist, vollständig mit den Formfehler erweitert, und maskiert für JavaScript. Aber es ist nicht JSON.

Was fehlt mir? Wie bekomme ich die Seite zur Verarbeitung new_modal_error.js als eine JavaScript-Datei, keine JSON-Variable? Oder gibt es einen einfacheren Weg, damit umzugehen?

Antwort

2

Das Hauptproblem hier war das Formular mit data-type => :json aufrufen. Das bedeutet, dass es eine JSON-Antwort erwartet, aber ich möchte, dass es JavaScript zurückgibt. Die Lösung ist data-type => :script zu setzen (oder lass es einfach aus und lassen Sie Rails infer JavaScript):

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

Dank dieser Artikel zur Erläuterung der verschiedenen Datentypen, und diese Daten-Typ Klärung bezieht sich auf die Antwort nicht die Übermittlung von Daten:

Rails 3 Remote Links and Forms Part 2: Data-type (with jQuery)

„jQuery .ajax() Verfahren einen optionalen Parameter dataType zu spezifizieren den gewünschten Datentyp der Antwort genannt zur Verfügung stellt.“

Ein anderes Problem, auf das ich @wanghq zeigte, ist, dass JQuerys .html() Methode das innerHTML eines Objekts aktualisiert. Ich zog eine teilweise nur die Form enthält, zu schaffen, die teilweise in einem <div id="new-contact-form-wrapper"> Wrapper aufrufen, dann gezielt die Wrapper das Formular zu ersetzen:

var myForm = "<%= escape_javascript(render :partial => 'contacts/new_modal_form', :locals => { :contact => @contact.errors }) %>"; 
$("#new-contact-form-wrapper").html(myForm); 

ich arbeite immer noch auf immer Variablen übergeben, klarte der Form auf Erfolg usw. Da ich einen Teil vom Controller verwende, werde ich wahrscheinlich einfach alle JQuery (sowohl für den Erfolg als auch für den Fehler) in dort setzen, so dass ich app/assets/javascripts/contacts nicht benötigen werde .js.

0

Ich verstehe nicht, warum Sie das Formular zurücksetzen müssen. Ich denke, es ist nicht notwendig.

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

Eine Sache, die Sie beheben müssen, ist unter der Linie in Ihrem new_model_error.js.erb, sonst werden Sie doppelten divs mit id haben = "new-Kontakt-modal".

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

Lassen Sie mich wissen, wenn Sie noch ein Problem haben.

+0

Die Idee ist, das Formular bei Erfolg zurückzusetzen, so dass es gelöscht wird, wenn der Benutzer es öffnen (un-ausblenden) und einen weiteren Kontakt hinzufügen möchte. Nun, da ich daran denke, könnte dies ein Problem sein, wenn das vorherige Formular Fehlermeldungen hatte - ich muss das Formular möglicherweise vom Server neu laden. In jedem Fall ist das Problem, dass das Formular mit Fehlermeldungen nicht gerendert werden kann, anders - es kommt nie so weit, meinen contacts.js-Code auszuführen. Ich werde etwas mehr tun. Deinen anderen Vorschlag und poste zurück. –

+0

Ich gebe zu, ich war etwas verwirrt durch die $ ('# signin-modal') .html ($ (modal)); 'in der [gist] (https://gist.github.com/4070421). Wenn 'modal' eine variable Zeichenfolge ist, die HTML enthält (das Teil, das wir injizieren wollen), warum muss es als' $ (modal) 'bezeichnet werden? Ich dachte, dass Notation war, um JQuery zu veranlassen, einen umbrochenen Satz von einem DOM-Selektor zu erstellen. Sollte es nicht nur $ sein ("# new-contact-modal"). Html (modal); '? In jedem Fall passiert mein Fehler "JSON.parse: Unerwartetes Zeichen" vor diesem: Es ist, wenn es versucht, den Inhalt von "app/views/contacts/new_modal_error.js.erb" zu laden. –

Verwandte Themen