JavaScript の onsubmit イベントをフォーム上でプログラム的に呼び出すことは可能ですか?
-
09-06-2019 - |
質問
Ruby on Rails で、 innerHTML
を使用した div タグの form_remote_tag
ヘルパー。この更新は、関連付けられた選択タグが onchange イベントを受信するたびに行われます。問題は、 <select onchange="this.form.submit();">
;機能しません。また、 document.forms[0].submit()
. 。form_remote_tag で生成された onsubmit コードを実行する唯一の方法は、非表示の送信ボタンを作成し、select タグからボタンの click メソッドを呼び出すことです。これは実際に動作する 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()
フォームにレンダリングされたコード。
Rails がこの ERb からレンダリングする実際の HTML フォームは次のようになります。
<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 によって生成されます。ただし、非表示の送信ボタンにファントム クリックを送信するのと、 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 生成を使用する必要がある場合は、戻りコードを補うために 1 つの小さな変更を加えて Orion のソリューションを使用します。
eval ('(function(){' + code + '})()');
ただし、私の意見では、JavaScript コードを外部ファイルまたは個別の呼び出し可能な関数に分離する方が、長期的には楽になると思います。
やめてください。
解決策はあります。
停止して、次の機能ポイントに進みます。
それはあまり良くないことはわかっていますが、さらに大きな問題があります。
まだ答えがあるかどうかはわかりませんが、 onclick
select、callの関数 onsubmit
の代わりに submit
.
理論的には、次のようなもの eval ('function(){' + code + '}()');
機能する可能性があります (ただし、その構文は失敗します)。たとえそれが機能したとしても、select を通じて eval を呼び出すのは一種のゲットーです。 onchange
. 。別の解決策は、何らかの方法で Rails に onsubmit
コードを onchange
選択タグのフィールドですが、それを行う方法があるかどうかはわかりません。ActionView には link_to_remote がありますが、同じコードを生成する明確なヘルパーはありません。 onchange
分野。