É possível chamar o Javascript do evento onsubmit programaticamente em um formulário?
-
09-06-2019 - |
Pergunta
Em Ruby on Rails, eu estou tentando atualizar o innerHTML
de uma tag div usando o form_remote_tag
auxiliar.Esta actualização acontece sempre que associadas a uma marca de seleção recebe um evento onchange.O problema é, <select onchange="this.form.submit();">
;não funciona.Nem document.forms[0].submit()
.A única maneira de obter o onsubmit o código gerado no form_remote_tag para executar é criar um oculto botão de submeter e invocar o método de clique no botão de marca de seleção.Aqui está um trabalho ERb exemplo parcial.
<% 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 %>
O que eu quero fazer é algo parecido com isso, mas ele não 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 %>
Assim, existe alguma maneira de remover o invisível botão enviar para este caso de uso?
Parece haver alguma confusão.Então, deixe-me explicar.O problema básico é que submit()
não chamar o onsubmit()
código processado no formulário.
O real formulário HTML que o Rails processa a partir desta ERb parecido com este:
<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>
Eu quero machado invisível botão enviar, mas o uso de uma forma reta.enviar parece não funcionar.Então, eu preciso de alguma forma para chamar o formulário do evento onsubmit código.
Atualização:Orion Edwards solução funcionaria se não houvesse uma return(false);
gerado pelo Rails.Eu não tenho certeza o que é pior ainda, o envio de um fantasma, clique em para um invisível botão de envio ou de chamada eval no getAttribute('onsubmit')
chamada depois de remover o retorno de chamada com um javascript de seqüência de caracteres de substituição!
Solução
Se você realmente não deseja submeter o formulário, mas apenas invocar qualquer código passou a ser no onsubmit, você poderia fazer isso:(não testado)
var code = document.getElementById('formId').getAttribute('onsubmit');
eval(code);
Outras dicas
Percebo que essa pergunta é meio velho, mas que diabos você está fazendo eval para?
document.getElementById('formId').onsubmit();
document.getElementById('formId').submit();
ou
document.formName.onsubmit();
document.formName.submit();
Quando o DOM de um documento é carregado, os eventos não são seqüências de caracteres mais, eles são funções.
alert(typeof document.formName.onsubmit); // function
Portanto, não há motivo para converter uma função para uma seqüência de caracteres para que você possa eval-lo.
dê a sua forma de uma id
.
em seguida,
document.getElementById('formid').submit();
Se você estiver carregando um Javascript em um div
via innerHTML
, não vai funcionar...atenciosamente.
Se você tiver que usar Ferroviário construído em Javascript geração, gostaria de usar Orion solução, mas com uma pequena alteração para compensar o código de retorno.
eval ('(function(){' + code + '})()');
No entanto, na minha opinião, você gostaria de ter um tempo mais fácil a longo prazo, separar o código Javascript em um arquivo externo ou separado exigível funções.
Não.
Você tem uma solução.
Parar, passe para o próximo ponto de função.
Eu sei, ele não é bonito, mas não há maiores problemas.
Não tenho certeza se você tem uma resposta ainda, ou não, mas no onclick
a função de selecionar, chamada de onsubmit
em vez de submit
.
Na teoria, algo como eval ('function(){' + code + '}()');
poderia trabalhar (que, sintaxe falha embora).Mesmo que fez o trabalho, ainda seria uma espécie de gueto para ser chamada de uma função eval, através de um select onchange
.Outra solução seria, de alguma forma, obter os Trilhos para injetar o onsubmit
código para o onchange
campo de selecionar tag, mas eu não tenho certeza se há uma maneira de fazer isso.ActionView tem link_to_remote, mas não é óbvio auxiliar para gerar o mesmo código no onchange
de campo.