web-dev-qa-db-ja.com

jQuery控えめな検証を使用するときに「submitHandler」関数を追加するにはどうすればよいですか?

ASP.NET MVC 3の新しい控えめな検証機能を使用してフォームを検証しています。

したがって、フォームの検証を開始するためにjQuery検証をセットアップするために記述したコードはありません。そのすべては、jQuery.validate.unobtrusive.jsライブラリーをロードすることによって行われます。

残念ながら、私は「本当によろしいですか?」フォームが有効であるが送信する前のメッセージボックス。 jQueryの検証では、次のように初期化するときにオプションhandleSubmitを追加します。

$("#my_form").validate({
  rules: {
    field1: "required",
    field1: {email: true },
    field2: "required"
  },
  submitHandler: function(form) {
     if(confirm('Are you sure?')) {
       form.submit();
     }
  }
});

ただし、目立たないライブラリを使用する場合は、初期化する必要はありません。

その場合に送信ハンドラを追加できる場所/方法はありますか?

THX

44
WooWaaBob

控えめなライブラリはすべてのフォームにバリデータを添付するため、submitHandlerを次のように置き換える必要があります。

$("form").data("validator").settings.submitHandler = function (form) { alert('submit'); form.submit(); };
69
petrhaus

invalidHandlerではなくsubmitHandlerを設定する方法を探しているときに、この質問を見つけました。興味深いことに、控えめな検証を使用する場合、invalidHandlerを同じ方法で設定することはできません。

無効なフォームが検出されても、関数は実行されません。

$("form").data("validator").settings.invalidHandler = function (form, validator) {
    alert('invalid!');
};

このアプローチは機能します:

$("form").bind("invalid-form.validate", function () {
  alert('invalid!');
});

jquery.validate.unobtrusive.jsスクリプトがValidateプラグインを初期化する方法と、プラグインがハンドラーを呼び出す方法が原因であると思われます。

63
DGreen

以下の調査結果は、両者の違いを理解するのに役立ちます。

submitHandler:フォームが正常に検証されたときに呼び出されます-サーバーポストバックの直前
invalidHandler:検証が失敗し、ポストバックがない場合に呼び出されます

@DGreenのソリューションは、フォームの検証が失敗し、ポップアップ検証の概要を表示するなどの必要がある場合に特別な処理を注入するための最良の方法のようです(invalidHandler

_$("form").bind("invalid-form.validate", function () {
  alert('invalid!');
});
_

@PeteHausソリューションは、正常に検証されたフォーム(submitHandler)のポストバックを防ぎたい場合に何かを行うための最良の方法です。

_$("form").data("validator").settings.submitHandler = function (form) { 
                                                     alert('submit'); form.submit(); };
_

ただし、このように_.validate_メソッドにバインドすることでオーバーライドする(またはオーバーライドしない)動作と、それぞれに異なる方法で実行する必要がある理由について少し心配しました。だから私はソースをチェックしました。この手順をもっと理解したい人は、そうすることを強くお勧めします-「アラート」ステートメントまたは「デバッガ」ステートメントを入力してください。

とにかく、_jquery.validate.unobtrusive_ハンドラーが_jquery.validate_プラグインを初期化すると、parseElement()メソッドで作成されたオプションを取得することにより、validationInfo()メソッドで初期化することがわかります。

ValidationInfo()は、次のようなオプションを返します。

_ options: {  // options structure passed to jQuery Validate's validate() method
             errorClass: "input-validation-error",
             errorElement: "span",
             errorPlacement: $.proxy(onError, form),
             invalidHandler: $.proxy(onErrors, form),
             messages: {},
             rules: {},
             success: $.proxy(onSuccess, form)
           },
_

_jquery.validate.unobtrusive_のonErrors()メソッドは、MVCの検証サマリーパネルを動的に作成します。検証概要パネルを作成していない場合(@Html.ValidationSummary()は偶然にFORM本文に含まれている必要があります)、このメソッドは完全に不活性であり、何もしないため、心配する必要はありません。

_function onErrors(event, validator) {  // 'this' is the form elementz
    var container = $(this).find("[data-valmsg-summary=true]"),
        list = container.find("ul");

    if (list && list.length && validator.errorList.length) {
        list.empty();
        container.addClass("validation-summary-errors").removeClass("validation-summary-valid");

        $.each(validator.errorList, function () {
            $("<li />").html(this.message).appendTo(list);
        });
    }
}
_

あなたが本当にしたいなら、このように_jquery.validate.unobtrusive_ハンドラーをアンバインドすることができます-しかし、私は自分自身を気にしません

_ $("form").unbind("invalid-form.validate"); // unbind default MS handler
_

なぜこれが機能するのか疑問に思っているなら

_ $("form").data("validator").settings.submitHandler = ...
_

これは機能しません

_ $("form").data("validator").settings.invalidHandler = ...
_

これは、検証が実行されるときにsubmitHandlerが_jquery.validate_内で明示的に呼び出されるためです。したがって、どの時点で設定されるかは問題ではありません。

_ validator.settings.submitHandler.call( validator, validator.currentForm );
_

しかし、invalidHandlerは、このようにinit()の間にイベントにバインドされるため、独自のコードで設定した場合、手遅れです

_if (this.settings.invalidHandler)
    $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
_

コードを少しステップ実行するだけで、多くのことを理解できる場合があります。お役に立てれば

*バンドルでの縮小が有効になっていないことを確認してください。

34
Simon_Weaver

バインドできるように、イベントハンドラーを挿入することを好みます... :)

//somewhere in your global scripts
$("form").data("validator").settings.submitHandler = function (form) {
    var ret = $(form).trigger('before-submit');
    if (ret !== false) form.submit();
};

このようにして、必要な場所にバインドできます...

//in your view script(s)
$("form").bind("before-submit", function() {
    return confirm("Are you sure?");
});
11
Tracker1

これは元の答えに基づいていましたが、うまくいきませんでした。 jQueryでは状況が変わったと思います。

いつものように、このコードを取り、大量のエラーチェックを追加します:Dフォームでの二重送信を防ぐために同様のコードを使用し、IE8 +で正常に機能します(mvc4およびjquery 1.8.x以降)。

$("#myFormId").confirmAfterValidation();

// placed outside of a $(function(){ scope
jQuery.fn.confirmAfterValidation = function () {
    // do error checking first.  should be null if no handler already
    $(this).data('validator').settings.submitHandler = confirmValidForm;
};

function confirmValidForm(form) {
    var validator = $(this);
    var f = $(form);
    if (confirm("really really submit?")) {
        // unbind so our handler doesn't get called again, and submit
        f.unbind('submit').submit();
    }
        // return value is _ignored_ by jquery.validate, so we have to set
        // the flag on the validator itself, but it should cancel the submit
        // anyway if we have a submitHandler
        validator.cancelSubmit = true;
    }
}
1
Andrew Backer