/** * exValidation * * @version : 1.3.0 * @author : nori (norimania@gmail.com) * @copyright : 5509 (http://5509.me/) * @license : The MIT License * @link : http://5509.me/log/exvalidation * @modified : 2011-10-01 01:28 */ ;(function($, window, undefined) { $.exValidationRules = $.exValidationRules || {}; var exValidation = function(form, conf) { if ( form.length > 1 ) { alert("You cannot select any forms"); return false; } this.form = form; // for browse var _this = this, b = $("body"); conf = this.conf = $.extend({ errInsertPos : "body", // "body" or after(before) err : null, ok : null, errFocus : false, errHoverHide : false, stepValidation : false, scrollToErr : true, scrollDuration : 500, scrollAdjust : -10, customScrollAdjust : false, errPosition : "absolute", // fixed errOpacity : undefined, errTipPos : "right", // left errTipCloseBtn : true, errTipCloseLabel : "×", errZIndex : 500, errMsgPrefix : "\* ", customAddError : null, // function(){} customClearError : null, // function(){} customSubmit : null, // function(){} customListener : "blur keyup change focus", customBind : null, /* Using this conf, you can bind validation func to any element { object: $(button), listener: "blur keyup change focus", callback: function() {} } */ customGetErrHeight : null, firstValidate : false, // default checking targets inputs: [ "input:text", "input:password", "input:hidden", "input:file", "textarea", "select", "input[type=email]", "input[type=url]", "input[type=tel]", "input[type=date]", "input[type=datetime]", "input[type=month]", "input[type=week]", "input[type=time]", "input[type=datetime-local]", "input[type=number]", "input[type=range]", "input[type=color]", "[class*=group]", "[class*=radio]", "[class*=checkbox]" ], // default checking targets in groups groupInputs: [ "input:text", "input:password", "input:checkbox", "input:radio", "input[type=email]", "input[type=url]", "input[type=tel]", "input[type=date]", "input[type=datetime]", "input[type=month]", "input[type=week]", "input[type=time]", "input[type=datetime-local]", "input[type=number]", "input[type=range]", "input[type=color]", "select", "textarea" ] }, conf); conf.inputs = conf.inputs.join(","); conf.groupInputs = conf.groupInputs.join(","); this.errFocus = function(id) { if ( !conf.errFocus ) return false; errFocus(id, conf.errZIndex); }; this.errFocusClear = function() { if ( !conf.errFocus ) return false; errFocusClear(conf.errZIndex); }; if ( fnConfirmation(conf.customSubmit) ) { form.submit(function() { return false; }); } $("input:checkbox,input:radio,input:button,input:submit,input:reset").click(function() { _this.errFocusClear(); }); // addClasses for each inputs by validation rules for ( var c in conf.rules ) { $("#" + c).addClass(conf.rules[c]); } // If this form doesn"t have ID, formID for error tips is to be decided by random integer var formID = form.attr("id") ? "form_" + form.attr("id") : "form_" + randomInt()*randomInt(); var inputs = $(conf.inputs, form) .filter(function() { return !$(this).parents().hasClass("chkgroup"); }), classReg = returnReg(), bindValidateFuncs = function(target, group) { var self = group ? group : target; target.bind(conf.customListener, function() { _this.basicValidate(group ? group : this, conf.err, conf.ok); _this.errFocus("#err_" + self.attr("id")); }).blur(function() { _this.errFocusClear(); }); }; inputs.each(function() { var self = $(this), cl = this.className, id = this.id, reg1 = undefined, reg2 = undefined, toggleTarget = undefined; if ( conf.errTipPos === "right" ) { self.addClass("errPosRight"); } // if target has one of classRegulations if ( classReg.test(cl) ) { if ( conf.errInsertPos === "body" ) { b.append(_this.generateErr(id, formID)); } else { self[conf.errInsertPos](_this.generateErr(id, formID)); self.addClass(conf.errInsertPos); } if ( conf.errHoverHide ) { $("#err_"+id).mouseenter(function() { $(this).fadeOut(); }); } //if ( conf.errTipCloseBtn ) { // $("#err_"+id).append( // $("") // .addClass("formErrorClose") // .text(conf.errTipCloseLabel) // .click(function() { // $(this).parent().fadeOut(); // }) // ); //} if ( conf.errOpacity !== undefined ) { $("#err_"+id).children().css("opacity", conf.errOpacity); } if ( conf.errPosition === "absolute" ) { if ( fnConfirmation(conf.customGetErrHeight) ) { _this.customGetErrHeight(id); } else { _this.getErrHeight(id, conf.errZIndex); } // Reget the position $(window).resize(function() { if ( fnConfirmation(conf.customGetErrHeight) ) { _this.customGetErrHeight(id); } else { _this.getErrHeight(id, conf.errZIndex); } }); } $("#err_"+id).hide(); } }); // Checkboxによる分岐 inputs.each(function() { var _self = $(this), reg1 = undefined, reg2 = undefined, toggleTarget = undefined; if ( this.className.match(/chktoggle_([^_]+)_([^ ]+)/) ) { reg1 = "#" + RegExp.$1; reg2 = "#" + RegExp.$2; toggleTarget = $(reg2).removeClass("chkrequired"); $(reg1).click(function() { console.log(toggleTarget); if ( this.checked ) { toggleTarget.addClass("chkrequired"); } else { toggleTarget.removeClass("chkrequired"); } _this.laterCall(toggleTarget); }); } if ( conf.firstValidate ) return; if ( _self.hasClass("chkgroup") ) { bindValidateFuncs($(conf.groupInputs, _self), _self); } else { bindValidateFuncs(_self); } }); // You call this func everytime you like after init this.laterCall = function(t) { _this.basicValidate(t, conf.err, conf.ok); }; function _exeValidation(customBindCallback) { if ( conf.firstValidate ) { inputs.unbind("blur keyup change click"); conf.firstValidate = false; } inputs.each(function() { var self = $(this); _this.basicValidate(this, conf.err, conf.ok, true); if ( self.hasClass("chkgroup") ) { bindValidateFuncs($(conf.groupInputs, self), self); } else { bindValidateFuncs(self); } }); var err = $(".formError:visible[class*='"+formID+"']"); // if errs are displayed if ( err.length > 0 ) { if ( fnConfirmation(conf.customAddError) ) { conf.customAddError(); } if ( conf.scrollToErr ) { var reverseOffsetTop, infoErr, errTop, scrollTarget = $.support.boxModel ? navigator.appName.indexOf("Opera") !== -1 ? "html" : "html,body" : "body"; if ( !conf.customScrollAdjust ) { reverseOffsetTop = $(err[0]).offset().top; errTop = $(err[0]); for ( var i=0, l=err.length; i', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '' ].join(""); }else if(id == "c_select_companies"){ return [ '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
' ].join(""); }else{ return [ '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
', '
' ].join(""); } }, // Insert error message insertErrMsg: function(t, id, c, errMsg) { var msgs = $(".errMsg", "#err_"+id), returnFlg = true; if ( msgs.length > 0 ) { $.each(msgs, function() { if ( $(this).hasClass(c) ) { returnFlg = false; } }); } if ( !returnFlg ) return false; $(".formErrorMsg", "#err_"+id).append( $("") .addClass("errMsg") .addClass(c) .text(errMsg) ); this.getErrHeight(id); }, // Basic get error height getErrHeight: function(id, zIndex) { if ( this.conf.errPosition !== "absolute" ) return false; var input = $("#"+id), err = $("#err_"+id), target = input.is(":hidden") ? input.next() : input, pos = target.offset(); if ( !!pos ) { if(id == "c_select"){// 追加 var left = target.hasClass("errPosRight") ? pos.left + target.get(0).offsetWidth - 415 : pos.left - 20; }else{ var left = target.hasClass("errPosRight") ? pos.left + target.get(0).offsetWidth - 40 : pos.left - 20; } err.css({ position: "absolute", top: pos.top - err.get(0).offsetHeight, left: left }); } if ( zIndex ) { err.css("zIndex", zIndex); } }, // Basic validation basicValidate: function(t, err, ok) { var _t = $(t), CL = _t.attr("class"), chk = $.exValidationRules, id = _t.attr("id"), txt = "", _this = this; if ( _t.hasClass("chkgroup") ) { var groupInputs = $(_this.conf.groupInputs, t); groupInputs.each(function(i) { var self = $(this); txt += self.val(); if( CL.indexOf("chkemail") !== -1 && i==0 && self.val().length > 0 ) txt += "@"; }); } else { txt = _t.val(); } var check = { isError: false, failed: function(t, c) { var msg = chk[c][0]; if ( c.match(/chkmin/i) && CL.match(/chkmin(\d+)/i) ) { msg = RegExp.$1 + msg; } else if ( c.match(/chkmax/i) && CL.match(/chkmax(\d+)/i) ) { msg = RegExp.$1 + msg; } if( fnConfirmation(err) ) { err(t, id, _this.conf.errMsgPrefix + msg); } else { _t.addClass("err"); $("."+c, "#err_"+id).show(); $("#err_"+id).fadeIn(); _this.insertErrMsg(t, id, c, _this.conf.errMsgPrefix + msg); _this.getErrHeight(id); } this.isError = true; } }; var c; for ( c in chk ) { if ( _t.hasClass(c) || (c === "chkmin" && CL.match(/(?:\s+|^)chkmin\d+(?:\s+|$)/) ) || (c === "chkmax" && CL.match(/(?:\s+|^)chkmax\d+(?:\s+|$)/) ) || ( CL.indexOf(c) !== -1 && CL.indexOf("chkretype") !== -1 ) ) { if ( typeof(chk[c][1]) !== "function" ) { if ( !txt.match(chk[c][1]) ) { check.failed(t, c); } else if ( _this.conf.stepValidation ) { if ( $(".errMsg:visible", "#err_"+id).length > 1 ) { $("."+c, "#err_"+id).hide(); _this.getErrHeight(id); } } } else { if ( !chk[c][1](txt, t) ) { check.failed(t, c); } else if ( _this.conf.stepValidation ) { if ( $(".errMsg:visible", "#err_"+id).length > 1 ) { $("."+c, "#err_"+id).hide(); _this.getErrHeight(id); } } } } } if ( !check.isError ) { if ( fnConfirmation(ok) ) { ok(t, id); } else { _t.removeClass("err"); $("#err_"+id).fadeOut(); } } } } // Common functions function returnReg() { var validationClasses = ""; for( var c in $.exValidationRules ) { validationClasses += "(?:\\s+|^)"+c+"(?:\\s+|$)|"; } validationClasses += "(?:\\s+|^)chkmin\\d+(?:\\s+|$)|"; validationClasses += "(?:\\s+|^)chkmax\\d+(?:\\s+|$)|"; validationClasses = validationClasses.replace(/\|$/,""); return new RegExp(validationClasses); } function errFocusClear(errZIndex) { $(".formError") .removeClass("fadeOut") .css("zIndex", errZIndex) } function errFocus(id, errZIndex) { var formError = $(".formError"); formError.removeClass("fadeOut").css("zIndex", errZIndex); formError.not(id).addClass("fadeOut"); $(id).css({ zIndex: errZIndex + 100 }); } function fnConfirmation(fn) { return fn && typeof fn === "function"; } function randomInt() { return Math.floor(Math.random()*10)+1; } // Extense the namespace of jQuery as method // This function returns instance $.fn.exValidation = function(options) { return new exValidation(this, options); }; if ( !$.fn.validation ) { $.fn.validation = $.fn.exValidation; } })(jQuery, this);