ASP.NET MVC で二重サブミットを防止したい

フォームなんかでボタンをうっかりダブルクリックしちゃって二重に投稿されてしまうのを防ぎたい。 クリックしたらボタンを無効にできればなお良し。

単純に JavaScript でボタンクリックされたら無効にするイベントハンドラ書けばいいと思ってたら、クライアントバリデーションに失敗したときボタンが押せなくなって困った。

なので今のところ

$(function () {
    $("form").on("submit", function (e) {
        var $form = $(this);
        // クライアントバリデーションに成功したら submit を無効にする
        if ($form.valid()) {
            $(this).find("[data-disable-with]").each(function () {
                var $button = $(this);
                var text = $button.attr("data-disable-with");
                $button.val(text);
                $button.prop("disabled", true);
            });
        }
    });
});

な感じでクライアントバリデーションに成功したらボタンを無効にするようにしている。Rails をマネして、data-disable-with 属性でボタンを無効にしたとき、ボタンのタイトルも変更できるようにもしてみた。

ビューでは

<input type="submit" value="ログイン" class="btn btn-lg btn-primary btn-block" data-disable-with="ログイン中..." />

という風に使っている。