ちょっと直しました。
viewは今までおまかせしていたのですが、エラー文をinputの隣に出力するようにしておきました。
個人的には隣というのは好きではないのですが…
上書きは簡単なので、上書いて使用してください。
あと、テストコードを追加しました。
jQueryを利用したリアルタイムヴァリデーションを制作しました。
このタイプのヴァリデーションは既存のものが多数存在しますが、
どれもやってくれすぎてしまい、見た目の調整がとても面倒だと思い、制作しました。
詳しい使用方法はGitHubを参照してください。
@ver 1.1
function varidateModel( varidateItem ){
dftCommon = {
type : 'input',
selecter : '',
required : true,
number : false,
telpost : false,
alphanumeric : false,
mail : false,
check : false,
en_one_char : false,
num_one_char : false,
credit : false,
kana : false,
alphaupper : false,
};
dftOptions = {
required : '',
maxlength : '',
minlength : 0,
};
this.Common = $.extend( dftCommon , varidateItem.common );
this.Options = $.extend( dftOptions , varidateItem.options );
dftMessages = {
// type はここから個別のものに変わってます 開始。
select : '選択必須項目です。',
radio : '選択必須項目です。',
// type はここから個別のものに変わってます 終了。
required : '必須項目です。',
maxlength : this.Options.maxlength + '文字以下にしてください',
minlength : this.Options.minlength + '文字以上入力してください',
number : '半角数字で入力してください',
telpost : '半角数字で入力してください',
mail : 'メールアドレスの形式で入力してください',
alphanumeric : '全て半角英数字で入力してください',
check : '入力された値が一致しません',
en_one_char : '英字を1文字以上含めてください',
num_one_char : '数字を1文字以上含めてください',
credit : '不正なカード番号です',
kana : '全角カタカナで入力してください',
alphaupper : '全て大文字アルファベットで入力してください',
};
this.Messages = $.extend( dftMessages , varidateItem.messages );
}
// disabledだった場合
varidateModel.prototype.disabled_check = function() {
if ( $(this.Common.selecter).is(':disabled') === true ) return 'disabled';
return true;
};
// セレクトボックスか
varidateModel.prototype.select = function( value ){
if( !value || value === "" ) return this.Messages.select;
return true;
};
// ラジオボタンか
varidateModel.prototype.radio = function( value ){
if( !value || value === "" ) return this.Messages.select;
return true;
};
// 必須項目か
varidateModel.prototype.required = function( value ){
if( value && value !== this.Options.required ) return true;
return this.Messages.required;
};
// カタカナのみか。
varidateModel.prototype.kana = function( value ){
if( value && value.match(/^[ァ-ン]+$/) ) return true;
return this.Messages.kana;
};
// 数字のみか。
varidateModel.prototype.number = function( value ){
if( value && value.match(/^\d+$/) ) return true;
return this.Messages.number;
};
// 電話番号と郵便番号の時に使う。-(ハイフン)が記入されていたら削除するよ。
// テストでは、ハイフンが消えているかどうかは確認できないよ。
varidateModel.prototype.telpost = function( value ){
if( value && value.match(/^\d+$/) ) return true;
return this.Messages.telpost;
};
// 最大記入文字数
varidateModel.prototype.maxlength = function( value ){
if( value && this.Options.maxlength >= value.length ) return true;
return this.Messages.maxlength;
};
// 最小記入文字数
varidateModel.prototype.minlength = function( value ){
if( value && this.Options.minlength <= value.length ) return true;
return this.Messages.minlength;
};
// メールアドレスとして正しいか。
varidateModel.prototype.mail = function( value ){
if( value && value.match(/^[A-Za-z0-9]+[\w\.\+-]+@[\w\.-]+\.\w{2,}$/) ) return true;
return this.Messages.mail;
};
// 英数字のみか。
varidateModel.prototype.alphanumeric = function( value ){
if( value && value.match(/^[a-zA-Z0-9]+$/) ) return true;
return this.Messages.alphanumeric;
};
// 大文字の英字のみか。
varidateModel.prototype.alphaupper = function( value ){
if( value && value.match(/^[A-Z]+$/) ) return true;
return this.Messages.alphaupper;
};
// 英字が1文字以上記入されているか。
varidateModel.prototype.en_one_char = function( value ){
var strs = value.split('');
for( var key in strs ){
if( value && strs[key].match(/^[a-zA-Z]+$/) ){
return true;
}
}
return this.Messages.en_one_char;
};
// 数字が1文字以上記入されているか。
varidateModel.prototype.num_one_char = function( value ){
if( !value ) return this.Messages.num_one_char;
var strs = value.split('');
for( var key in strs ){
if( value && strs[key].match(/^[0-9]+$/) ){
return true;
}
}
return this.Messages.num_one_char;
};
// 設定したinputの内容と一致するかどうか。
varidateModel.prototype.check = function( value ){
if( $(this.Common.check).val() === value ) return true;
return this.Messages.check;
};
// クレジットカードの番号確認
varidateModel.prototype.credit = function( value ){
if( value && value.match(/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13}|(?:2131|1800|35[0-9]{3})[0-9]{11})$/) ){
return true;
}
return this.Messages.credit;
};
varidateModel.prototype.event = function (data){
var events = {};
var value = $(data).val();
if( this.Common.telpost === true ) {
value = value.replace(/-/g,'');
$(this.Common.selecter).val( value );
}
events.disabled = this.disabled_check();
if( this.Common.type === 'select' ) events.select = this.select( $(data).find('option:selected').val() );
if( this.Common.type === 'radio' ) events.radio = this.radio( $(data).find('input:checked').val() );
if( this.Common.required && this.Common.type === 'input' ) events.required = this.required( value );
if( this.Common.kana ) events.kana = this.kana( value );
if( this.Common.number ) events.number = this.number( value );
if( this.Common.telpost ) events.telpost = this.telpost( value );
if( this.Common.mail ) events.mail = this.mail( value );
if( this.Common.alphanumeric ) events.alphanumeric = this.alphanumeric( value );
if( this.Options.maxlength !== '' ) events.maxlength = this.maxlength( value );
if( this.Options.minlength !== 0 ) events.minlength = this.minlength( value );
if( this.Common.check ) events.check = this.check( value );
if( this.Common.en_one_char ) events.en_one_char = this.en_one_char(value);
if( this.Common.num_one_char ) events.num_one_char = this.num_one_char(value);
if( this.Common.credit ) events.credit = this.credit(value);
if( this.Common.alphaupper ) events.alphaupper = this.alphaupper(value);
return events;
};
function varidation( options ){
var self = this;
this.Options = options;
this.Models = [];
this.fixedSize = this.Options.fixedSize ? this.Options.fixedSize : 0;
this.SubmitBefore = this.Options.SubmitBefore ? this.Options.SubmitBefore : function(){ return true; };
// インスタンスを生成し、配列に格納
for( var key in options.varidateItem ){
self.Models.push( new varidateModel( options.varidateItem[key] ) );
}
this.controller( );
}
varidation.prototype.initialize = function ( events ) {
var errorList = [];
for( var key in events ){
if( events[key] === 'disabled' ) return false; // disabledだったら見る必要ないからやめさせます。
if( events[key] !== true ) errorList.push( events[key] );
}
return $.unique(errorList);
};
varidation.prototype.controller = function(){
var self = this;
// サブミットボタンが押された際の処理
$( self.Options.submitBtn ).click(function(){
var errorItems = [];
for( var key in self.Models ){
if( !event(self.Models[key]) ){
errorItems.push( self.Models[key].Common.selecter );
}
}
if( errorItems.length > 0 ){
$("html,body").animate({ scrollTop: $( errorItems[0] ).offset().top - self.Options.fixedSize });
return false;
}
self.SubmitBefore();
});
for( var key in self.Models ){
switch( self.Models[key].Common.type ){
case 'select':
chengeEvent( key );
break;
default :
blurEvent( key );
break;
}
}
function chengeEvent( key ){
$( self.Models[key].Common.selecter ).change(function(){
event( self.Models[key] );
});
}
function blurEvent( key ){
$( self.Models[key].Common.selecter ).blur(function(){
event( self.Models[key] );
});
}
function event(Model){
return self.view(
Model.Common.selecter,
self.initialize(
Model.event( Model.Common.selecter )
)
);
}
};
varidation.prototype.view = function( id , errorList ){
var $id = $(id);
$id.siblings('.error_message').remove();
$id.after('<div class="error_message"></div>');
if( errorList.length > 0 ){
$id.addClass('error');
$.each( errorList , function( index , item){
$( id ).siblings('.error_message').append( "<div>※" + item + "</div>" );
});
return false;
}else{
$id.removeClass('error');
$id.siblings('.error_message').html('');
return true;
}
};