parsley.js 日本語最適化

JavaScriptのフォームバリデーションライブラリの [parsley.js](http://parsleyjs.org/) の日本語最適化。
不具合、詰め甘い点あるかもしれません。。。

[デモ](http://jsdo.it/ksk1015/5m6K)

```js:parsley-jap.js
// 日本語エラーメッセージ
ParsleyConfig.i18n.ja = {
    defaultMessage: "入力内容が適切ではありません",
    type: {
        email:        "正しいメールアドレスの形式を入力してください",
        url:          "正しいURLの形式を入力してください",
        number:       "数値を入力してください",
        integer:      "整数を入力してください",
        digits:       "数字を入力して下さい",
        alphanum:     "英数字を入力してください"
    },
    notblank:       "空白のままではダメよ～ダメダメ", // requiredとの使い分けがわからぬ
    required:       "入力必須項目です",
    pattern:        "無効な値です",
    min:            "%s以上の数値を入力してください",
    max:            "%s以下の数値を入力してください",
    range:          "%s以上%s以下の数値を入力してください",
    minlength:      "%s文字以上で入力してください",
    maxlength:      "%s文字以下で入力してください",
    length:         "%s文字以上%s文字以下で入力してください",
    mincheck:       "%s個をで選択して下さい",
    maxcheck:       "%s個以下で選択して下さい",
    check:          "%s個以上%s個以下で選択して下さい",
    equalto:        "同じ値を入力して下さい"
};

// ビルドインのemail validatorが日本語も許容するため上書き
// もっと上手な上書き方あるのかな。。。
ParsleyValidator.Validator.Assert.prototype.Email = function(){
    this.__class__ = 'Email';
    this.validate = function ( value ) {
        var regExp = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
        if ( 'string' !== typeof value )
            throw new ParsleyValidator.Validator.Violation( this, value, { value: ParsleyValidator.Validator.Validator.errorCode.must_be_a_string } );
        if ( !regExp.test( value ) )
            throw new ParsleyValidator.Validator.Violation( this, value );
        return true;
    };
    return this;
};

// data-parsley-hansu属性のフィールドをvalidateする前に全角を半角に自動変換する
// window.ParsleyConfig.autoHan = true; で [type=email], [type=url]を半角に自動変換する
// [type=number]は半角数字以外を入力するとvalueがとれないので対象としてない
$.listen('parsley:form:init', function(parsleyForm){
    var attr = 'data-parsley-hansu';
    var autoTargets = ['email','url'];
    $.each(parsleyForm.fields, function(){
        var parsleyField = this, isHansu = false;
        if( parsleyField.$element.is('[' + attr + ']') ){
            isHansu = true;
        }else if(window.ParsleyConfig.autoHan){
            $.each(parsleyField.constraints, function(){
                //console.log(parsleyField.constraints);
                if ( $.inArray(this.requirements, autoTargets) >= 0 ){
                    isHansu = true;
                    return false;
                }
            });
        }
        if( isHansu ){
            parsleyField.subscribe('parsley:field:validate', function(parsleyField){
                // 入力時に変換走ると入力できなくなるので
                // submit時でなくてかつfocusしてるときはbreak（submitイベントのタイムスタンを見てonSubmitを判定）
                var onSubmit = parsleyField.parent.submitEvent? (new Date()).getTime() - parsleyField.parent.submitEvent.timeStamp < 100 : false;
                if( !onSubmit && parsleyField.$element.is(':focus') ){
                    return;
                }
                var hanVal = parsleyField.$element.val().replace(/[！-～]/g, function(s) {
                    return String.fromCharCode(s.charCodeAt(0) - 0xFEE0);
                });
                parsleyField.$element.val(hanVal);
                parsleyField.value = hanVal;
            });
        }
    });
});


// エラーメッセージを日本語を使用
window.ParsleyValidator.setLocale('ja');

// email, urlフィールドの全角を半角に変換
window.ParsleyConfig.autoHan = true;
```