ASP.NET MVC3 による Web アプリ開発での話。
カスタム入力検証のクライアント側実装
@shibayan の下記ブログ記事を参考に、モデルに自作のカスタム検証属性を付与し、さらにクライアント側スクリプトでもそのカスタム検証を行う実装を書いた。
ASP.NET MVC 3 で独自の検証属性を作成して、クライアントサイド検証を行う
http://d.hatena.ne.jp/shiba-yan/20110108/1294423577
ASP.NET MVC2 用にカスタム検証属性とそのクライアント側実装はなんどか書いたことがあったが、ASP.NET MVC3 用は初めて。
上記ブログ記事のお陰で、無事実装することができた...
...と言いたかったところだが、自分のはやとちりで、うまくいかずはまってしまった。
クライアント側実装が動作しない!?
ASP.NET MVC3 の独自入力検証のクライアント側実装では、下記のような JavaScript コードを記述して、カスタム検証ロジックを実装する。
// 検証ロジックの記述
jQuery.validator.addMethod("myValidate", function (value, element, param) {
// ここで検証結果: true か false かを返す
};
// "控えめJavaScript" のパース処理で認識してもらえるよう、名前で登録
jQuery.validator.unobtrusive.adapters.addBool("myValidate");
さてここで私は、上記コードを、$(function(){ ... }) 内、すなわち document ready のタイミングで実行するように書いてしまったのだ。
そうすると何がおきるか。
何も起きないのである。
せっかく書いたクライアント側のカスタム検証スクリプトが一切呼び出されないのである。
※ちなみに、サーバー側実装は申し分なく期待どおりに正常動作した。
@shibayan に多謝。
正解は...
いろいろ試行錯誤してようやくたどり着いた正解は、上記コードを、document ready のタイミングではなく、上記コードを記述した .js ファイル内に
インラインで書く
こと。
つまり、その .js ファイルがロードされたら実行されるようにしておくのだ。
というのも、ASP.NET MVC3 の "控えめ JavaScript" ベースのクライアント側検証エンジンは、document ready のタイミングで、 jQuery.validator.unobtrusive.parse() を実行するからだ。
jQuery.validator.unobtrusive.parse メソッドでは、HTML DOM を走査して、data-val-ほげほげ といった "控えめ JavaScript" 方式のためのマークアップを探しだし、適切にイベントハンドラを配線して、検証コードと紐づけていく。
すなわち、 jQuery.validator.unobtrusive.parse() の実行後にカスタム検証ロジックを登録しても、すでに手遅れ、検証のためのイベントハンドラの配線は行われないのである。
...というつまらぬところではまってしまった。
わかってしまえば、至極当然、当たり前のことなのであるが。
以上、恥ずかしい失敗ではあるが、覚え書きということで。