作成日
2009-05-13
変更日
2009-09-03

jQuery Validation Pluginメモ

乱暴なメモです。

開発環境

プリントデバッグ

Firefox
Firebugを導入する。
console.log()でコンソールに出力可能。オブジェクトを渡しても中身を表示して呉れる。かなり便利。
Firefox 3とFirebugで始めるJavaScript開発:第2回 Firebugによるデバッグの基本,Console APIとその活用|gihyo.jp … 技術評論社
Safari
window.console.log()でコンソールに出力可能。オブジェクトは展開されない。
Safari Developer FAQ
Safari 3は環境設定から開発メニューを表示させる事が出来るので、ターミナルで設定を変更する必要は無い。
Webアプリ開発環境としてのSafariを知ってますか? - @IT
Opera
opera.postError()という関数があるらしい。
How to debug JavaScript problems with Opera - Opera Developer Community
Dragonflyでconsole.log()が導入されるかどうかは未定(原稿執筆時)。
Internet Explorer、その他
【ハウツー】あのFirebugがIEでも使えるようになる!? 簡易版Firebug「Firebug Lite」 (4) Scriptに対する動作を確認する | エンタープライズ | マイコミジャーナル

バリデーションの適用

あるformに対して、

$(function() {
  $('#buy').validate();
});

とする事により、バリデーションが働く。$( ... );$(document).ready( ... );のショートカット。DOMが構築出来た段階で実行される(もっとも、blurやsubmitなどに反応してチェックが行われるので、直ちに実行されるわけではない)。

何も設定しなければ、入力欄を変更したり項目を移動したりする際にチェックが行われる。ページの読み込み時にもチェックを行わせたい場合は、

$(function() {
  $('#buy').validate({
  // バリデーションの設定色々
}).form();
});

とする。form()はValidatorのメソッドで、フォームを検証してチェックが通ったらtrueを返し、それ以外はfalseを返す。

Submitが押された場合、問答無用でバリデーションが実行されるため、ページ遷移型――例えばウィザード形式で「戻る」/「進む」のボタンがあるような――サイトでは、入力が不完全だと戻れなくなる虞がある。「戻る」ボタンや「キャンセル」ボタンなどが押された際にチェックを省略するには、class="cancel"とする。

debug:trueにしているとsubmitされないので注意(エラーをコンソールから確認出来る様にする為の仕様)。submitHandlerで無理矢理submitさせる事も出来るが、本物のボタンを押した場合と挙動が異なる場合がある。例えば、<input type="image" name="Test" value="submit" src=...(中略)... >を押すと、

といった値が送信される可能性があるが、submitHandlerで単純にform.submit();などとした場合には、たとえ上記のボタンを押してもこれらの値は送信されない(当たり前といえば当たり前の話ですが)。

prototype.jsと異なり、#を含めてid指定してやらねばならない点に注意する。他にも$F()が存在しない(代わりに使えそうなのは$().val()とか$().is(':checked')あたり?)などの相違点があるので、prototype.jsからの移行者は注意されたい。

ルールの書き方

rules: {
  name属性1: "ルール",
  name属性2: {
    ルール1: パラメータ,
    ルール2: パラメータ
  }
}

などといった形式で書く。ルールは複数設定可能。なお、name属性中に[]などが入っている場合は、クオーテーションで括る必要がある。

既にclass属性で指定してあるものは敢えて指定しなくても良い。但し、min、max、minlength、maxlengthなど、class属性だけで指定し切れないものについては、rulesの中で書く必要がある。

エラーメッセージの書き方

単にデフォルトの検証メソッドを使う限りにおいては必ずしも書く必要は無い。

上記サイトでメッセージの日本語版が公開されているので、これを利用することでメッセージを日本語にする事が出来る。

massages: {
  name属性1: "メッセージ",
  name属性2: {
    ルール1: "メッセージ1",
    ルール2: "メッセージ2"
  }
}

などといった形式でメッセージを指定する。ルールが複数あって、それぞれに違うメッセージが必要な場合は、ルールの数だけ書く必要がある。複数のルールに対して同じメッセージを出力する場合は、検証メソッドを省略してname属性2: "メッセージ"の様に書く。

グループの書き方

例えば、3つに分かれた電話番号の入力欄を検証させる際、3つもエラーメッセージが出るのは煩わしい。その様な時にgroupsを使って複数の入力欄をグループ化すると、一つのメッセージだけが出る様になる。name属性をスペースで区切って並べる。

groups: {
  tel: "tel_0 tel_1 tel_2"
}

後述のerrorPlacementでエラーの表示位置を変更するのを忘れずに。

検証メソッドの追加

validator.addMethodを使うと、勝手に検証メソッドを追加する事が出来る。例は以下。

仮名
jQuery.validator.addMethod("kana", function(value, element) {
return this.optional(element) || /^([ァ-ヶー|ぁ-ん]+)$/.test(value);
}, "カタカナまたはひらがなで入力してください。");
全角を含む数字
jQuery.validator.addMethod("numeric", function(value, element) {
return this.optional(element) || /^([0-9|0-9]+)$/.test(value);
}, "数字で入力してください。");

複数のページで使い回す場合は、これらを適当なファイルに記述しておいて、ページ毎のJavaScriptと分けると良いかも。

複雑な検証

特定条件下の場合のみ検証させる

requiredはパラメータとしてdependency-expressionやdependency-callbackを取る事が出来る。

dependency-expressionの例: あるID(例えば#male)を持つラジオボタンやチェックボックスが選択された場合だけ必須項目とする
rules: {
  "abc": {
    required: '#male:checked'
  }
}
dependency-expressionの例: あるID(例えば#male)を持つラジオボタンやチェックボックスが選択されていない場合だけ必須項目とする
rules: {
  "abc": {
    required: '#male:!checked'
  }
}
dependency-callbackの例: あるテキストフィールド(例えば#day)が特定の値(例えば20か30)を持つ時だけ必須項目とする
rules: {
  "abc": {
    required: function() { return ($('#day').val() ==  '20' || $('#day').val() == '30'); }
  }
}

この他のメソッドも

rules: {
  "email": {
    'email': {
      depends: '#want_newsletter:checked'
    }
  },
  "email_confirm": {
    equalTo: {
      param: '#email',
      depends: '#want_newsletter:checked'
      }
    }
  }
}

といった様にdependsを付ける事でdependency-expressionと同等の事が出来る。らしい。depends: function() { ... }も使えるのでdependency-callbackも可能(戻り値がtrueならば検証される)。らしい。詳細未確認。

エラー表示のカスタマイズ

showErrorsを指定する事で、エラーの表示方法を変更可能。

デフォルトでは、エラーはinputの項目の逆順に表示されて行くので、エラーをリスト表示させた時などに分かり辛い。これを修正するには、

showErrors: function(errorMap, errorList) {
  for ( var i = this.errorList.length -1; this.errorList[i]; i-- ) {
    var error = this.errorList[i];
    this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass );
    this.showLabel( error.element, error.message );
  }
  if( this.errorList.length ) {
    this.toShow = this.toShow.add( this.containers );
  }
  if (this.settings.success) {
    for ( var i = 0; this.successList[i]; i++ ) {
      this.showLabel( this.successList[i] );
    }
  }
  if (this.settings.unhighlight) {
    for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {
      this.settings.unhighlight.call( this, elements[i], this.settings.errorClass );
    }
  }
  this.toHide = this.toHide.not( this.toShow );
  this.hideErrors();
  this.addWrapper( this.toShow ).show();
}

for ( var i = this.errorList.length -1; this.errorList[i]; i-- )とすることで、エラーリストを最後から順番に取り出している。defaultShowErrors()の先頭のfor文を逆順にしただけ。他の部分に若しかしたら影響があるかも。

エラーの出現位置は、デフォルトでは要素の直後。これはerrorPlacementで指定出来る。

errorPlacement: function(error, element) {
  switch(element.attr('name')) {
    case "family_name":
    case "given_name":
      error.insertAfter($('#username'));
      break;
    case "apple":
    case "banana":
    case "orange":
      error.insertAfter($('#favorite_fruit'));
      break;
    default:
      error.insertAfter(element);
  }
}

トラブルシューティング

IEだけえらー

Validation Pluginとは直接関係ない話ですが。

IEだとエラーが出てうまく行かない場合、何行目がエラーになったか表示される筈なので、その行に余計な,が付いていないかチェックする。具体的には、

rules: {
  "username": {
    minlength: 3,
    maxlength: 8,
  },
}

などという書き方をするとエラーになる。余分な,を削除するとちゃんと動いて呉れます。

IEだけえらー(2)

validationが有効になっていてIMEがオンの時にテキストフィールドへ入力しようとすると、最初の一文字を入力した後、それ以上入力出来なくなってしまうというトラブルがあった。何故かIETesterでは再現せず。

例えば、仮名限定の制限が掛かっているテキストフィールドに「やまだ」と入れようとすると、Yを入力した時点でエラーメッセージが表示され(まだ平仮名になっていないのでここまでは正常)、focusが外れてしまい、入力出来なくなってしまう。更に、この状態でBackSpaceを押すと前のページに戻ってしまう(focusがテキストフィールドから外れているため、「戻る」のショートカットになってしまった)。

あれこれ調べてみたのだが、onkeyupが悪さをしているらしいという事が判明。validateメソッドにonkeyup:falseを設定してやるとfocusが外れなくなった。

エラーが出たIE6にはGoogleツールバーだの何だのがインストールされていたので、推測の域を出ないが、onkeyupイベントを拾う他のツールと競合してfocusがおかしくなってしまったのではないかと思われる。IETesterで再現しなかったのは、IETesterにはツールバーをインストールしていないからなのではないか。

このonkeyupという設定、デフォルトはonkeyup:trueで、キーが離されたタイミングで検証が行われるのだが、その度にチェックが行われてエラーメッセージが出たり消えたりするので、閲覧者にとっては気分の良いものではないかも知れない。

IEだけ表示が変

pluginが出力するエラーメッセージがIE6なんかだと変な位置に出現する事が有るのだが、何うしようもないみたいなので放置。