2008-08-29 6 views
6

Dans Ruby on Rails, j'essaie de mettre à jour le innerHTML d'une balise div en utilisant l'assistant form_remote_tag. Cette mise à jour a lieu chaque fois qu'une balise select associée reçoit un événement onchange. Le problème est, <select onchange="this.form.submit();">; ne fonctionne pas. Pas plus document.forms[0].submit(). La seule façon d'exécuter le code de sous-instruction généré dans le formulaire_remote_tag est de créer un bouton de soumission masqué et d'appeler la méthode de clic du bouton à partir de la balise de sélection. Voici un exemple partiel d'ERb fonctionnant.Est-il possible d'appeler l'événement onsubmit de Javascript par programmation sur un formulaire?

<% 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 %> 

Ce que je veux faire est quelque chose comme ceci, mais cela ne fonctionne pas.

<% 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 %> 

Alors, est-il possible de supprimer le bouton de soumission invisible pour ce cas d'utilisation?

Il semble y avoir une certaine confusion. Alors, laissez-moi vous expliquer. Le problème de base est que submit() n'appelle pas le code onsubmit() rendu dans le formulaire.

Le formulaire HTML réel qui Rails rend de ce ERb ressemble à ceci:

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

Je veux hache l'invisible bouton d'envoi, mais en utilisant un form.submit droit semble ne pas fonctionner. Donc, j'ai besoin d'un moyen d'appeler le code d'événement onsubmit du formulaire.

Mise à jour: la solution Orion Edwards fonctionnerait s'il n'y avait pas de return(false); généré par Rails. Je ne suis pas sûr de ce qui est pire cependant, en envoyant un clic fantôme à un bouton de soumission invisible ou en appelant eval sur l'appel getAttribute('onsubmit') après avoir supprimé l'appel de retour avec un remplacement de chaîne javascript!

Répondre

-3

Si vous ne voulez vraiment soumettre le formulaire, mais juste invoquer le code que se trouvait dans l'onsubmit, vous pourriez le faire: (non testé)

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

Cela fonctionne en théorie, mais j'utilise toujours mon code original en production juste pour éviter d'avoir à utiliser un eval. – hoyhoy

3

donnez à votre formulaire un id.

puis

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

Si vous chargez Javascript dans un div via innerHTML, il ne fonctionnera pas ... juste votre information.

2

Si vous devez utiliser rail de génération intégrée de Javascript, j'utiliserais la solution d'Orion, mais avec une petite modification pour compenser le code de retour.

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

Cependant, à mon avis, vous auriez plus de facilité à long terme, en séparant le code Javascript dans un fichier externe ou fonctions appelables séparées.

+0

Cette syntaxe est erronée, mais l'idée est solide. – hoyhoy

-1

En théorie, quelque chose comme eval ('function(){' + code + '}()'); pourrait fonctionner (cette syntaxe échoue cependant). Même si cela fonctionnait, ce serait encore une sorte de ghetto d'appeler un eval à travers un onchange sélectionné. Une autre solution serait de faire en sorte que Rails injecte le code onsubmit dans le champ onchange de la balise select, mais je ne suis pas sûr qu'il existe un moyen de le faire. ActionView a link_to_remote, mais il n'y a aucune aide évidente pour générer le même code dans le champ onchange.

0

Ne pas.

Vous avez une solution.

Arrêtez-vous, passez au point de fonction suivant.

Je sais, ce n'est pas joli, mais il y a de plus gros problèmes.

0

Vous ne savez pas si vous avez encore une réponse ou non, mais dans la fonction onclick de la sélection, appelez onsubmit au lieu de submit.

5

Je me rends compte que cette question est un peu ancienne, mais pour quoi diable faites-vous?

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

ou

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

Lorsque le DOM d'un document est chargé, les événements ne sont pas des chaînes plus, ce sont des fonctions. Il n'y a donc aucune raison de convertir une fonction en chaîne pour pouvoir l'évaluer. Il n'y a donc aucune raison de convertir une fonction en chaîne.