// バリデーション
//
// validationObj = new validationClass();
// ret = validationObj.check( table.element ); # true:エラー有り false:エラー無し
// list = validationObj.getErrList(); # エラーリスト取得
// ele = validationObj.getEle( no ); # エラーエレメント取得
// text = validationObj.getMessage(); # エラーメッセージ取得
//
// ▼unloadCheckClassと連携
// validationObj = new validationClass();
// unloadCheckObj = new unloadCheckClass( validationObj );
//
// ★チェッククラスは複数設定可能
//
//
// ▼必須項目
//
//
//
//
//
//
//
// ▼全て入力必須(アラート共通)
// 姓
// 名
// ※「checkName_〇〇」は任意
//
// ▼1項目以上入力必須(アラート共通)
// 商品についてのお問い合わせ
// 店舗についてのお問い合わせ
// ※「checkName_〇〇」は任意、「checkRequiredChoice」
//
// ▼内容チェック
// // 半角数値+ハイフン [0-9\-]+
// // 半角数値 [0-9]+
// // \d+:\d+
// // 半角英字 [A-Za-z]+
// // 半角英数字 [A-Za-z0-9]+
// // 半角英数字+アンダースコア+ドット[A-Za-z0-9_\.]+
// // 半角英数字+ハイフン+アンダースコア+スラッシュ+ドット[A-Za-z0-9\-_/\.]+
// ▽文字数
// // 桁数(固定):全角1、半角1
// // 桁数(以上):全角1、半角1
// // 桁数(以下):全角1、半角1
// // 桁数(範囲):全角1、半角1
// ▽バイト数(半角基準)
// // 桁数(固定):全角2、半角1、サロゲートペア文字(絵文字)4
// // 桁数(以上):全角2、半角1、サロゲートペア文字(絵文字)4
// // 桁数(以下):全角2、半角1、サロゲートペア文字(絵文字)4
// // 桁数(範囲):全角2、半角1、サロゲートペア文字(絵文字)4
// ▽バイト数(全角基準)
// // 桁数(固定):全角1、半角0.5、サロゲートペア文字(絵文字)2
// // 桁数(以上):全角1、半角0.5、サロゲートペア文字(絵文字)2
// // 桁数(以下):全角1、半角0.5、サロゲートペア文字(絵文字)2
// // 桁数(範囲):全角1、半角0.5、サロゲートペア文字(絵文字)2
// ▽バイト数(UTF-8)
// // 桁数(固定):全角3、半角1、サロゲートペア文字(絵文字)4
// // 桁数(以上):全角3、半角1、サロゲートペア文字(絵文字)4
// // 桁数(以下):全角3、半角1、サロゲートペア文字(絵文字)4
// // 桁数(範囲):全角3、半角1、サロゲートペア文字(絵文字)4
//
// // URLに利用できる文字
// // メールアドレス
// // IPアドレス
// // パスワード(記号可:6~50文字)
// // ひらがなのみ
// // カタカナのみ
// // 半角カタカナのみ
// // 半角カタカナはNG
// // 半角記号はNG
// // 「〇〇」で始まる文字
// // 「〇〇」で終わる文字
// // 年月日(YYYY/MM/DD)
//
// ▼同一内容チェック
//
//
//
//
// ※「checkSam_〇〇」は任意
//
// ▼入力時に同名必須チェック
//
//
// ※「checkEnough_〇〇」は任意
//
// ▼裏で動かして一緒にアラート(valueはjavascriptで制御)
// // valueが入っていたらアラート表示:alertIDでフォーカス
//
// ▼入力内容が一致する場合は他の処理を無視する
//
//
// ▼独自関数でチェック
//
//
//
// ▼フォーカスが外れた時に事前チェック(非同期通信を利用したい場合など)
// ★ただし処理直前のPHP側のチェックは必須
// ※以下の例の場合、checkCode.phpは重複していたら「1」を返す。
//
//
function validationClass() {
this.errList = [];
this.preCheck = false;
this.fnc = new Array();
this.blur = new Array();
var this_ = this;
$('[class*=checkBlur]').blur(function(){
if( !$(this).val() ) return true;
var className = " " + this.className + " ";
if( parts = className.match( / checkBlur\[([^\]]+)\] / ) ) {
if( parts[1] in this_.blur ) {
$(this).data('checkBlur','をチェック中です。しばらくお待ちください。');
this_.blur[parts[1]](this);
}
}
});
}
validationClass.prototype.setPreCheck = function( obj ) {
this.preCheck = obj;
}
validationClass.prototype.getErrList = function() {
return this.errList;
}
validationClass.prototype.getEle = function( no ) {
return this.errList[no][0];
}
validationClass.prototype.getMessage = function() {
var message = '';
for( key in this.errList ) {
if( this.errList[key][1] ) message += '『'+this.errList[key][1]+'』';
if( this.errList[key][2] ) message += this.errList[key][2];
message += '\n';
}
return message;
}
validationClass.prototype.check = function( ele ) {
if( this.preCheck ) this.preCheck.check();
var eleName;
var eleList = {};
for( var i = 0; i < ele.length; i++ ) {
var className = " " + ele[i].className + " ";
eleName = ( parts = className.match( / checkName_([^ ]+) / ) )? parts[1]: ele[i].name;
var alertName = ele[i].getAttribute('alertName');
var alertFormat = ele[i].getAttribute('alertFormat');
if( !alertName ) alertName = eleName;
// 無視
if( className.match( / checkIgnore / ) || ( parts = className.match( / checkIgnore\[([^\]]+)\] / ) && ele[i].value == parts[1] ) ) continue;
// 必須
var checkRequired = false;
if( parts = className.match( / checkRequired(Choice)? / ) ) {
checkRequired = true;
switch( ele[i].type ) {
case 'date':
case 'datetime-local':
case 'email':
case 'month':
case 'number':
case 'password':
case 'search':
case 'tel':
case 'text':
case 'time':
case 'url':
case 'week':
case 'textarea':
var value = ( !ele[i].value.match( /\S/g ) )? '': ele[i].value;
var sw = false;
if( !eleList['Required_'+eleName] ) {
sw = true;
} else if( parts[1] == 'Choice' ) {
if( !eleList['Required_'+eleName][1] && value ) sw = true;
} else {
if( eleList['Required_'+eleName][1] && !value ) sw = true;
}
if( sw ) eleList['Required_'+eleName] = Array( ele[i], value, alertName, 'を入力してください。' );
break;
case 'file':
eleList['Required_'+eleName] = Array( ele[i], ( ele[i].value ), alertName, 'を選択してください。' );
break;
case 'radio':
if( !eleList['Required_'+eleName] || ( ele[i].checked ) ) eleList['Required_'+eleName] = Array( ele[i], ( ele[i].checked ), alertName, 'を選択してください。' );
break;
case 'checkbox':
if( !eleList['Required_'+eleName] || ( ele[i].checked ) ) eleList['Required_'+eleName] = Array( ele[i], ( ele[i].checked ), alertName, 'にチェックを入れてください。' );
break;
case 'select':
case 'select-one':
if( !eleList['Required_'+eleName] || ( eleList['Required_'+eleName][1] && !ele[i].options[ele[i].selectedIndex].value ) ) eleList['Required_'+eleName] = Array( ele[i], ( ele[i].options[ele[i].selectedIndex].value ), alertName, 'を選択してください。' );
break;
case 'select-multiple':
for( var j = 0; j < ele[i].length; j++ ) {
if( !eleList['Required_'+eleName] || ( ele[i][j].selected ) ) eleList['Required_'+eleName] = Array( ele[i], ( ele[i][j].selected ), alertName, 'を選択してください。' );
}
break;
}
}
if( ( ele[i].type == 'date' || ele[i].type == 'datetime-local' || ele[i].type == 'email' || ele[i].type == 'month' || ele[i].type == 'number' || ele[i].type == 'password' || ele[i].type == 'search' || ele[i].type == 'tel' || ele[i].type == 'text' || ele[i].type == 'time' || ele[i].type == 'url' || ele[i].type == 'week' || ele[i].type == 'textarea' || ele[i].type == 'select-one' || ele[i].type == 'select-multiple' ) ) {
var value = ele[i].value;
if( value ) {
// 半角数値+ハイフン
if( className.match( / checkTel / ) ) {
if( !value.match( /^[0-9\-]+$/ ) ) eleList['Tel_'+eleName] = Array( ele[i], false, alertName, 'は半角数字で入力してください。(ハイフン可)' );
}
// 半角数値のみ
if( className.match( / checkNumber / ) ) {
if( !value.match( /^[0-9]+$/ ) ) eleList['Tel_'+eleName] = Array( ele[i], false, alertName, 'は半角数字のみで入力してください。' );
}
// 半角数値+小数点
if( className.match( / checkFloat / ) ) {
if( !value.match( /^[0-9\.]+$/ ) ) eleList['Float_'+eleName] = Array( ele[i], false, alertName, 'は半角数字で入力してください。' );
}
// 半角英字のみ
if( className.match( / checkAlphabet / ) ) {
if( value.match( /[^A-Za-z]+/ ) ) eleList['Alphabet_'+eleName] = Array( ele[i], false, alertName, 'は半角英字を使用してください。' );
}
// 半角文字のみ
if( className.match( / checkHankaku / ) ) {
if( value.match( /[^A-Za-z0-9]+/ ) ) eleList['Hankaku_'+eleName] = Array( ele[i], false, alertName, 'は半角英数字を使用してください。' );
}
// 半角英数字+アンダースコア+ドット
if( className.match( / checkFilename / ) ) {
if( value.match( /[^A-Za-z0-9_\.]+/ ) ) eleList['Dirname_'+eleName] = Array( ele[i], false, alertName, 'は半角英数字・ハイフン・アンダースコア・スラッシュ・ドットを使用してください。' );
}
// 半角英数字+ハイフン+アンダースコア+スラッシュ+ドット
if( className.match( / checkDirname / ) ) {
if( value.match( /[^A-Za-z0-9\-_/\.]+/ ) ) eleList['Dirname_'+eleName] = Array( ele[i], false, alertName, 'は半角英数字・ハイフン・アンダースコア・スラッシュ・ドットを使用してください。' );
}
// ひらがなのみ
if( className.match( / checkHiragana / ) ) {
if( !value.match( /^[\u3040-\u309Fー・]+$/ ) ) eleList['Hiragana_'+eleName] = Array( ele[i], false, alertName, 'は「ひらがな」を使用してください。' );
}
// カタカナのみ
if( className.match( / checkKatakana / ) ) {
if( !value.match( /^[\u30A0-\u30FFー・ ]+$/ ) ) eleList['Katakana_'+eleName] = Array( ele[i], false, alertName, 'は「カタカナ」を使用してください。' );
}
// 半角カタカナのみ
if( className.match( / checkHankakukana / ) ) {
if( !value.match( /^[ヲ-゚]*$/ ) ) eleList['Hankakukana_'+eleName] = Array( ele[i], false, alertName, 'は「半角カタカナ」を使用してください。' );
}
// 半角カタカナはNG
if( className.match( / checkHankakukana- / ) ) {
if( value.match( /[ヲ-゚]/ ) ) eleList['Hankakukana_'+eleName] = Array( ele[i], false, alertName, 'は「半角カタカナ」を使用できません。' );
}
// 半角記号はNG
if( className.match( / checkKigou- / ) ) {
if( value.match( /[\x21-\x2f\x3a-\x40\x5b-\x60\x7b-\xa5]/ ) ) eleList['KIgou_'+eleName] = Array( ele[i], false, alertName, 'は「半角記号」を使用できません。' );
}
// 時刻
if( className.match( / checkTime / ) ) {
if( !value.match( /^[0-9]+:[0-9]+$/ ) ) eleList['Time_'+eleName] = Array( ele[i], false, alertName, 'は半角数字を「:」で区切って入力してください。' );
}
// 〇で始まる
if( parts = className.match( / checkStart\[([^\]]+)\] / ) ) {
var re = new RegExp( '^'+parts[1] );
alertFormat = ( !alertFormat )? '「'+parts[1]+'」で始まる文字': '「'+alertFormat+'」';
if( !value.match( re ) ) eleList['Start_'+eleName] = Array( ele[i], false, alertName, 'は'+alertFormat+'で入力してください。' );
}
// 〇で終わる
if( parts = className.match( / checkEnd\[([^\]]+)\] / ) ) {
var re = new RegExp( parts[1]+'$' );
alertFormat = ( !alertFormat )? '「'+parts[1]+'」で終わる文字': '「'+alertFormat+'」';
if( !value.match( re ) ) eleList['End_'+eleName] = Array( ele[i], false, alertName, 'は'+alertFormat+'で入力してください。' );
}
// 桁数
if( parts = className.match( / checkLength(\d+)?(\-)?(\d+)? / ) ) {
parts[1] = Number( parts[1] );
parts[3] = Number( parts[3] );
if( parts[2] != '-' ) {
if( value.length != parts[1] ) eleList['Length_'+eleName] = Array( ele[i], false, alertName, 'は'+parts[1]+'文字で入力してください。' );
} else {
if( parts[1] && parts[3] ) {
if( value.length < parts[1] || value.length > parts[3] ) eleList['Length_'+eleName] = Array( ele[i], false, alertName, 'は'+parts[1]+'文字~'+parts[3]+'文字で入力してください。' );
} else if( parts[1] ) {
if( value.length < parts[1] ) eleList['Length_'+eleName] = Array( ele[i], false, alertName, 'は'+parts[1]+'文字以上で入力してください。' );
} else if( parts[3] ) {
if( value.length > parts[3] ) eleList['Length_'+eleName] = Array( ele[i], false, alertName, 'は'+parts[3]+'文字以下で入力してください。' );
}
}
}
// 桁数(バイト)
if( parts = className.match( / checkByte(\d+)?(\-)?(\d+)? / ) ) {
parts[1] = Number( parts[1] );
parts[3] = Number( parts[3] );
textByteSize = 0;
for (let i = 0; i < value.length; i++) { (value[i].match(/[ -~]/)) ? textByteSize += 1 : textByteSize += 2; }
if( parts[2] != '-' ) {
if( textByteSize != parts[1] ) eleList['Byte_'+eleName] = Array( ele[i], false, alertName, 'は半角'+parts[1]+'文字で入力してください。' );
} else {
if( parts[1] && parts[3] ) {
if( textByteSize < parts[1] || textByteSize > parts[3] ) eleList['Byte_'+eleName] = Array( ele[i], false, alertName, 'は半角'+parts[1]+'文字~'+parts[3]+'文字で入力してください。' );
} else if( parts[1] ) {
if( textByteSize < parts[1] ) eleList['Byte_'+eleName] = Array( ele[i], false, alertName, 'は半角'+parts[1]+'文字以上で入力してください。' );
} else if( parts[3] ) {
if( textByteSize > parts[3] ) eleList['Byte_'+eleName] = Array( ele[i], false, alertName, 'は半角'+parts[3]+'文字以下で入力してください。' );
}
}
}
if( parts = className.match( / checkByteA(\d+)?(\-)?(\d+)? / ) ) {
parts[1] = Number( parts[1] );
parts[3] = Number( parts[3] );
textByteSize = 0;
for (let i = 0; i < value.length; i++) { (value[i].match(/[ -~]/)) ? textByteSize += 0.5 : textByteSize += 1; }
if( parts[2] != '-' ) {
if( textByteSize != parts[1] ) eleList['Byte_'+eleName] = Array( ele[i], false, alertName, 'は全角'+parts[1]+'文字で入力してください。' );
} else {
if( parts[1] && parts[3] ) {
if( textByteSize < parts[1] || textByteSize > parts[3] ) eleList['Byte_'+eleName] = Array( ele[i], false, alertName, 'は全角'+parts[1]+'文字~'+parts[3]+'文字で入力してください。' );
} else if( parts[1] ) {
if( textByteSize < parts[1] ) eleList['Byte_'+eleName] = Array( ele[i], false, alertName, 'は全角'+parts[1]+'文字以上で入力してください。' );
} else if( parts[3] ) {
if( textByteSize > parts[3] ) eleList['Byte_'+eleName] = Array( ele[i], false, alertName, 'は全角'+parts[3]+'文字以下で入力してください。' );
}
}
}
if( parts = className.match( / checkByteU(\d+)?(\-)?(\d+)? / ) ) {
parts[1] = Number( parts[1] );
parts[3] = Number( parts[3] );
parts[11] = Math.floor( parts[1] /3 );
parts[12] = Math.ceil( parts[1] /3 );
parts[13] = Math.floor( parts[3] /3 );
textByteSize = encodeURIComponent(value).replace(/%../g,"x").length;
if( parts[2] != '-' ) {
if( textByteSize != parts[1] ) eleList['Byte_'+eleName] = Array( ele[i], false, alertName, 'は全角'+parts[11]+'文字(半角'+parts[1]+'文字)で入力してください。' );
} else {
if( parts[1] && parts[3] ) {
if( textByteSize < parts[1] || textByteSize > parts[3] ) eleList['Byte_'+eleName] = Array( ele[i], false, alertName, 'は全角'+parts[12]+'文字~'+parts[13]+'文字(半角'+parts[1]+'文字~'+parts[3]+'文字)で入力してください。' );
} else if( parts[1] ) {
if( textByteSize < parts[1] ) eleList['Byte_'+eleName] = Array( ele[i], false, alertName, 'は全角'+parts[12]+'文字(半角'+parts[1]+'文字)以上で入力してください。' );
} else if( parts[3] ) {
if( textByteSize > parts[3] ) eleList['Byte_'+eleName] = Array( ele[i], false, alertName, 'は全角'+parts[13]+'文字(半角'+parts[3]+'文字)以下で入力してください。' );
}
}
}
// フォーカスが外れた時に事前チェック(非同期通信を利用したい場合など)
if( parts = className.match( / checkBlur\[([^\]]+)\] / ) ) {
if( parts[1] in this.blur ) {
if( alertMessage = $(ele[i]).data('checkBlur') ) eleList['Blur_'+eleName] = Array( ele[i], false, alertName, alertMessage );
}
}
// URLに利用できる文字
if( className.match( / checkURL / ) ) {
if( value.match( /[^A-Za-z0-9\-_\.!'\(\)#%\^\:\?@$&\+,;\=\/]+/ ) ) eleList['Dirname_'+eleName] = Array( ele[i], false, alertName, 'を正しく入力して下さい。' );
}
// メールアドレス
if( className.match( / checkMail / ) ) {
if( !value.match( /[!#-9A-~]+@+[a-z0-9]+.+[^.]$/i ) ) eleList['Mail_'+eleName] = Array( ele[i], false, alertName, 'の形式が異なります。' );
if( !value.match( /^[a-z0-9A-Z-\._@~!#$%&+/=?{|}]+$/ ) ) eleList['Mail_'+eleName] = Array( ele[i], false, alertName, 'は半角文字を使用してください。' );
}
// パスワード(記号可)
if( className.match( / checkPassword / ) ) {
if( !value.match( /^[a-zA-Z0-9\._@~!#$%&+\/=\?{|}\-]{1,50}$/ ) ) eleList['Password_'+eleName] = Array( ele[i], false, alertName, 'は半角英数小文字50文字以下(記号可)で入力してください。' );
}
// 年月日
if( className.match( / checkDate / ) ) {
if( !value.match( /^\d{4}[\/](0?[1-9]|1[012])[\/](0?[1-9]|[12][0-9]|3[01])$/ ) ) eleList['Date_'+eleName] = Array( ele[i], false, alertName, 'の形式が異なります。' );
}
// IPアドレス
if( className.match( / checkIP / ) ) {
if( !value.match( /^[0-9\.]+$/ ) ) {
eleList['IP_'+eleName] = Array( ele[i], false, alertName, 'の形式(IPv4)が異なります。' );
} else {
if( parts = value.match( /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ ) ) {
check = true;
for( var p in parts ) {
if( parts[p] > 255 ) check = false;
}
if( !check ) eleList['IP_'+eleName] = Array( ele[i], false, alertName, 'の形式(IPv4)が異なります。' );
} else {
eleList['IP_'+eleName] = Array( ele[i], false, alertName, 'の形式(IPv4)が異なります。' );
}
}
}
// 同一チェック
if( parts = className.match( / checkSam_([^ ]+) / ) ) {
if( eleList['Sam_'+parts[1]] ) {
if( eleList['Sam_'+parts[1]][4] != value ) {
eleList['Sam_'+parts[1]][1] = false;
eleList['Sam_'+parts[1]][2] += 'と'+alertName;
}
eleList['Sam_'+parts[1]][5]++;
} else {
eleList['Sam_'+parts[1]] = Array( ele[i], true, alertName, 'が一致しません。入力し直してください。', value, 1 );
}
}
}
// 独自関数
if( parts = className.match( / checkFnc\[([^\]]+)\] / ) ) {
if( parts[1] in this.fnc ) {
res = this.fnc[parts[1]](ele[i],eleName,alertName,value);
if( res ) {
if( $.isPlainObject( res ) ) {
if( !( 'checkName' in res ) ) res['checkName'] = eleName;
if( !( 'focusEle' in res ) ) res['focusEle'] = ele[i];
if( !( 'value' in res ) ) res['value'] = false;
if( !( 'alertName' in res ) ) res['alertName'] = alertName;
if( !( 'alertMessage' in res ) ) res['alertMessage'] = '';
eleList['Fnc_'+res['checkName']] = Array( res['focusEle'], res['value'], res['alertName'], res['alertMessage'] );
} else {
eleList['Fnc_'+eleName] = Array( ele[i], false, alertName, res );
}
}
}
}
// 入力時に同名必須チェック
if( parts = className.match( / checkEnough_([^ ]+) / ) ) {
if( eleList['Enough_'+parts[1]] ) {
if( eleList['Enough_'+parts[1]][5] != 4 ) {
if( checkRequired && !value ) {
eleList['Enough_'+parts[1]][1] = true;
eleList['Enough_'+parts[1]][5] = 4;
} else {
if( eleList['Enough_'+parts[1]][4] ) {
if( !value && eleList['Enough_'+parts[1]][5] == 2 ) {
eleList['Enough_'+parts[1]][0] = ele[i];
eleList['Enough_'+parts[1]][1] = false;
eleList['Enough_'+parts[1]][2] = alertName;
eleList['Enough_'+parts[1]][3] = 'を正しく'+( ( ele[i].type == 'date' || ele[i].type == 'datetime-local' || ele[i].type == 'email' || ele[i].type == 'month' || ele[i].type == 'number' || ele[i].type == 'password' || ele[i].type == 'search' || ele[i].type == 'tel' || ele[i].type == 'text' || ele[i].type == 'time' || ele[i].type == 'url' || ele[i].type == 'week' || ele[i].type == 'textarea' )? '入力': '選択' )+'してください。';
eleList['Enough_'+parts[1]][5] = 3;
}
} else {
if( value ) eleList['Enough_'+parts[1]][1] = false;
}
}
}
} else {
eleList['Enough_'+parts[1]] = Array( ele[i], true, alertName, 'を正しく'+( ( ele[i].type == 'date' || ele[i].type == 'datetime-local' || ele[i].type == 'email' || ele[i].type == 'month' || ele[i].type == 'number' || ele[i].type == 'password' || ele[i].type == 'search' || ele[i].type == 'tel' || ele[i].type == 'text' || ele[i].type == 'time' || ele[i].type == 'url' || ele[i].type == 'week' || ele[i].type == 'textarea' )? '入力': '選択' )+'してください。', value, ( ( checkRequired && !value )? 4: 2 ) );
}
}
}
if( ele[i].type == 'hidden' && ele[i].value ) {
var value = ele[i].value;
// アラート
if( className.match( / checkAlert / ) && value != '' ) {
var setEle = ele[i];
var alertID = ele[i].getAttribute('alertID');
if( alertID ) {
var alertEle = document.getElementById( ele[i].getAttribute('alertID') );
if( alertEle ) setEle = alertEle;
}
eleList['Alert_'+eleName] = Array( setEle, false, '', alertName );
}
}
}
var ret = false;
this.errList = Array();
for( key in eleList ) {
if( !eleList[key][1] || eleList[key][5] == 1 ) {
ret = true;
this.errList.push( [ eleList[key][0], eleList[key][2], eleList[key][3] ] );
}
}
return ret;
}