2008-08-29 20 views
6

En Ruby on Rails, estoy intentando actualizar el innerHTML de una etiqueta div usando el ayudante form_remote_tag. Esta actualización ocurre siempre que una etiqueta de selección asociada recibe un evento onchange. El problema es <select onchange="this.form.submit();">; no funciona Tampoco lo hace document.forms[0].submit(). La única forma de ejecutar el código onsubmit generado en form_remote_tag es crear un botón de envío oculto e invocar el método de clic en el botón de la etiqueta de selección. Aquí hay un ejemplo parcial de ERb que funciona.¿Es posible invocar el evento onsubmit de Javascript programáticamente en un formulario?

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

Lo que quiero hacer es algo como esto, pero no funciona.

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

Entonces, ¿hay alguna manera de eliminar el botón de envío invisible para este caso de uso?

Parece haber alguna confusión. Entonces, déjame explicarte. El problema básico es que submit() no llama al código onsubmit() representado en el formulario.

El formulario HTML real que hace que los carriles de esta ERb se parece a esto:

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

Quiero hacha lo invisible botón de enviar, pero utilizando un form.submit recta parece no funcionar. Entonces, necesito alguna forma de llamar al código de evento onsubmit del formulario.

Actualización: la solución de Orion Edwards funcionaría si no hubiera un return(false); generado por Rails. No estoy seguro de que es peor, enviando un clic fantasma a un botón de envío invisible o llamando a eval en la llamada getAttribute('onsubmit') después de eliminar la devolución de llamada con un reemplazo de cadena de JavaScript.

Respuesta

-3

Si no desea realmente para enviar el formulario, pero sólo invocar cualquier código que se encontraba en el onsubmit, posiblemente podría hacer esto: (no probado)

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

Esto funciona en teoría, pero todavía uso mi código original en producción solo para evitar tener que usar una evaluación. – hoyhoy

3

den su forma un id.

continuación

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

Si va a cargar Javascript en un div través innerHTML, no va a funcionar ... lo digo.

2

Si usted tiene que utilizar Rail Generación de Javascript incorporada, usaría la solución de Orion, pero con una pequeña modificación para compensar el código de retorno.

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

Sin embargo, en mi opinión tendría un tiempo más fácil en el largo plazo separando el código Javascript en un archivo externo o se puede llamar funciones separadas.

+0

Esta sintaxis es incorrecta, pero la idea es sólida. – hoyhoy

-1

En teoría, podría funcionar algo como eval ('function(){' + code + '}()'); (aunque la sintaxis falla). Incluso si eso funcionó, todavía sería una especie de gueto llamar a una evaluación a través de un select onchange. Otra solución sería conseguir que Rails inyecte el código onsubmit en el campo onchange de la etiqueta de selección, pero no estoy seguro de si hay alguna manera de hacerlo. ActionView tiene link_to_remote, pero no hay ayuda obvia para generar el mismo código en el campo onchange.

0

Do not.

Tiene una solución.

Detener, pasar al siguiente punto de función.

Lo sé, no es bonito, pero hay problemas más grandes.

0

No estoy seguro si aún tiene una respuesta o no, pero en la función onclick de la selección, llame al onsubmit en lugar de submit.

5

Me doy cuenta de que esta pregunta es algo antigua, pero ¿para qué diablos estás evaluando?

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

o

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

Cuando se carga el DOM de un documento, los eventos no son cadenas más, se trata de funciones.

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

Así que no hay razón para convertir una función en una cadena para que pueda evaluarla.

Cuestiones relacionadas