1/*! 2 * exValidation 3 * 4 * @version : 1.3.3 5 * @author : nori ([email protected]) 6 * @copyright : 5509 (http://5509.me/) 7 * @license : The MIT License 8 * @link : http://5509.me/log/exvalidation 9 * @modified : 2012-04-09 16:59 10 */ 11;(function($, window, undefined) { 12 $.exValidationRules = $.exValidationRules || {}; 13 var exValidation = function(form, conf) { 14 if ( form.length > 1 ) { 15 alert("You cannot select any forms"); 16 return false; 17 } 18 19 this.form = form; 20 // for browse 21 var _this = this, 22 b = $("body"); 23 24 conf = this.conf = $.extend({ 25 errInsertPos : "body", // "body" or after(before) 26 err : null, 27 ok : null, 28 errFocus : false, 29 errHoverHide : false, 30 stepValidation : false, 31 scrollToErr : true, 32 scrollDuration : 500, 33 scrollAdjust : -10, 34 customScrollAdjust : false, 35 errPosition : "absolute", // fixed 36 errOpacity : undefined, 37 errTipPos : "right", // left 38 errTipCloseBtn : true, 39 errTipCloseLabel : "Ã", 40 errZIndex : 500, 41 errMsgPrefix : "\* ", 42 customAddError : null, // function(){} 43 customClearError : null, // function(){} 44 customSubmit : null, // function(){} 45 customListener : "blur keyup change focus", 46 customBind : null, 47 /* Using this conf, you can bind validation func to any element 48 { 49 object: $(button), 50 listener: "blur keyup change focus", 51 callback: function() {} 52 } 53 */ 54 customGetErrHeight : null, 55 firstValidate : false, 56 // default checking targets 57 inputs: [ 58 "input:text", 59 "input:password", 60 "input:hidden", 61 "input:file", 62 "textarea", 63 "select", 64 "input[type=email]", 65 "input[type=url]", 66 "input[type=tel]", 67 "input[type=date]", 68 "input[type=datetime]", 69 "input[type=month]", 70 "input[type=week]", 71 "input[type=time]", 72 "input[type=datetime-local]", 73 "input[type=number]", 74 "input[type=range]", 75 "input[type=color]", 76 "[class*=group]", 77 "[class*=radio]", 78 "[class*=checkbox]" 79 ], 80 // default checking targets in groups 81 groupInputs: [ 82 "input:text", 83 "input:password", 84 "input:checkbox", 85 "input:radio", 86 "input[type=email]", 87 "input[type=url]", 88 "input[type=tel]", 89 "input[type=date]", 90 "input[type=datetime]", 91 "input[type=month]", 92 "input[type=week]", 93 "input[type=time]", 94 "input[type=datetime-local]", 95 "input[type=number]", 96 "input[type=range]", 97 "input[type=color]", 98 "select", 99 "textarea" 100 ] 101 }, conf); 102 103 conf.inputs = conf.inputs.join(","); 104 conf.groupInputs = conf.groupInputs.join(","); 105 106 this.errFocus = function(id) { 107 if ( !conf.errFocus ) return false; 108 errFocus(id, conf.errZIndex); 109 }; 110 this.errFocusClear = function() { 111 if ( !conf.errFocus ) return false; 112 errFocusClear(conf.errZIndex); 113 }; 114 115 if ( fnConfirmation(conf.customSubmit) ) { 116 form.submit(function() { 117 return false; 118 }); 119 } 120 form.find("input:checkbox,input:radio,input:button,input:submit,input:reset").click(function() { 121 _this.errFocusClear(); 122 }); 123 124 // addClasses for each inputs by validation rules 125 for ( var c in conf.rules ) { 126 $("#" + c).addClass(conf.rules[c]); 127 } 128 129 // If this form doesn"t have ID, formID for error tips is to be decided by random integer 130 var formID = form.attr("id") 131 ? "form_" + form.attr("id") 132 : "form_" + randomInt()*randomInt(); 133 134 var inputs = $(conf.inputs, form) 135 .filter(function() { return !$(this).parents().hasClass("chkgroup"); }), 136 classReg = returnReg(), 137 bindValidateFuncs = function(target, group) { 138 var self = group ? group : target; 139 target.bind(conf.customListener, function() {
140 _this.basicValidate(group ? group : this, conf.err, conf.ok); 141 _this.errFocus("#err_" + self.attr("id")); 142 }).blur(function() { 143 _this.errFocusClear(); 144 }); 145 }; 146 147 inputs.each(function() { 148 var self = $(this), 149 cl = this.className, 150 id = this.id, 151 reg1 = undefined, 152 reg2 = undefined, 153 toggleTarget = undefined; 154 155 if ( conf.errTipPos === "right" ) { 156 self.addClass("errPosRight"); 157 } 158 159 // if target has one of classRegulations 160 if ( classReg.test(cl) ) { 161 if ( conf.errInsertPos === "body" ) { 162 b.append(_this.generateErr(id, formID)); 163 } else { 164 self[conf.errInsertPos](_this.generateErr(id, formID)); 165 self.addClass(conf.errInsertPos); 166 } 167 168 if ( conf.errHoverHide ) { 169 $("#err_"+id).mouseenter(function() { 170 $(this).fadeOut(); 171 }); 172 } 173 if ( conf.errTipCloseBtn ) { 174 $("#err_"+id).append( 175 $("<span></span>") 176 .addClass("formErrorClose") 177 .text(conf.errTipCloseLabel) 178 .click(function() { 179 $(this).parent().fadeOut(); 180 }) 181 ); 182 } 183 if ( conf.errOpacity !== undefined ) { 184 $("#err_"+id).children().css("opacity", conf.errOpacity); 185 } 186 if ( conf.errPosition === "absolute" ) { 187 if ( fnConfirmation(conf.customGetErrHeight) ) { 188 _this.customGetErrHeight(id); 189 } else { 190 _this.getErrHeight(id, conf.errZIndex); 191 } 192 193 // Reget the position 194 $(window).resize(function() { 195 if ( fnConfirmation(conf.customGetErrHeight) ) { 196 _this.customGetErrHeight(id); 197 } else { 198 _this.getErrHeight(id, conf.errZIndex); 199 } 200 }); 201 } 202 $("#err_"+id).hide(); 203 } 204 205 }); 206 207 // Checkboxã«ããåå² 208 inputs.each(function() { 209 var _self = $(this), 210 reg1 = undefined, 211 reg2 = undefined, 212 toggleTarget = undefined; 213 214 if ( this.className.match(/chktoggle_([^_]+)_([^ ]+)/) ) { 215 reg1 = "#" + RegExp.$1; 216 reg2 = "#" + RegExp.$2; 217 toggleTarget = $(reg2).removeClass("chkrequired"); 218 $(reg1).click(function() { 219 console.log(toggleTarget); 220 if ( this.checked ) { 221 toggleTarget.addClass("chkrequired"); 222 } else { 223 toggleTarget.removeClass("chkrequired"); 224 } 225 _this.laterCall(toggleTarget); 226 }); 227 } 228 229 if ( !conf.firstValidate ) return; 230 if ( _self.hasClass("chkgroup") ) { 231 bindValidateFuncs($(conf.groupInputs, _self), _self); 232 } else { 233 bindValidateFuncs(_self); 234 } 235 }); 236 237 // You call this func everytime you like after init 238 this.laterCall = function(t) { 239 _this.basicValidate(t, conf.err, conf.ok); 240 }; 241 242 function _exeValidation(customBindCallback) { 243 if ( conf.firstValidate ) { 244 inputs.unbind("blur keyup change click"); 245 conf.firstValidate = false; 246 } 247 inputs.each(function() { 248 var self = $(this); 249 _this.basicValidate(this, conf.err, conf.ok, true); 250 251 if ( self.hasClass("chkgroup") ) { 252 bindValidateFuncs($(conf.groupInputs, self), self); 253 } else { 254 bindValidateFuncs(self); 255 } 256 }); 257 258 var err = $(".formError:visible[class*='"+formID+"']"); 259 var headerHight = 210; //åºå®ãããã®é«ã 260 261 // if errs are displayed 262 if ( err.length > 0 ) { 263 if ( fnConfirmation(conf.customAddError) ) { 264 conf.customAddError(); 265 } 266 if ( conf.scrollToErr ) { 267 var reverseOffsetTop, 268 infoErr, errTop, 269 scrollTarget = $.support.boxModel 270 ? navigator.appName.indexOf("Opera") !== -1 ? 271 "html" : "html,body" 272 : "body"; 273 274 275 if ( !conf.customScrollAdjust ) { 276 reverseOffsetTop = $(err[0]).offset().top-headerHight; 277 errTop = $(err[0]); 278 279 for ( var i=0, l=err.length; i<l; i++ ) { 280 infoErr = $(err[i]); 281 reverseOffsetTop = infoErr.offset().top-headerHight < reverseOffsetTop 282 ? infoErr.offset().top-headerHight : reverseOffsetTop; 283 errTop = infoErr.offset().top-headerHight < reverseOffsetTop 284 ? infoErr : errTop; 285 } 286 287 288 289 if ( conf.errPosition === "fixed" ) { 290 reverseOffsetTop -= $("#"+errTop.attr("id").replace("err_", "")).get(0).offsetHeight; 291 } 292 } else { 293 reverseOffsetTop = fnConfirmation(conf.customScrollAdjust) 294 ? parseFloat(conf.customScrollAdjust()) : parseFloat(conf.customScrollAdjust); 295 } 296 297 $(scrollTarget).animate({ 298 scrollTop: reverseOffsetTop + conf.scrollAdjust 299 }, { 300 easing: $.easing.easeInOutCirc ? "easeInOutCirc" : "swing", 301 duration: conf.scrollDuration 302 }); 303 } 304 return false;
305 306 // if no err is displayed 307 } else { 308 if ( fnConfirmation(conf.customClearError) ) { 309 // falseãè¿ã£ã¦ããå ´åã¯ãã£ã³ã»ã«ãã 310 var result = conf.customClearError(); 311 if ( !result ) return false; 312 // if ( result == false ) return false; 313 } 314 // CustomBindCallBack 315 if ( fnConfirmation(customBindCallback) ) { 316 customBindCallback(); 317 return false; 318 } else { 319 // customSubmit 320 if ( fnConfirmation(conf.customSubmit) ) { 321 conf.customSubmit(); 322 return false; 323 // Default Postback 324 } else { 325 // OK 326 return true; 327 } 328 } 329 } 330 } 331 332 // When the form is submited 333 form.submit(_exeValidation); 334 335 // Add the Validation 336 if ( conf.customBind ) { 337 conf.customBind.object.bind(conf.customBind.listener, function() { 338 _exeValidation(conf.customBind.callback); 339 return false; 340 }); 341 } 342 343 // Return the instance 344 return this; 345 }; 346 347 // Common prototype functions 348 exValidation.prototype = { 349 // Errtip content 350 // this HTML source code from "A jQuery inline form validation, because validation is a mess" 351 // thanks to http://bit.ly/onlNv (http://www.position-relative.net/) 352 generateErr: function(id, formID) { 353 return [ 354 '<div id="err_'+id+'" class="formError userformError'+' '+formID+' '+this.conf.errPosition+'">', 355 '<div class="formErrorMsg formErrorContent"></div>', 356 '<div class="formErrorArrow">', 357 '<div class="line10"></div>', 358 '<div class="line9"></div>', 359 '<div class="line8"></div>', 360 '<div class="line7"></div>', 361 '<div class="line6"></div>', 362 '<div class="line5"></div>', 363 '<div class="line4"></div>', 364 '<div class="line3"></div>', 365 '<div class="line2"></div>', 366 '<div class="line1"></div>', 367 '</div>', 368 '</div>' 369 ].join(""); 370 }, 371 // Insert error message 372 insertErrMsg: function(t, id, c, errMsg) { 373 var msgs = $(".errMsg", "#err_"+id), 374 returnFlg = true; 375 if ( msgs.length > 0 ) { 376 $.each(msgs, function() { 377 if ( $(this).hasClass(c) ) { 378 returnFlg = false; 379 } 380 }); 381 } 382 if ( !returnFlg ) return false; 383 $(".formErrorMsg", "#err_"+id).append( 384 $("<span></span>") 385 .addClass("errMsg") 386 .addClass(c) 387 .text(errMsg) 388 ); 389 this.getErrHeight(id); 390 }, 391 // Basic get error height 392 getErrHeight: function(id, zIndex) { 393 if ( this.conf.errPosition !== "absolute" ) return false; 394 var input = $("#"+id), 395 err = $("#err_"+id), 396 target = input.is(":hidden") ? input.next() : input, 397 pos = target.offset(); 398 399 if ( !!pos ) { 400 var left = target.hasClass("errPosRight") 401 ? pos.left + target.get(0).offsetWidth - 40 402 : pos.left - 20; 403 404 err.css({ 405 position: "absolute", 406 top: pos.top - err.get(0).offsetHeight, 407 left: left 408 }); 409 } 410 411 if ( zIndex ) { 412 err.css("zIndex", zIndex); 413 } 414 }, 415 // Basic validation 416 basicValidate: function(t, err, ok) { 417 var _t = $(t), 418 CL = _t.attr("class"), 419 chk = $.exValidationRules, 420 id = _t.attr("id"), 421 txt = "", 422 _this = this; 423 424 if ( _t.hasClass("chkgroup") ) { 425 var groupInputs = $(_this.conf.groupInputs, t); 426 groupInputs.each(function(i) { 427 var self = $(this); 428 txt += self.val(); 429 if( CL.indexOf("chkemail") !== -1 && i==0 && self.val().length > 0 ) 430 txt += "@"; 431 }); 432 } else { 433 txt = _t.val(); 434 } 435 436 var check = { 437 isError: false, 438 failed: function(t, c) { 439 var msg = chk[c][0]; 440 if ( c.match(/chkmin/i) && CL.match(/chkmin(\d+)/i) ) { 441 msg = RegExp.$1 + msg; 442 } else 443 if ( c.match(/chkmax/i) && CL.match(/chkmax(\d+)/i) ) { 444 msg = RegExp.$1 + msg; 445 } 446 447 if( fnConfirmation(err) ) { 448 err(t, id, _this.conf.errMsgPrefix + msg); 449 } else { 450 _t.addClass("err"); 451 $("."+c, "#err_"+id).show(); 452 $("#err_"+id).stop(true, true).fadeIn(); 453 _this.insertErrMsg(t, id, c, _this.conf.errMsgPrefix + msg); 454 _this.getErrHeight(id); 455 } 456 this.isError = true; 457 } 458 }; 459 460 var c; 461 for ( c in chk ) { 462 if ( !CL ) continue; 463 if ( _t.hasClass(c) 464 || (c === "chkmin" && CL.match(/(?:\s+|^)chkmin\d+(?:\s+|$)/) ) 465 || (c === "chkmax" && CL.match(/(?:\s+|^)chkmax\d+(?:\s+|$)/) ) 466 || ( CL.indexOf(c) !== -1 && CL.indexOf("chkretype") !== -1 ) ) { 467 if ( typeof(chk[c][1]) !== "function" ) { 468 if ( !txt.match(chk[c][1]) ) { 469 check.failed(t, c); 470 } else 471 if ( _this.conf.stepValidation ) { 472 if ( $(".errMsg:visible", "#err_"+id).length > 1 ) { 473 $("."+c, "#err_"+id).hide(); 474 _this.getErrHeight(id); 475 } 476 } 477 } else { 478 if ( !chk[c][1](txt, t) ) { 479 check.failed(t, c); 480 } else 481 if ( _this.conf.stepValidation ) { 482 if ( $(".errMsg:visible", "#err_"+id).length > 1 ) { 483 $("."+c, "#err_"+id).hide(); 484 _this.getErrHeight(id); 485 } 486 } 487 } 488 } 489 } 490 491 if ( !check.isError ) { 492 if ( fnConfirmation(ok) ) { 493 ok(t, id); 494 } else { 495 _t.removeClass("err"); 496 $("#err_"+id).stop(true, true).fadeOut(); 497 } 498 } 499 } 500 } 501 502 // Common functions 503 function returnReg() {
504 var validationClasses = ""; 505 for( var c in $.exValidationRules ) { 506 validationClasses += "(?:\\s+|^)"+c+"(?:\\s+|$)|"; 507 } 508 validationClasses += "(?:\\s+|^)chkmin\\d+(?:\\s+|$)|"; 509 validationClasses += "(?:\\s+|^)chkmax\\d+(?:\\s+|$)|"; 510 validationClasses = validationClasses.replace(/\|$/,""); 511 return new RegExp(validationClasses); 512 } 513 function errFocusClear(errZIndex) { 514 $(".formError") 515 .removeClass("fadeOut") 516 .css("zIndex", errZIndex) 517 } 518 function errFocus(id, errZIndex) { 519 var formError = $(".formError"); 520 formError.removeClass("fadeOut").css("zIndex", errZIndex); 521 formError.not(id).addClass("fadeOut"); 522 $(id).css({ 523 zIndex: errZIndex + 100 524 }); 525 } 526 function fnConfirmation(fn) { 527 return fn && typeof fn === "function"; 528 } 529 function randomInt() { 530 return Math.floor(Math.random()*10)+1; 531 } 532 533 // Extense the namespace of jQuery as method 534 // This function returns instance 535 $.fn.exValidation = function(options) { 536 return new exValidation(this, options); 537 }; 538 if ( !$.fn.validation ) { 539 $.fn.validation = $.fn.exValidation; 540 } 541})(jQuery, this);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.