¿Es posible llamar al evento de envío de Javascript mediante programación en un formulario?

StackOverflow https://stackoverflow.com/questions/33860

  •  09-06-2019
  •  | 
  •  

Pregunta

En Ruby on Rails, estoy intentando actualizar el innerHTML de una etiqueta div usando el form_remote_tag ayudante.Esta actualización ocurre cada vez que una etiqueta de selección asociada recibe un evento de cambio.El problema es, <select onchange="this.form.submit();">;no funciona.Ni tampoco document.forms[0].submit().La única forma de ejecutar el código de envío 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 funcional.

<% 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 forma de eliminar el botón de envío invisible para este caso de uso?

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

El formulario HTML real que Rails representa desde este ERb se ve así:

<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 eliminar el botón de envío invisible, pero usar un formulario directo. Enviar parece no funcionar.Entonces, necesito alguna forma de llamar al código de evento de envío del formulario.

Actualizar:La solución de Orion Edwards funcionaría si no hubiera una return(false); generado por Rails.Sin embargo, no estoy seguro de qué es peor: enviar un clic fantasma a un botón de envío invisible o llamar a eval en el getAttribute('onsubmit') ¡Llame después de eliminar la llamada de devolución con un reemplazo de cadena de JavaScript!

¿Fue útil?

Solución

Si en realidad no desea enviar el formulario, sino simplemente invocar cualquier código que haya en el envío, posiblemente podría hacer esto:(no probado)

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

Otros consejos

Me doy cuenta de que esta pregunta es un poco antigua, pero ¿para qué diablos estás haciendo evaluación?

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 ya no son cadenas, son funciones.

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

Por lo tanto, no hay razón para convertir una función en una cadena solo para poder evaluarla.

Dale a tu formulario un id.

entonces

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

Si está cargando Javascript en un div a través de innerHTML, no se ejecutará... solo para su información.

Si tiene que utilizar la generación de Javascript integrada de Rail, 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, a la larga le resultará más fácil separar el código Javascript en un archivo externo o separar funciones invocables.

No.

Tienes una solución.

Deténgase y pase al siguiente punto de función.

Lo sé, no es bonito, pero hay problemas mayores.

No estoy seguro si tienes una respuesta todavía o no, pero en el onclick función de seleccionar, llamar onsubmit en lugar de submit.

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top