2008-08-29 5 views
6

In Ruby on Rails versuche ich die innerHTML eines div-Tags mit dem form_remote_tag Helfer zu aktualisieren. Diese Aktualisierung findet immer dann statt, wenn ein zugehöriges select-Tag ein onchange-Ereignis empfängt. Das Problem ist <select onchange="this.form.submit();">; funktioniert nicht. Noch tut document.forms[0].submit(). Die einzige Möglichkeit, den Code oninsubmit zu erhalten, der in form_remote_tag generiert wird, besteht darin, eine verborgene Übergabeschaltfläche zu erstellen und die click-Methode auf der Schaltfläche des select-Tags aufzurufen. Hier ist ein funktionierendes ERB-Teilbeispiel.Ist es möglich, Javascript onsubmit-Ereignis programmgesteuert auf einem Formular aufzurufen?

<% form_remote_tag :url => product_path, :update => 'content', :method => 'get' do -%> 
    <% content_tag :div, :id => 'content' do -%> 
    <%= select_tag :update, options_for_select([["foo", 1], ["bar", 2]]), :onchange => "this.form.commit.click" %> 
    <%= submit_tag 'submit_button', :style => "display: none" %> 
    <% end %> 
<% end %> 

Was ich tun möchte, ist so etwas, aber es funktioniert nicht.

<% form_remote_tag :url => product_path, :update => 'content', :method => 'get' do -%> 
    <% content_tag :div, :id => 'content' do -%> 
    # the following line does not work 
    <%= select_tag :update, options_for_select([["foo", 1], ["bar", 2]]), :onchange => "this.form.onsubmit()" %> 
    <% end %> 
<% end %> 

Also gibt es eine Möglichkeit, die unsichtbare Senden-Schaltfläche für diesen Anwendungsfall zu entfernen?

Es scheint etwas Verwirrung zu geben. Also, lass mich das erklären. Das grundlegende Problem ist, dass submit() den onsubmit()-Code nicht aufruft, der in dem Formular gerendert wird.

Die eigentliche HTML-Formular, dass Rails aus dieser ERb macht sieht wie folgt aus:

<form action="/products/1" method="post" onsubmit="new Ajax.Updater('content', '/products/1', {asynchronous:true, evalScripts:true, method:'get', parameters:Form.serialize(this)}); return false;"> 
    <div style="margin:0;padding:0"> 
    <input name="authenticity_token" type="hidden" value="4eacf78eb87e9262a0b631a8a6e417e9a5957cab" /> 
    </div> 
    <div id="content"> 
    <select id="update" name="update" onchange="this.form.commit.click"> 
     <option value="1">foo</option> 
     <option value="2">bar</option> 
    </select> 
    <input name="commit" style="display: none" type="submit" value="submit_button" /> 
    </div> 
</form> 

ich die unsichtbare Submit-Button Axt wollen, scheint aber eine gerade form.submit mit zu arbeiten, um nicht. Also muss ich den Onsubmit-Ereigniscode des Formulars aufrufen.

Update: Orion Edwards Lösung würde funktionieren, wenn es keine return(false); von Rails generiert. Ich bin mir nicht sicher, was schlimmer ist, indem ich einen Phantom-Klick auf eine unsichtbare Schaltfläche zum Senden abschicke oder eval auf den Aufruf getAttribute('onsubmit') aufruft, nachdem ich den Return-Aufruf mit einem Javascript-String-Ersatz entfernt habe!

Antwort

-3

Wenn Sie eigentlich nicht wollen das Formular abzuschicken, aber nur aufrufen Code, der gerade onsubmit sein passiert ist, Sie möglicherweise könnte dies tun: (ungetestet)

var code = document.getElementById('formId').getAttribute('onsubmit'); 
eval(code); 
+0

Dies funktioniert in der Theorie, aber ich verwende immer noch meinen ursprünglichen Code in der Produktion, nur um zu vermeiden, ein Eval zu verwenden. – hoyhoy

3

geben Sie Ihrem Formular eine id.

dann

document.getElementById('formid').submit(); 

Wenn Sie Javascript in eine div über innerHTML geladen werden, wird es nicht laufen ... nur FYI.

2

Wenn Sie verwenden müssen Rail integrierte JavaScript-Generierung, würde ich Orions Lösung verwenden, aber mit einer kleinen Änderung, um den Rückkehrcode zu kompensieren.

eval ('(function(){' + code + '})()'); 

jedoch meiner Meinung nach würden Sie leichter auf lange Sicht haben durch den Javascript-Code in eine externe Datei oder getrennt aufrufbaren Funktionen abscheidet.

+0

Diese Syntax ist falsch, aber die Idee ist solide. – hoyhoy

-1

In der Theorie könnte etwas wie eval ('function(){' + code + '}()'); funktionieren (diese Syntax schlägt jedoch fehl). Selbst wenn das funktionieren würde, wäre es immer noch eine Art Ghetto, eine Bewertung durch eine ausgewählte onchange aufzurufen. Eine andere Lösung wäre, Rails irgendwie dazu zu bringen, den Code onsubmit in das Feld 10 des Select-Tags zu injizieren, aber ich bin mir nicht sicher, ob es einen Weg dafür gibt. ActionView hat link_to_remote, aber es gibt keinen offensichtlichen Helfer, der denselben Code im Feld onchange generiert.

0

Nicht.

Sie haben eine Lösung.

Stopp, weiter zum nächsten Funktionspunkt.

Ich weiß, es ist nicht schön, aber es gibt größere Probleme.

0

Nicht sicher, ob Sie bereits eine Antwort haben oder nicht, aber rufen Sie in der onclick-Funktion der Auswahl onsubmit statt submit.

5

Ich weiß, diese Frage ist irgendwie alt, aber was zum Teufel machst du Eval für?

document.getElementById('formId').onsubmit(); 
document.getElementById('formId').submit(); 

oder

document.formName.onsubmit(); 
document.formName.submit(); 

Wenn das DOM eines Dokuments geladen wird, die Ereignisse sind nicht Saiten nicht mehr, sie sind Funktionen.

alert(typeof document.formName.onsubmit); // function 

Es gibt also keinen Grund, eine Funktion in eine Zeichenkette umzuwandeln, nur um sie auszuwerten.

Verwandte Themen