背景
1つのフォームタグの中に、更新ボタンや削除ボタン果てはアップロードボタンまで1つのフォームの中に入って来るデザインが来ます...。このデザイン...マジか。このデザイン受領したくない。よし、これはネタになる。
目的
1つのフォームタグの中で押下したボタンに応じて、action、method、enctypeを動的に変更させます。
aタグでPOSTする要件がなぜかあります。
PUT, DELETEなどの時は hidden タグを生成して、 _method に値を入れる。
実装
HTML
<form>
<button type="submit" class="change-action" data-action="/" data-method="GET">一覧へ</button>
<a href="javascript:void(0)" class="change-action" data-action="/update/1" data-method="PUT">更新</a>
<button type="submit" class="change-action" data-action="/images" data-method="POST" data-enctype="multipart/form-data">ファイルアップロード</button>
<button type="submit" class="change-action" data-action="/images/1" data-method="DELETE">画像削除</button>
</form>
JavaScript
"use strict";
$(function () {
/**
* ボタンのdata属性からフォーム属性を変更
*/
$(".change-action").on("click", function (event) {
// デフォルトアクションを抑止
event.preventDefault();
let form = $(this).parents("form");
// action
if ($(this).data("action")) {
form.attr("action", $(this).data("action"));
}
// method
if ($(this).data("method")) {
if ($.inArray($(this).data("method"), ["GET", "POST"]) == -1) {
// PUT, DELETE
var element = $("<input />", { type: "hidden", name: "_method", value: $(this).data("method") });
form.append(element);
form.attr("method", "POST");
} else {
// GET, POST
form.attr("method", $(this).data("method"));
}
}
// enctype
if ($(this).data("enctype")) {
form.attr("enctype", $(this).data("enctype"));
}
// debug用
console.log(form.attr("action"));
console.log(form.attr("method"));
console.log($("[name=_method]").val());
console.log(form.attr("enctype"));
// submit
form.submit();
});
});
デモ
今後の課題
1つの画面で色々詰め込み過ぎてるデザインのため、HTMLのフォームバリデーションは全て外す必要がありました。
HTMLバリデーションとの共存が今後の課題ですが...
押下されたボタンに応じてバリデーション付けたり外したりする対応はあまり現実的ではなさそうです。
サーバーサイドでバリデーションチェックされていれば、とりあえずは...。
さいごに
1日7記事書くとか...もう絶対やりません。
最近、魔性のjQuery本に感化されてjQueryの話が書きたくなりました。