Можно ли программно вызвать событие onsubmit Javascript в форме?
-
09-06-2019 - |
Вопрос
В Ruby on Rails я пытаюсь обновить innerHTML
тега div с помощью form_remote_tag
помощник.Это обновление происходит всякий раз, когда связанный тег выбора получает событие onchange.Проблема в, <select onchange="this.form.submit();">
;не работает.И не document.forms[0].submit()
.Единственный способ выполнить код onsubmit, сгенерированный в form_remote_tag, — это создать скрытую кнопку отправки и вызвать метод click для кнопки из тега select.Вот рабочий частичный пример ERb.
<% 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 %>
Я хочу сделать что-то вроде этого, но это не работает.
<% 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 %>
Итак, есть ли способ удалить невидимую кнопку отправки для этого варианта использования?
Кажется, возникла некоторая путаница.Итак, позвольте мне объяснить.Основная проблема в том, что submit()
не звонит onsubmit()
код, отображаемый в форме.
Фактическая HTML-форма, которую Rails отображает из этого ERb, выглядит следующим образом:
<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>
Я хочу убрать невидимую кнопку отправки, но использование прямой формы form.submit, похоже, не работает.Итак, мне нужен какой-то способ вызвать код события onsubmit формы.
Обновлять:Решение Orion Edwards работало бы, если бы не было return(false);
созданный Rails.Я не уверен, что хуже: отправка фантомного щелчка по невидимой кнопке отправки или вызов eval на getAttribute('onsubmit')
вызов после удаления обратного вызова с заменой строки javascript!
Решение
Если вы на самом деле не хотели отправлять форму, а просто вызывали любой код, который оказался в onsubmit, вы можете сделать это: (не проверено)
var code = document.getElementById('formId').getAttribute('onsubmit');
eval(code);
Другие советы
Я понимаю, что этот вопрос довольно старый, но какого черта вы делаете eval?
document.getElementById('formId').onsubmit();
document.getElementById('formId').submit();
или
document.formName.onsubmit();
document.formName.submit();
Когда DOM документа загружается, события больше не являются строками, а являются функциями.
alert(typeof document.formName.onsubmit); // function
Таким образом, нет смысла преобразовывать функцию в строку только для того, чтобы вы могли ее оценить.
дайте вашей форме id
.
затем
document.getElementById('formid').submit();
Если вы загружаете Javascript в div
с помощью innerHTML
, он не запустится... просто к вашему сведению.
Если вам нужно использовать встроенную в Rail генерацию JavaScript, я бы использовал решение Ориона, но с одним небольшим изменением, чтобы компенсировать код возврата.
eval ('(function(){' + code + '})()');
Однако, на мой взгляд, в конечном итоге вам будет легче, если вы отделите код Javascript от внешнего файла или отдельных вызываемых функций.
Не.
У вас есть решение.
Стоп, переходим к следующему функциональному пункту.
Я знаю, это некрасиво, но есть и более серьезные проблемы.
Не уверен, есть ли у вас ответ или нет, но в функции onclick
выбора выберите onsubmit
вместо submit
.
Теоретически, что-то вроде eval ('function(){' + code + '}()');
может работать (хотя этот синтаксис не работает). Даже если бы это сработало, все равно было бы что-то вроде гетто - вызывать eval через select onchange
. Другим решением было бы как-то заставить Rails внедрить код onsubmit
в поле <=> тега select, но я не уверен, есть ли способ сделать это. В ActionView есть link_to_remote, но нет очевидного помощника для генерации того же кода в поле <=>.