1. ホーム
  2. ハイパーリンク

[解決済み】HTMLフォームのネスト制限を克服する方法は?

2022-04-19 23:09:33

質問

XHTMLがネストしたフォームタグをサポートしないことは知っていますし、このテーマに関してStack Overflowの他の回答も読みましたが、この問題に対するエレガントな解決策がまだ見つかっていません。

必要ない」「必要なシナリオが思いつかない」という意見もあります。まあ、個人的には、このようなシナリオは考えられませんが していない 必要です。

ごく簡単な例を見てみましょう。

ブログアプリを作っていて、新しい記事を作成するためのいくつかのフィールドを持つフォームと、"Save", "Delete", "Cancel" といったアクションを持つツールバーを持っているとします。

<form
 action="/post/dispatch/too_bad_the_action_url_is_in_the_form_tag_even_though_conceptually_every_submit_button_inside_it_may_need_to_post_to_a_diffent_distinct_url"
method="post">

    <input type="text" name="foo" /> <!-- several of those here -->
    <div id="toolbar">
        <input type="submit" name="save" value="Save" />
        <input type="submit" name="delete" value="Delete" />
        <a href="/home/index">Cancel</a>
    </div>
</form>

私たちの目的は、フォームを次のように書くことです。 JavaScriptを必要としない HTMLのフォームと送信ボタンだけです。

アクションの URL は Form タグで定義され、個々の送信ボタンでは定義されないので、唯一の選択肢は汎用 URL に投稿して、送信されたボタンの名前を決定するために "if...then...else" を開始することです。あまりエレガントではありませんが、JavaScriptに頼りたくないので、唯一の選択肢です。

唯一の問題は、このアクションに必要なのはpost-idのHidden入力だけなのに、"Delete"を押すと、サーバー上のすべてのフォームフィールドを送信してしまうことです。この小さな例ではそれほど大きな問題ではありませんが、私は何百ものフィールドとタブを持つフォームを、私の LOB のアプリケーションでは、(要件により)すべてを一度に送信する必要があり、いずれにしても非常に非効率的で無駄が多いように思われます。もしフォームのネストがサポートされていれば、少なくとも投稿ボタンを独自のフォームにラップして、post-idフィールドだけを表示させることができるようになると思うのですが。

と言われるかもしれませんが、quot;Delete" を submit" の代わりにリンクとして実装すればいいだけです。これは多くの点で間違っていますが、最も重要なことは、ここでの "Delete" のような副作用のあるアクションは、決して GET リクエストであってはならないということです。

そこで質問ですが、(特にフォームのネストを必要としたことがないとおっしゃる方に)皆さんはどうされていますか?私が見逃しているエレガントなソリューションがあるのでしょうか、それとも本当に"JavaScriptを必要とするか、すべてを送信するか"なのでしょうか?

解決方法は?

サーバーにすべてを送信し、どのボタンがクリックされたかをチェックするために単純なif/elseを実行します。

そして、フォームのonsubmitイベントに結びついたJavascriptコールを実装し、フォームが送信される前にチェックし、関連するデータのみをサーバーに送信します(おそらく、処理に必要なIDを隠し入力としてページにある第2のフォームを介して、またはGETリクエストとして渡された必要なデータでページの場所を更新するか、サーバーへのAjaxポスト、または...)。

この方法では、Javascriptを持たない人もフォームを問題なく使用でき、Javascriptを持っている人は必要なデータ1つだけを送信するため、サーバーの負荷は相殺されます。 どちらか一方だけをサポートすることにこだわると、選択肢が不必要に狭くなってしまいます。

また、企業のファイアウォールの内側で作業していて、誰もがJavascriptを無効にしている場合、2つのフォームを作成し、CSSで削除ボタンが最初のフォームの一部であるかのように見せかけることも可能です。