1// SpryValidationTextField.js - version 0.38 - Spry Pre-Release 1.6.1 2// 3// Copyright (c) 2006. Adobe Systems Incorporated. 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions are met: 8// 9// * Redistributions of source code must retain the above copyright notice, 10// this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above copyright notice, 12// this list of conditions and the following disclaimer in the documentation 13// and/or other materials provided with the distribution. 14// * Neither the name of Adobe Systems Incorporated nor the names of its 15// contributors may be used to endorse or promote products derived from this 16// software without specific prior written permission. 17// 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28// POSSIBILITY OF SUCH DAMAGE. 29 30/* æ´æ°å±¥æ´ 31---------------------------------------------------*/ 32// 14/09/24 1087è¡ç®ï¼Firefoxã§æªå¤æã®æåã確å®ããããã°ãåé¿ 33// 34 35(function() { // BeginSpryComponent 36 37if (typeof Spry == "undefined") window.Spry = {}; if (!Spry.Widget) Spry.Widget = {}; 38 39Spry.Widget.BrowserSniff = function() 40{ 41 var b = navigator.appName.toString(); 42 var up = navigator.platform.toString(); 43 var ua = navigator.userAgent.toString(); 44 45 this.mozilla = this.ie = this.opera = this.safari = false; 46 var re_opera = /Opera.([0-9\.]*)/i; 47 var re_msie = /MSIE.([0-9\.]*)/i; 48 var re_gecko = /gecko/i; 49 var re_safari = /(applewebkit|safari)\/([\d\.]*)/i; 50 var r = false; 51 52 if ( (r = ua.match(re_opera))) { 53 this.opera = true; 54 this.version = parseFloat(r[1]); 55 } else if ( (r = ua.match(re_msie))) { 56 this.ie = true; 57 this.version = parseFloat(r[1]); 58 } else if ( (r = ua.match(re_safari))) { 59 this.safari = true; 60 this.version = parseFloat(r[2]); 61 } else if (ua.match(re_gecko)) { 62 var re_gecko_version = /rv:\s*([0-9\.]+)/i; 63 r = ua.match(re_gecko_version); 64 this.mozilla = true; 65 this.version = parseFloat(r[1]); 66 } 67 this.windows = this.mac = this.linux = false; 68 69 this.Platform = ua.match(/windows/i) ? "windows" : 70 (ua.match(/linux/i) ? "linux" : 71 (ua.match(/mac/i) ? "mac" : 72 ua.match(/unix/i)? "unix" : "unknown")); 73 this[this.Platform] = true; 74 this.v = this.version; 75 76 if (this.safari && this.mac && this.mozilla) { 77 this.mozilla = false; 78 } 79}; 80 81Spry.is = new Spry.Widget.BrowserSniff(); 82 83Spry.Widget.ValidationTextField = function(element, type, options) 84{ 85 type = Spry.Widget.Utils.firstValid(type, "none"); 86 if (typeof type != 'string') { 87 this.showError('The second parameter in the constructor should be the validation type, the options are the third parameter.'); 88 return; 89 } 90 if (typeof Spry.Widget.ValidationTextField.ValidationDescriptors[type] == 'undefined') { 91 this.showError('Unknown validation type received as the second parameter.'); 92 return; 93 } 94 options = Spry.Widget.Utils.firstValid(options, {}); 95 this.type = type; 96 if (!this.isBrowserSupported()) { 97 //disable character masking and pattern behaviors for low level browsers 98 options.useCharacterMasking = false; 99 } 100 this.init(element, options); 101 102 //make sure we validate at least on submit 103 var validateOn = ['submit'].concat(Spry.Widget.Utils.firstValid(this.options.validateOn, [])); 104 validateOn = validateOn.join(","); 105 106 this.validateOn = 0; 107 this.validateOn = this.validateOn | (validateOn.indexOf('submit') != -1 ? Spry.Widget.ValidationTextField.ONSUBMIT : 0); 108 this.validateOn = this.validateOn | (validateOn.indexOf('blur') != -1 ? Spry.Widget.ValidationTextField.ONBLUR : 0); 109 this.validateOn = this.validateOn | (validateOn.indexOf('change') != -1 ? Spry.Widget.ValidationTextField.ONCHANGE : 0); 110 111 if (Spry.Widget.ValidationTextField.onloadDidFire) 112 this.attachBehaviors(); 113 else 114 Spry.Widget.ValidationTextField.loadQueue.push(this); 115}; 116 117Spry.Widget.ValidationTextField.ONCHANGE = 1; 118Spry.Widget.ValidationTextField.ONBLUR = 2; 119Spry.Widget.ValidationTextField.ONSUBMIT = 4; 120 121Spry.Widget.ValidationTextField.ERROR_REQUIRED = 1; 122Spry.Widget.ValidationTextField.ERROR_FORMAT = 2; 123Spry.Widget.ValidationTextField.ERROR_RANGE_MIN = 4; 124Spry.Widget.ValidationTextField.ERROR_RANGE_MAX = 8; 125Spry.Widget.ValidationTextField.ERROR_CHARS_MIN = 16; 126Spry.Widget.ValidationTextField.ERROR_CHARS_MAX = 32; 127 128/* validation parameters: 129 * - characterMasking : prevent typing of characters not matching an regular expression 130 * - regExpFilter : additional regular expression to disalow typing of characters 131 * (like the "-" sign in the middle of the value); use for partial matching of the currently typed value; 132 * the typed value must match regExpFilter at any moment 133 * - pattern : enforce character on each position inside a pattern (AX0?) 134 * - validation : function performing logic validation; return false if failed and the typedValue value on success 135 * - minValue, maxValue : range validation; check if typedValue inside the specified range 136 * - minChars, maxChars : value length validation; at least/at most number of characters 137 * */ 138Spry.Widget.ValidationTextField.ValidationDescriptors = { 139 'none': { 140 }, 141 'custom': { 142 }, 143 'integer': { 144 characterMasking: /[\-\+\d]/, 145 regExpFilter: /^[\-\+]?\d*$/, 146 validation: function(value, options) { 147 if (value == '' || value == '-' || value == '+') { 148 return false;
149 } 150 var regExp = /^[\-\+]?\d*$/; 151 if (!regExp.test(value)) { 152 return false; 153 } 154 options = options || {allowNegative:false}; 155 var ret = parseInt(value, 10); 156 if (!isNaN(ret)) { 157 var allowNegative = true; 158 if (typeof options.allowNegative != 'undefined' && options.allowNegative == false) { 159 allowNegative = false; 160 } 161 if (!allowNegative && value < 0) { 162 ret = false; 163 } 164 } else { 165 ret = false; 166 } 167 return ret; 168 } 169 }, 170 'real': { 171 characterMasking: /[\d\.,\-\+e]/i, 172 regExpFilter: /^[\-\+]?\d(?:|\.,\d{0,2})|(?:|e{0,1}[\-\+]?\d{0,})$/i, 173 validation: function (value, options) { 174 var regExp = /^[\+\-]?[0-9]+([\.,][0-9]+)?([eE]{0,1}[\-\+]?[0-9]+)?$/; 175 if (!regExp.test(value)) { 176 return false; 177 } 178 var ret = parseFloat(value); 179 if (isNaN(ret)) { 180 ret = false; 181 } 182 return ret; 183 } 184 }, 185 'currency': { 186 formats: { 187 'dot_comma': { 188 characterMasking: /[\d\.\,\-\+\$]/, 189 regExpFilter: /^[\-\+]?(?:[\d\.]*)+(|\,\d{0,2})$/, 190 validation: function(value, options) { 191 var ret = false;
192 //2 or no digits after the comma 193 if (/^(\-|\+)?\d{1,3}(?:\.\d{3})*(?:\,\d{2}|)$/.test(value) || /^(\-|\+)?\d+(?:\,\d{2}|)$/.test(value)) { 194 value = value.toString().replace(/\./gi, '').replace(/\,/, '.'); 195 ret = parseFloat(value); 196 } 197 return ret; 198 } 199 }, 200 'comma_dot': { 201 characterMasking: /[\d\.\,\-\+\$]/, 202 regExpFilter: /^[\-\+]?(?:[\d\,]*)+(|\.\d{0,2})$/, 203 validation: function(value, options) { 204 var ret = false; 205 //2 or no digits after the comma 206 if (/^(\-|\+)?\d{1,3}(?:\,\d{3})*(?:\.\d{2}|)$/.test(value) || /^(\-|\+)?\d+(?:\.\d{2}|)$/.test(value)) { 207 value = value.toString().replace(/\,/gi, ''); 208 ret = parseFloat(value); 209 } 210 return ret; 211 } 212 } 213 } 214 }, 215 'email': { 216 characterMasking: /[^\s]/, 217 validation: function(value, options) { 218 var rx = /^[\w\.-]+@[\w\.-]+\.\w+$/i; 219 return rx.test(value); 220 } 221 }, 222 'date': { 223 validation: function(value, options) { 224 var formatRegExp = /^([mdy]+)[\.\-\/\\\s]+([mdy]+)[\.\-\/\\\s]+([mdy]+)$/i; 225 var valueRegExp = this.dateValidationPattern; 226 var formatGroups = options.format.match(formatRegExp); 227 var valueGroups = value.match(valueRegExp); 228 if (formatGroups !== null && valueGroups !== null) { 229 var dayIndex = -1; 230 var monthIndex = -1; 231 var yearIndex = -1; 232 for (var i=1; i<formatGroups.length; i++) { 233 switch (formatGroups[i].toLowerCase()) { 234 case "dd": 235 dayIndex = i; 236 break; 237 case "mm": 238 monthIndex = i; 239 break; 240 case "yy": 241 case "yyyy": 242 yearIndex = i; 243 break; 244 } 245 } 246 if (dayIndex != -1 && monthIndex != -1 && yearIndex != -1) { 247 var maxDay = -1; 248 var theDay = parseInt(valueGroups[dayIndex], 10); 249 var theMonth = parseInt(valueGroups[monthIndex], 10); 250 var theYear = parseInt(valueGroups[yearIndex], 10); 251 252 // Check month value to be between 1..12 253 if (theMonth < 1 || theMonth > 12) { 254 return false; 255 } 256 257 // Calculate the maxDay according to the current month 258 switch (theMonth) { 259 case 1: // January 260 case 3: // March 261 case 5: // May 262 case 7: // July 263 case 8: // August 264 case 10: // October 265 case 12: // December 266 maxDay = 31; 267 break; 268 case 4: // April 269 case 6: // June 270 case 9: // September 271 case 11: // November 272 maxDay = 30; 273 break; 274 case 2: // February 275 if ((parseInt(theYear/4, 10) * 4 == theYear) && (theYear % 100 != 0 || theYear % 400 == 0)) { 276 maxDay = 29; 277 } else { 278 maxDay = 28; 279 } 280 break; 281 } 282 283 // Check day value to be between 1..maxDay 284 if (theDay < 1 || theDay > maxDay) { 285 return false; 286 } 287 288 // If successfull we'll return the date object 289 return (new Date(theYear, theMonth - 1, theDay)); //JavaScript requires a month between 0 and 11 290 } 291 } else { 292 return false; 293 } 294 } 295 }, 296 'time': { 297 validation: function(value, options) { 298 // HH:MM:SS T 299 var formatRegExp = /([hmst]+)/gi; 300 var valueRegExp = /(\d+|AM?|PM?)/gi; 301 var formatGroups = options.format.match(formatRegExp); 302 var valueGroups = value.match(valueRegExp); 303 //mast match and have same length 304 if (formatGroups !== null && valueGroups !== null) { 305 if (formatGroups.length != valueGroups.length) { 306 return false; 307 } 308 309 var hourIndex = -1; 310 var minuteIndex = -1; 311 var secondIndex = -1; 312 //T is AM or PM 313 var tIndex = -1; 314 var theHour = 0, theMinute = 0, theSecond = 0, theT = 'AM'; 315 for (var i=0; i<formatGroups.length; i++) { 316 switch (formatGroups[i].toLowerCase()) { 317 case "hh": 318 hourIndex = i; 319 break; 320 case "mm": 321 minuteIndex = i; 322 break; 323 case "ss": 324 secondIndex = i; 325 break; 326 case "t": 327 case "tt": 328 tIndex = i; 329 break; 330 } 331 } 332 if (hourIndex != -1) { 333 var theHour = parseInt(valueGroups[hourIndex], 10); 334 if (isNaN(theHour) || theHour > (formatGroups[hourIndex] == 'HH' ? 23 : 12 )) { 335 return false; 336 } 337 } 338 if (minuteIndex != -1) { 339 var theMinute = parseInt(valueGroups[minuteIndex], 10); 340 if (isNaN(theMinute) || theMinute > 59) { 341 return false;
342 } 343 } 344 if (secondIndex != -1) { 345 var theSecond = parseInt(valueGroups[secondIndex], 10); 346 if (isNaN(theSecond) || theSecond > 59) { 347 return false; 348 } 349 } 350 if (tIndex != -1) { 351 var theT = valueGroups[tIndex].toUpperCase(); 352 if ( 353 formatGroups[tIndex].toUpperCase() == 'TT' && !/^a|pm$/i.test(theT) || 354 formatGroups[tIndex].toUpperCase() == 'T' && !/^a|p$/i.test(theT) 355 ) { 356 return false; 357 } 358 } 359 var date = new Date(2000, 0, 1, theHour + (theT.charAt(0) == 'P'?12:0), theMinute, theSecond); 360 return date; 361 } else { 362 return false; 363 } 364 } 365 }, 366 'credit_card': { 367 characterMasking: /\d/, 368 validation: function(value, options) { 369 var regExp = null; 370 options.format = options.format || 'ALL'; 371 switch (options.format.toUpperCase()) { 372 case 'ALL': regExp = /^[3-6]{1}[0-9]{12,18}$/; break; 373 case 'VISA': regExp = /^4(?:[0-9]{12}|[0-9]{15})$/; break; 374 case 'MASTERCARD': regExp = /^5[1-5]{1}[0-9]{14}$/; break; 375 case 'AMEX': regExp = /^3(4|7){1}[0-9]{13}$/; break; 376 case 'DISCOVER': regExp = /^6011[0-9]{12}$/; break; 377 case 'DINERSCLUB': regExp = /^3(?:(0[0-5]{1}[0-9]{11})|(6[0-9]{12})|(8[0-9]{12}))$/; break; 378 } 379 if (!regExp.test(value)) { 380 return false; 381 } 382 var digits = []; 383 var j = 1, digit = ''; 384 for (var i = value.length - 1; i >= 0; i--) { 385 if ((j%2) == 0) { 386 digit = parseInt(value.charAt(i), 10) * 2; 387 digits[digits.length] = digit.toString().charAt(0); 388 if (digit.toString().length == 2) { 389 digits[digits.length] = digit.toString().charAt(1); 390 } 391 } else { 392 digit = value.charAt(i); 393 digits[digits.length] = digit; 394 } 395 j++; 396 } 397 var sum = 0; 398 for(i=0; i < digits.length; i++ ) { 399 sum += parseInt(digits[i], 10); 400 } 401 if ((sum%10) == 0) { 402 return true; 403 } 404 return false; 405 } 406 }, 407 'zip_code': { 408 formats: { 409 'zip_us9': { 410 pattern:'00000-0000' 411 }, 412 'zip_us5': { 413 pattern:'00000' 414 }, 415 'zip_uk': { 416 characterMasking: /[\dA-Z\s]/, 417 validation: function(value, options) { 418 //check one of the following masks 419 // AN NAA, ANA NAA, ANN NAA, AAN NAA, AANA NAA, AANN NAA 420 return /^[A-Z]{1,2}\d[\dA-Z]?\s?\d[A-Z]{2}$/.test(value); 421 } 422 }, 423 'zip_canada': { 424 characterMasking: /[\dA-Z\s]/, 425 pattern: 'A0A 0A0' 426 }, 427 'zip_custom': {} 428 } 429 }, 430 'phone_number': { 431 formats: { 432 //US phone number; 10 digits 433 'phone_us': { 434 pattern:'(000) 000-0000' 435 }, 436 'phone_custom': {} 437 } 438 }, 439 'social_security_number': { 440 pattern:'000-00-0000' 441 }, 442 'ip': { 443 characterMaskingFormats: { 444 'ipv4': /[\d\.]/i, 445 'ipv6_ipv4': /[\d\.\:A-F\/]/i, 446 'ipv6': /[\d\.\:A-F\/]/i 447 }, 448 validation: function (value, options) { 449 return Spry.Widget.ValidationTextField.validateIP(value, options.format); 450 } 451 }, 452 453 'url': { 454 characterMasking: /[^\s]/, 455 validation: function(value, options) { 456 //fix for ?ID=223429 and ?ID=223387 457 /* the following regexp matches components of an URI as specified in http://tools.ietf.org/html/rfc3986#page-51 page 51, Appendix B. 458 scheme = $2 459 authority = $4 460 path = $5 461 query = $7 462 fragment = $9 463 */ 464 var URI_spliter = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/; 465 var parts = value.match(URI_spliter); 466 if (parts && parts[4]) { 467 //encode each component of the domain name using Punycode encoding scheme: http://tools.ietf.org/html/rfc3492 468 var host = parts[4].split("."); 469 var punyencoded = ''; 470 for (var i=0; i<host.length; i++) { 471 punyencoded = Spry.Widget.Utils.punycode_encode(host[i], 64); 472 if (!punyencoded) { 473 return false; 474 } else { 475 if (punyencoded != (host[i] + "-")) { 476 host[i] = 'xn--' + punyencoded; 477 } 478 } 479 } 480 host = host .join("."); 481 //the encoded domain name is replaced into the original URL to be validated again later as URL 482 value = value.replace(URI_spliter, "$1//" + host + "$5$6$8"); 483 } 484 485 //fix for ?ID=223358 and ?ID=223594 486 //the following validates an URL using ABNF rules as defined in http://tools.ietf.org/html/rfc3986 , Appendix A., page 49 487 //except host which is extracted by match[1] and validated separately 488 /* 489 * userinfo= (?:(?:[a-z0-9\-\._~\!\$\&\'\(\)\*\+\,\;\=:]|%[0-9a-f]{2,2})*\@)? 490 * host= (?:((?:(?:[a-z0-9][a-z0-9\-]*[a-z0-9]|[a-z0-9])\.)*(?:[a-z][a-z0-9\-]*[a-z0-9]|[a-z])|(?:\[[^\]]*\])) 491 * pathname= (?:\/(?:[a-z0-9\-\._~\!\$\&\'\(\)\*\+\,\;\=\:\@]|%[0-9a-f]{2,2})*)* 492 * query= (?:\?(?:[a-z0-9\-\._~\!\$\&\'\(\)\*\+\,\;\=\:\@\/\?]|%[0-9a-f]{2,2})*)? 493 * anchor= (?:\#(?:[a-z0-9\-\._~\!\$\&\'\(\)\*\+\,\;\=\:\@\/\?]|%[0-9a-f]{2,2})*)? 494 */ 495 var regExp = /^(?:https?|ftp)\:\/\/(?:(?:[a-z0-9\-\._~\!\$\&\'\(\)\*\+\,\;\=:]|%[0-9a-f]{2,2})*\@)?(?:((?:(?:[a-z0-9][a-z0-9\-]*[a-z0-9]|[a-z0-9])\.)*(?:[a-z][a-z0-9\-]*[a-z0-9]|[a-z])|(?:\[[^\]]*\]))(?:\:[0-9]*)?)(?:\/(?:[a-z0-9\-\._~\!\$\&\'\(\)\*\+\,\;\=\:\@]|%[0-9a-f]{2,2})*)*(?:\?(?:[a-z0-9\-\._~\!\$\&\'\(\)\*\+\,\;\=\:\@\/\?]|%[0-9a-f]{2,2})*)?(?:\#(?:[a-z0-9\-\._~\!\$\&\'\(\)\*\+\,\;\=\:\@\/\?]|%[0-9a-f]{2,2})*)?$/i; 496
497 var valid = value.match(regExp); 498 if (valid) { 499 //extract the address from URL 500 var address = valid[1]; 501 502 if (address) { 503 if (address == '[]') { 504 return false; 505 } 506 if (address.charAt(0) == '[' ) { 507 //IPv6 address or IPv4 enclosed in square brackets 508 address = address.replace(/^\[|\]$/gi, ''); 509 return Spry.Widget.ValidationTextField.validateIP(address, 'ipv6_ipv4'); 510 } else { 511 if (/[^0-9\.]/.test(address)) { 512 return true; 513 } else { 514 //check if hostname is all digits and dots and then check for IPv4 515 return Spry.Widget.ValidationTextField.validateIP(address, 'ipv4'); 516 } 517 } 518 } else { 519 return true; 520 } 521 } else { 522 return false; 523 } 524 } 525 } 526}; 527 528/* 5292.2.1. Preferred 530x:x:x:x:x:x:x:x, where the 'x's are the hexadecimal values of the eight 16-bit pieces of the address. 531Examples: 532 FEDC:BA98:7654:3210:FEDC:BA98:7654:3210 533 1080:0:0:0:8:800:200C:417A 534Note that it is not necessary to write the leading zeros in an 535individual field, but there must be at least one numeral in every 536field (except for the case described in 2.2.2.). 537 5382.2.2. Compressed 539The use of "::" indicates multiple groups of 16-bits of zeros. 540The "::" can only appear once in an address. The "::" can also be 541used to compress the leading and/or trailing zeros in an address. 542 1080:0:0:0:8:800:200C:417A --> 1080::8:800:200C:417A 543 FF01:0:0:0:0:0:0:101 --> FF01::101 544 0:0:0:0:0:0:0:1 --> ::1 545 0:0:0:0:0:0:0:0 --> :: 546 5472.5.4 IPv6 Addresses with Embedded IPv4 Addresses 548 IPv4-compatible IPv6 address (tunnel IPv6 packets over IPv4 routing infrastructures) 549 ::0:129.144.52.38 550 IPv4-mapped IPv6 address (represent the addresses of IPv4-only nodes as IPv6 addresses) 551 ::ffff:129.144.52.38 552 553The text representation of IPv6 addresses and prefixes in Augmented BNF (Backus-Naur Form) [ABNF] for reference purposes. 554[ABNF http://tools.ietf.org/html/rfc2234] 555 IPv6address = hexpart [ ":" IPv4address ] 556 IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT 557 558 IPv6prefix = hexpart "/" 1*2DIGIT 559 560 hexpart = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ] 561 hexseq = hex4 *( ":" hex4) 562 hex4 = 1*4HEXDIG 563*/ 564Spry.Widget.ValidationTextField.validateIP = function (value, format) 565{ 566 var validIPv6Addresses = [ 567 //preferred 568 /^(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}(?:\/\d{1,3})?$/i, 569 570 //various compressed 571 /^[a-f0-9]{0,4}::(?:\/\d{1,3})?$/i, 572 /^:(?::[a-f0-9]{1,4}){1,6}(?:\/\d{1,3})?$/i, 573 /^(?:[a-f0-9]{1,4}:){1,6}:(?:\/\d{1,3})?$/i, 574 /^(?:[a-f0-9]{1,4}:)(?::[a-f0-9]{1,4}){1,6}(?:\/\d{1,3})?$/i, 575 /^(?:[a-f0-9]{1,4}:){2}(?::[a-f0-9]{1,4}){1,5}(?:\/\d{1,3})?$/i, 576 /^(?:[a-f0-9]{1,4}:){3}(?::[a-f0-9]{1,4}){1,4}(?:\/\d{1,3})?$/i, 577 /^(?:[a-f0-9]{1,4}:){4}(?::[a-f0-9]{1,4}){1,3}(?:\/\d{1,3})?$/i, 578 /^(?:[a-f0-9]{1,4}:){5}(?::[a-f0-9]{1,4}){1,2}(?:\/\d{1,3})?$/i, 579 /^(?:[a-f0-9]{1,4}:){6}(?::[a-f0-9]{1,4})(?:\/\d{1,3})?$/i, 580 581 582 //IPv6 mixes with IPv4 583 /^(?:[a-f0-9]{1,4}:){6}(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,3})?$/i, 584 /^:(?::[a-f0-9]{1,4}){0,4}:(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,3})?$/i, 585 /^(?:[a-f0-9]{1,4}:){1,5}:(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,3})?$/i, 586 /^(?:[a-f0-9]{1,4}:)(?::[a-f0-9]{1,4}){1,4}:(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,3})?$/i, 587 /^(?:[a-f0-9]{1,4}:){2}(?::[a-f0-9]{1,4}){1,3}:(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,3})?$/i, 588 /^(?:[a-f0-9]{1,4}:){3}(?::[a-f0-9]{1,4}){1,2}:(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,3})?$/i, 589 /^(?:[a-f0-9]{1,4}:){4}(?::[a-f0-9]{1,4}):(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{1,3})?$/i 590 ]; 591 var validIPv4Addresses = [ 592 //IPv4 593 /^(\d{1,3}\.){3}\d{1,3}$/i 594 ]; 595 var validAddresses = []; 596 if (format == 'ipv6' || format == 'ipv6_ipv4') { 597 validAddresses = validAddresses.concat(validIPv6Addresses); 598 } 599 if (format == 'ipv4' || format == 'ipv6_ipv4') { 600 validAddresses = validAddresses.concat(validIPv4Addresses); 601 } 602 603 var ret = false;
604 for (var i=0; i<validAddresses.length; i++) { 605 if (validAddresses[i].test(value)) { 606 ret = true; 607 break; 608 } 609 } 610 611 if (ret && value.indexOf(".") != -1) { 612 //if address contains IPv4 fragment, it must be valid; all 4 groups must be less than 256 613 var ipv4 = value.match(/:?(?:\d{1,3}\.){3}\d{1,3}/i); 614 if(!ipv4) { 615 return false; 616 } 617 ipv4 = ipv4[0].replace(/^:/, ''); 618 var pieces = ipv4.split('.'); 619 if (pieces.length != 4) { 620 return false; 621 } 622 var regExp = /^[\-\+]?\d*$/; 623 for (var i=0; i< pieces.length; i++) { 624 if (pieces[i] == '') { 625 return false; 626 } 627 var piece = parseInt(pieces[i], 10); 628 if (isNaN(piece) || piece > 255 || !regExp.test(pieces[i]) || pieces[i].length>3 || /^0{2,3}$/.test(pieces[i])) { 629 return false; 630 } 631 } 632 } 633 if (ret && value.indexOf("/") != -1) { 634 // if prefix-length is specified must be in [1-128] 635 var prefLen = value.match(/\/\d{1,3}$/); 636 if (!prefLen) return false; 637 var prefLenVal = parseInt(prefLen[0].replace(/^\//,''), 10); 638 if (isNaN(prefLenVal) || prefLenVal > 128 || prefLenVal < 1) { 639 return false; 640 } 641 } 642 return ret; 643}; 644 645Spry.Widget.ValidationTextField.onloadDidFire = false; 646Spry.Widget.ValidationTextField.loadQueue = []; 647 648Spry.Widget.ValidationTextField.prototype.isBrowserSupported = function() 649{ 650 return Spry.is.ie && Spry.is.v >= 5 && Spry.is.windows 651 || 652 Spry.is.mozilla && Spry.is.v >= 1.4 653 || 654 Spry.is.safari 655 || 656 Spry.is.opera && Spry.is.v >= 9; 657}; 658 659Spry.Widget.ValidationTextField.prototype.init = function(element, options) 660{ 661 this.element = this.getElement(element); 662 this.errors = 0; 663 this.flags = {locked: false, restoreSelection: true}; 664 this.options = {}; 665 this.event_handlers = []; 666 667 this.validClass = "textfieldValidState"; 668 this.focusClass = "textfieldFocusState"; 669 this.requiredClass = "textfieldRequiredState"; 670 this.hintClass = "textfieldHintState"; 671 this.invalidFormatClass = "textfieldInvalidFormatState"; 672 this.invalidRangeMinClass = "textfieldMinValueState"; 673 this.invalidRangeMaxClass = "textfieldMaxValueState"; 674 this.invalidCharsMinClass = "textfieldMinCharsState"; 675 this.invalidCharsMaxClass = "textfieldMaxCharsState"; 676 this.textfieldFlashTextClass = "textfieldFlashText"; 677 if (Spry.is.safari) { 678 this.flags.lastKeyPressedTimeStamp = 0; 679 } 680 681 switch (this.type) { 682 case 'phone_number':options.format = Spry.Widget.Utils.firstValid(options.format, 'phone_us');break; 683 case 'currency':options.format = Spry.Widget.Utils.firstValid(options.format, 'comma_dot');break; 684 case 'zip_code':options.format = Spry.Widget.Utils.firstValid(options.format, 'zip_us5');break; 685 case 'date': 686 options.format = Spry.Widget.Utils.firstValid(options.format, 'mm/dd/yy'); 687 break; 688 case 'time': 689 options.format = Spry.Widget.Utils.firstValid(options.format, 'HH:mm'); 690 options.pattern = options.format.replace(/[hms]/gi, "0").replace(/TT/gi, 'AM').replace(/T/gi, 'A'); 691 break; 692 case 'ip': 693 options.format = Spry.Widget.Utils.firstValid(options.format, 'ipv4'); 694 options.characterMasking = Spry.Widget.ValidationTextField.ValidationDescriptors[this.type].characterMaskingFormats[options.format]; 695 break; 696 } 697 698 //retrieve the validation type descriptor to be used with this instance (base on type and format) 699 //widgets may have different validations depending on format (like zip_code with formats) 700 var validationDescriptor = {}; 701 if (options.format && Spry.Widget.ValidationTextField.ValidationDescriptors[this.type].formats) { 702 if (Spry.Widget.ValidationTextField.ValidationDescriptors[this.type].formats[options.format]) { 703 Spry.Widget.Utils.setOptions(validationDescriptor, Spry.Widget.ValidationTextField.ValidationDescriptors[this.type].formats[options.format]); 704 } 705 } else { 706 Spry.Widget.Utils.setOptions(validationDescriptor, Spry.Widget.ValidationTextField.ValidationDescriptors[this.type]); 707 } 708 709 //set default values for some parameters which were not aspecified 710 options.useCharacterMasking = Spry.Widget.Utils.firstValid(options.useCharacterMasking, false); 711 options.hint = Spry.Widget.Utils.firstValid(options.hint, ''); 712 options.isRequired = Spry.Widget.Utils.firstValid(options.isRequired, true); 713 options.additionalError = Spry.Widget.Utils.firstValid(options.additionalError, false); 714 if (options.additionalError) 715 options.additionalError = this.getElement(options.additionalError); 716 717 //set widget validation parameters 718 //get values from validation type descriptor 719 //use the user specified values, if defined 720 options.characterMasking = Spry.Widget.Utils.firstValid(options.characterMasking, validationDescriptor.characterMasking); 721 options.regExpFilter = Spry.Widget.Utils.firstValid(options.regExpFilter, validationDescriptor.regExpFilter); 722 options.pattern = Spry.Widget.Utils.firstValid(options.pattern, validationDescriptor.pattern); 723 options.validation = Spry.Widget.Utils.firstValid(options.validation, validationDescriptor.validation); 724 if (typeof options.validation == 'string') { 725 options.validation = eval(options.validation); 726 } 727 728 options.minValue = Spry.Widget.Utils.firstValid(options.minValue, validationDescriptor.minValue); 729 options.maxValue = Spry.Widget.Utils.firstValid(options.maxValue, validationDescriptor.maxValue); 730 731 options.minChars = Spry.Widget.Utils.firstValid(options.minChars, validationDescriptor.minChars); 732 options.maxChars = Spry.Widget.Utils.firstValid(options.maxChars, validationDescriptor.maxChars); 733 734 Spry.Widget.Utils.setOptions(this, options); 735 Spry.Widget.Utils.setOptions(this.options, options); 736}; 737 738Spry.Widget.ValidationTextField.prototype.destroy = function() { 739 if (this.event_handlers) 740 for (var i=0; i<this.event_handlers.length; i++) { 741 Spry.Widget.Utils.removeEventListener(this.event_handlers[i][0], this.event_handlers[i][1], this.event_handlers[i][2], false); 742 } 743 try { delete this.element; } catch(err) {} 744 try { delete this.input; } catch(err) {} 745 try { delete this.form; } catch(err) {} 746 try { delete this.event_handlers; } catch(err) {} 747 try { this.selection.destroy(); } catch(err) {} 748 try { delete this.selection; } catch(err) {} 749 750 var q = Spry.Widget.Form.onSubmitWidgetQueue; 751 var qlen = q.length; 752 for (var i = 0; i < qlen; i++) { 753 if (q[i] == this) { 754 q.splice(i, 1); 755 break; 756 } 757 } 758}; 759 760Spry.Widget.ValidationTextField.prototype.attachBehaviors = function() 761{ 762 if (this.element) { 763 if (this.element.nodeName == "INPUT") { 764 this.input = this.element; 765 } else { 766 this.input = Spry.Widget.Utils.getFirstChildWithNodeNameAtAnyLevel(this.element, "INPUT"); 767 } 768 } 769 770 if (this.input) { 771 if (this.maxChars) { 772 this.input.removeAttribute("maxLength"); 773 } 774 this.putHint(); 775 this.compilePattern();
776 if (this.type == 'date') { 777 this.compileDatePattern(); 778 } 779 this.input.setAttribute("AutoComplete", "off"); 780 this.selection = new Spry.Widget.SelectionDescriptor(this.input); 781 this.oldValue = this.input.value; 782 783 var self = this; 784 this.event_handlers = []; 785 786 this.event_handlers.push([this.input, "keydown", function(e) { if (self.isDisabled()) return true; return self.onKeyDown(e || event); }]); 787 this.event_handlers.push([this.input, "keypress", function(e) { if (self.isDisabled()) return true; return self.onKeyPress(e || event); }]); 788 if (Spry.is.opera) { 789 this.event_handlers.push([this.input, "keyup", function(e) { if (self.isDisabled()) return true; return self.onKeyUp(e || event); }]); 790 } 791 792 this.event_handlers.push([this.input, "focus", function(e) { if (self.isDisabled()) return true; return self.onFocus(e || event); }]); 793 this.event_handlers.push([this.input, "blur", function(e) { if (self.isDisabled()) return true; return self.onBlur(e || event); }]); 794 795 this.event_handlers.push([this.input, "mousedown", function(e) { if (self.isDisabled()) return true; return self.onMouseDown(e || event); }]); 796 797 var changeEvent = 798 Spry.is.mozilla || Spry.is.opera || Spry.is.safari?"input": 799 Spry.is.ie?"propertychange": 800 "change"; 801 this.event_handlers.push([this.input, changeEvent, function(e) { if (self.isDisabled()) return true; return self.onChange(e || event); }]); 802 803 if (Spry.is.mozilla || Spry.is.safari) { 804 //oninput event on mozilla does not fire ondragdrop 805 this.event_handlers.push([this.input, "dragdrop", function(e) { if (self.isDisabled()) return true; self.removeHint();return self.onChange(e || event); }]); 806 } else if (Spry.is.ie){ 807 //ondrop&onpropertychange crash on IE 808 this.event_handlers.push([this.input, "drop", function(e) { if (self.isDisabled()) return true; return self.onDrop(e || event); }]); 809 } 810 811 for (var i=0; i<this.event_handlers.length; i++) { 812 Spry.Widget.Utils.addEventListener(this.event_handlers[i][0], this.event_handlers[i][1], this.event_handlers[i][2], false); 813 } 814 815 // submit 816 this.form = Spry.Widget.Utils.getFirstParentWithNodeName(this.input, "FORM"); 817 if (this.form) { 818 // if no "onSubmit" handler has been attached to the current form, attach one 819 if (!this.form.attachedSubmitHandler && !this.form.onsubmit) { 820 this.form.onsubmit = function(e) { e = e || event; return Spry.Widget.Form.onSubmit(e, e.srcElement || e.currentTarget) }; 821 this.form.attachedSubmitHandler = true; 822 } 823 if (!this.form.attachedResetHandler) { 824 Spry.Widget.Utils.addEventListener(this.form, "reset", function(e) { e = e || event; return Spry.Widget.Form.onReset(e, e.srcElement || e.currentTarget) }, false); 825 this.form.attachedResetHandler = true; 826 } 827 // add the currrent widget to the "onSubmit" check queue; 828 Spry.Widget.Form.onSubmitWidgetQueue.push(this); 829 } 830 } 831}; 832 833Spry.Widget.ValidationTextField.prototype.isDisabled = function() { 834 return this.input && (this.input.disabled || this.input.readOnly) || !this.input; 835}; 836 837Spry.Widget.ValidationTextField.prototype.getElement = function(ele) 838{ 839 if (ele && typeof ele == "string") 840 return document.getElementById(ele); 841 return ele; 842}; 843 844Spry.Widget.ValidationTextField.addLoadListener = function(handler) 845{ 846 if (typeof window.addEventListener != 'undefined') 847 window.addEventListener('load', handler, false); 848 else if (typeof document.addEventListener != 'undefined') 849 document.addEventListener('load', handler, false); 850 else if (typeof window.attachEvent != 'undefined') 851 window.attachEvent('onload', handler); 852}; 853 854Spry.Widget.ValidationTextField.processLoadQueue = function(handler) 855{ 856 Spry.Widget.ValidationTextField.onloadDidFire = true; 857 var q = Spry.Widget.ValidationTextField.loadQueue; 858 var qlen = q.length; 859 for (var i = 0; i < qlen; i++) 860 q[i].attachBehaviors(); 861}; 862 863Spry.Widget.ValidationTextField.addLoadListener(Spry.Widget.ValidationTextField.processLoadQueue); 864Spry.Widget.ValidationTextField.addLoadListener(function(){ 865 Spry.Widget.Utils.addEventListener(window, "unload", Spry.Widget.Form.destroyAll, false); 866}); 867 868Spry.Widget.ValidationTextField.prototype.setValue = function(newValue) { 869 this.flags.locked = true; 870 this.input.value = newValue; 871 this.flags.locked = false;
872 this.oldValue = newValue; 873 if (!Spry.is.ie) { 874 this.onChange(); 875 } 876}; 877 878/** 879 * save the state of the input (selection and value) so we can revert to it 880 * should call this just before modifying the input value 881 */ 882Spry.Widget.ValidationTextField.prototype.saveState = function() 883{ 884 this.oldValue = this.input.value; 885 this.selection.update(); 886}; 887 888Spry.Widget.ValidationTextField.prototype.revertState = function(revertValue) 889{ 890 if (revertValue != this.input.value) { 891 this.input.readOnly = true; 892 this.input.value = revertValue; 893 this.input.readOnly = false; 894 if (Spry.is.safari && this.flags.active) { 895 this.input.focus(); 896 } 897 } 898 if (this.flags.restoreSelection) { 899 this.selection.moveTo(this.selection.start, this.selection.end); 900 } 901 902 this.redTextFlash(); 903}; 904 905Spry.Widget.ValidationTextField.prototype.removeHint = function() 906{ 907 if (this.flags.hintOn) { 908 this.input.value = ""; 909 this.flags.hintOn = false; 910 this.removeClassName(this.element, this.hintClass); 911 this.removeClassName(this.additionalError, this.hintClass); 912 } 913}; 914 915Spry.Widget.ValidationTextField.prototype.putHint = function() 916{ 917 if(this.hint && this.input && this.input.type == "text" && this.input.value == "") { 918 this.flags.hintOn = true; 919 this.input.value = this.hint; 920 this.addClassName(this.element, this.hintClass); 921 this.addClassName(this.additionalError, this.hintClass); 922 } 923}; 924 925Spry.Widget.ValidationTextField.prototype.redTextFlash = function() 926{ 927 var self = this; 928 this.addClassName(this.element, this.textfieldFlashTextClass); 929 setTimeout(function() { 930 self.removeClassName(self.element, self.textfieldFlashTextClass) 931 }, 100); 932}; 933 934Spry.Widget.ValidationTextField.prototype.doValidations = function(testValue, revertValue) 935{ 936 if (this.isDisabled()) return false; 937 938 if (this.flags.locked) { 939 return false; 940 } 941 942 if (testValue.length == 0 && !this.isRequired) { 943 this.errors = 0; 944 return false; 945 } 946 this.flags.locked = true; 947 948 var mustRevert = false; 949 var continueValidations = true; 950 if (!this.options.isRequired && testValue.length == 0) { 951 continueValidations = false; 952 } 953 954 var errors = 0; 955 var fixedValue = testValue; 956 957 //characterMasking - test if all characters are valid with the characterMasking (keyboard filter) 958 if (this.useCharacterMasking && this.characterMasking) { 959 for(var i=0; i<testValue.length; i++) { 960 if (!this.characterMasking.test(testValue.charAt(i))) { 961 errors = errors | Spry.Widget.ValidationTextField.ERROR_FORMAT; 962 fixedValue = revertValue; 963 mustRevert = true; 964 break; 965 } 966 } 967 } 968 969 //regExpFilter - character mask positioning (additional mask to restrict some characters only in some position) 970 if (!mustRevert && this.useCharacterMasking && this.regExpFilter) { 971 if (!this.regExpFilter.test(fixedValue)) { 972 errors = errors | Spry.Widget.ValidationTextField.ERROR_FORMAT; 973 mustRevert = true; 974 } 975 } 976 977 //pattern - testValue matches the pattern so far 978 if (!mustRevert && this.pattern) { 979 var currentRegExp = this.patternToRegExp(testValue.length); 980 if (!currentRegExp.test(testValue)) { 981 errors = errors | Spry.Widget.ValidationTextField.ERROR_FORMAT; 982 mustRevert = true; 983 } else if (this.patternLength != testValue.length) { 984 //testValue matches pattern so far, but it's not ok if it does not have the proper length 985 //do not revert, but should show the error 986 errors = errors | Spry.Widget.ValidationTextField.ERROR_FORMAT; 987 } 988 } 989 990 if (fixedValue == '') { 991 errors = errors | Spry.Widget.ValidationTextField.ERROR_REQUIRED; 992 } 993 994 if (!mustRevert && this.pattern && this.useCharacterMasking) { 995 var n = this.getAutoComplete(testValue.length); 996 if (n) { 997 fixedValue += n; 998 } 999 } 1000 1001 if(!mustRevert && this.minChars !== null && continueValidations) { 1002 if (testValue.length < this.minChars) { 1003 errors = errors | Spry.Widget.ValidationTextField.ERROR_CHARS_MIN; 1004 continueValidations = false; 1005 } 1006 } 1007 1008 if(!mustRevert && this.maxChars !== null && continueValidations) { 1009 if (testValue.length > this.maxChars) { 1010 errors = errors | Spry.Widget.ValidationTextField.ERROR_CHARS_MAX; 1011 continueValidations = false; 1012 } 1013 } 1014 1015 //validation - testValue passes widget validation function 1016 if (!mustRevert && this.validation && continueValidations) { 1017 var value = this.validation(fixedValue, this.options); 1018 if (false === value) { 1019 errors = errors | Spry.Widget.ValidationTextField.ERROR_FORMAT; 1020 continueValidations = false;
1021 } else { 1022 this.typedValue = value; 1023 } 1024 } 1025 1026 if(!mustRevert && this.validation && this.minValue !== null && continueValidations) { 1027 var minValue = this.validation(this.minValue.toString(), this.options); 1028 if (minValue !== false) { 1029 if (this.typedValue < minValue) { 1030 errors = errors | Spry.Widget.ValidationTextField.ERROR_RANGE_MIN; 1031 continueValidations = false; 1032 } 1033 } 1034 } 1035 1036 if(!mustRevert && this.validation && this.maxValue !== null && continueValidations) { 1037 var maxValue = this.validation(this.maxValue.toString(), this.options); 1038 if (maxValue !== false) { 1039 if( this.typedValue > maxValue) { 1040 errors = errors | Spry.Widget.ValidationTextField.ERROR_RANGE_MAX; 1041 continueValidations = false; 1042 } 1043 } 1044 } 1045 1046 //an invalid value was tested; must make sure it does not get inside the input 1047 if (this.useCharacterMasking && mustRevert) { 1048 this.revertState(revertValue); 1049 } 1050 1051 this.errors = errors; 1052 this.fixedValue = fixedValue; 1053 1054 this.flags.locked = false; 1055 1056 return mustRevert; 1057}; 1058 1059Spry.Widget.ValidationTextField.prototype.onChange = function(e) 1060{ 1061 if (Spry.is.opera && this.flags.operaRevertOnKeyUp) { 1062 return true; 1063 } 1064 if (Spry.is.ie && e && e.propertyName != 'value') { 1065 return true; 1066 } 1067 if (this.flags.drop) { 1068 //delay this if it's a drop operation 1069 var self = this; 1070 setTimeout(function() { 1071 self.flags.drop = false; 1072 self.onChange(null); 1073 }, 0); 1074 return; 1075 } 1076 1077 if (this.flags.hintOn) { 1078 return true; 1079 } 1080 1081 if (this.keyCode == 8 || this.keyCode == 46 ) { 1082 var mustRevert = this.doValidations(this.input.value, this.input.value); 1083 this.oldValue = this.input.value; 1084 if ((mustRevert || this.errors) && this.validateOn & Spry.Widget.ValidationTextField.ONCHANGE) { 1085 var self = this; 1086 setTimeout(function() {self.validate();}, 0); 1087 return true; 1088 } 1089 } 1090 1091 var mustRevert = this.doValidations(this.input.value, this.oldValue); 1092 /* Firefoxã®å ´åã¯ç¡å¹ã«ï¼æªå¤æã®æåã確å®ããããã°ã®ãããremoveClassã®ãã°ï¼ï¼ */ 1093 //if ((!mustRevert || this.errors) && this.validateOn & Spry.Widget.ValidationTextField.ONCHANGE) { 1094 if (!Spry.is.mozilla && (!mustRevert || this.errors) && this.validateOn & Spry.Widget.ValidationTextField.ONCHANGE) { 1095 var self = this; 1096 setTimeout(function() {self.validate();}, 0); 1097 } 1098 return true; 1099}; 1100 1101Spry.Widget.ValidationTextField.prototype.onKeyUp = function(e) { 1102 if (this.flags.operaRevertOnKeyUp) { 1103 this.setValue(this.oldValue); 1104 Spry.Widget.Utils.stopEvent(e); 1105 this.selection.moveTo(this.selection.start, this.selection.start); 1106 this.flags.operaRevertOnKeyUp = false; 1107 return false; 1108 } 1109 if (this.flags.operaPasteOperation) { 1110 window.clearInterval(this.flags.operaPasteOperation); 1111 this.flags.operaPasteOperation = null; 1112 } 1113}; 1114 1115Spry.Widget.ValidationTextField.prototype.operaPasteMonitor = function() { 1116 if (this.input.value != this.oldValue) { 1117 var mustRevert = this.doValidations(this.input.value, this.input.value); 1118 if (mustRevert) { 1119 this.setValue(this.oldValue); 1120 this.selection.moveTo(this.selection.start, this.selection.start); 1121 } else { 1122 this.onChange(); 1123 } 1124 } 1125}; 1126 1127 1128Spry.Widget.ValidationTextField.prototype.compileDatePattern = function () 1129{ 1130 var dateValidationPatternString = ""; 1131 var groupPatterns = []; 1132 var fullGroupPatterns = []; 1133 var autocompleteCharacters = []; 1134 1135 1136 var formatRegExp = /^([mdy]+)([\.\-\/\\\s]+)([mdy]+)([\.\-\/\\\s]+)([mdy]+)$/i; 1137 var formatGroups = this.options.format.match(formatRegExp); 1138 if (formatGroups !== null) { 1139 for (var i=1; i<formatGroups.length; i++) { 1140 switch (formatGroups[i].toLowerCase()) { 1141 case "dd": 1142 groupPatterns[i-1] = "\\d{1,2}"; 1143 fullGroupPatterns[i-1] = "\\d\\d"; 1144 dateValidationPatternString += "(" + groupPatterns[i-1] + ")"; 1145 autocompleteCharacters[i-1] = null; 1146 break; 1147 case "mm": 1148 groupPatterns[i-1] = "\\d{1,2}"; 1149 fullGroupPatterns[i-1] = "\\d\\d"; 1150 dateValidationPatternString += "(" + groupPatterns[i-1] + ")"; 1151 autocompleteCharacters[i-1] = null; 1152 break; 1153 case "yy": 1154 groupPatterns[i-1] = "\\d{1,2}"; 1155 fullGroupPatterns[i-1] = "\\d\\d"; 1156 dateValidationPatternString += "(\\d\\d)"; 1157 autocompleteCharacters[i-1] = null; 1158 break; 1159 case "yyyy": 1160 groupPatterns[i-1] = "\\d{1,4}"; 1161 fullGroupPatterns[i-1] = "\\d\\d\\d\\d"; 1162 dateValidationPatternString += "(\\d\\d\\d\\d)"; 1163 autocompleteCharacters[i-1] = null; 1164 break; 1165 default: 1166 groupPatterns[i-1] = fullGroupPatterns[i-1] = Spry.Widget.ValidationTextField.regExpFromChars(formatGroups[i]); 1167 dateValidationPatternString += "["+ groupPatterns[i-1] + "]"; 1168 autocompleteCharacters[i-1] = formatGroups[i]; 1169 } 1170 } 1171 } 1172 this.dateValidationPattern = new RegExp("^" + dateValidationPatternString + "$" , ""); 1173 this.dateAutocompleteCharacters = autocompleteCharacters; 1174 this.dateGroupPatterns = groupPatterns; 1175 this.dateFullGroupPatterns = fullGroupPatterns; 1176 this.lastDateGroup = formatGroups.length-2; 1177}; 1178 1179Spry.Widget.ValidationTextField.prototype.getRegExpForGroup = function (group) 1180{ 1181 var ret = '^'; 1182 for (var j = 0; j <= group; j++) ret += this.dateGroupPatterns[j]; 1183 ret += '$'; 1184 return new RegExp(ret, ""); 1185}; 1186 1187Spry.Widget.ValidationTextField.prototype.getRegExpForFullGroup = function (group) 1188{ 1189 var ret = '^'; 1190 for (var j = 0; j < group; j++) ret += this.dateGroupPatterns[j]; 1191 ret += this.dateFullGroupPatterns[group]; 1192 return new RegExp(ret, ""); 1193}; 1194 1195Spry.Widget.ValidationTextField.prototype.getDateGroup = function(value, pos) 1196{ 1197 if (pos == 0) return 0; 1198 var test_value = value.substring(0, pos); 1199 for (var i=0; i <= this.lastDateGroup; i++) 1200 if (this.getRegExpForGroup(i).test(test_value)) return i; 1201 return -1; 1202}; 1203 1204 1205Spry.Widget.ValidationTextField.prototype.isDateGroupFull = function(value, group) 1206{ 1207 return this.getRegExpForFullGroup(group).test(value); 1208}; 1209 1210Spry.Widget.ValidationTextField.prototype.isValueValid = function(value, pos, group) 1211{ 1212 var test_value = value.substring(0, pos); 1213 return this.getRegExpForGroup(group).test(test_value); 1214}; 1215 1216 1217Spry.Widget.ValidationTextField.prototype.isPositionAtEndOfGroup = function (value, pos, group) 1218{ 1219 var test_value = value.substring(0, pos); 1220 return this.getRegExpForFullGroup(group).test(test_value); 1221}; 1222 1223Spry.Widget.ValidationTextField.prototype.nextDateDelimiterExists = function (value, pos, group) 1224{ 1225 var autocomplete = this.dateAutocompleteCharacters[group+1]; 1226 if (value.length < pos + autocomplete.length) 1227 return false;
1228 else 1229 { 1230 var test_value = value.substring(pos, pos+autocomplete.length); 1231 if (test_value == autocomplete) 1232 return true; 1233 } 1234 return false; 1235}; 1236 1237 1238 1239Spry.Widget.ValidationTextField.prototype.onKeyPress = function(e) 1240{ 1241 if (this.flags.skp) { 1242 this.flags.skp = false; 1243 Spry.Widget.Utils.stopEvent(e); 1244 return false; 1245 } 1246 1247 if (e.ctrlKey || e.metaKey || !this.useCharacterMasking) { 1248 return true; 1249 } 1250/* 1251 if (Spry.is.safari) { 1252 if ( (e.timeStamp - this.flags.lastKeyPressedTimeStamp)<10 ) { 1253 return true; 1254 } 1255 this.flags.lastKeyPressedTimeStamp = e.timeStamp; 1256 } 1257*/ 1258 if (Spry.is.opera && this.flags.operaRevertOnKeyUp) { 1259 Spry.Widget.Utils.stopEvent(e); 1260 return false; 1261 } 1262 1263 if (this.keyCode == 8 || this.keyCode == 46) { 1264 var mr = this.doValidations(this.input.value, this.input.value); 1265 if (mr) { 1266 return true; 1267 } 1268 } 1269 1270 var pressed = Spry.Widget.Utils.getCharacterFromEvent(e); 1271 1272 if (pressed && this.characterMasking) { 1273 if (!this.characterMasking.test(pressed)) { 1274 Spry.Widget.Utils.stopEvent(e); 1275 this.redTextFlash(); 1276 return false; 1277 } 1278 } 1279 1280 if(pressed && this.pattern) { 1281 var currentPatternChar = this.patternCharacters[this.selection.start]; 1282 if (/[ax]/i.test(currentPatternChar)) { 1283 //convert the entered character to the pattern character case 1284 if (currentPatternChar.toLowerCase() == currentPatternChar) { 1285 pressed = pressed.toLowerCase(); 1286 } else { 1287 pressed = pressed.toUpperCase(); 1288 } 1289 } 1290 1291 var autocomplete = this.getAutoComplete(this.selection.start); 1292 if (this.selection.start == this.oldValue.length) { 1293 if (this.oldValue.length < this.patternLength) { 1294 if (autocomplete) { 1295 Spry.Widget.Utils.stopEvent(e); 1296 var futureValue = this.oldValue.substring(0, this.selection.start) + autocomplete + pressed; 1297 var mustRevert = this.doValidations(futureValue, this.oldValue); 1298 if (!mustRevert) { 1299 this.setValue(this.fixedValue); 1300 this.selection.moveTo(this.fixedValue.length, this.fixedValue.length); 1301 } else { 1302 this.setValue(this.oldValue.substring(0, this.selection.start) + autocomplete); 1303 this.selection.moveTo(this.selection.start + autocomplete.length, this.selection.start + autocomplete.length); 1304 } 1305 return false; 1306 } 1307 } else { 1308 Spry.Widget.Utils.stopEvent(e); 1309 this.setValue(this.input.value); 1310 return false; 1311 } 1312 } else if (autocomplete) { 1313 Spry.Widget.Utils.stopEvent(e); 1314 this.selection.moveTo(this.selection.start + autocomplete.length, this.selection.start + autocomplete.length); 1315 return false; 1316 } 1317 1318 Spry.Widget.Utils.stopEvent(e); 1319 1320 var futureValue = this.oldValue.substring(0, this.selection.start) + pressed + this.oldValue.substring(this.selection.start + 1); 1321 var mustRevert = this.doValidations(futureValue, this.oldValue); 1322 1323 if (!mustRevert) { 1324 autocomplete = this.getAutoComplete(this.selection.start + 1); 1325 this.setValue(this.fixedValue); 1326 this.selection.moveTo(this.selection.start + 1 + autocomplete.length, this.selection.start + 1 + autocomplete.length); 1327 } else { 1328 this.selection.moveTo(this.selection.start, this.selection.start); 1329 } 1330 1331 return false; 1332 } 1333 1334 1335 if (pressed && this.type == 'date' && this.useCharacterMasking) 1336 { 1337 var group = this.getDateGroup(this.oldValue, this.selection.start); 1338 if (group != -1) { 1339 Spry.Widget.Utils.stopEvent(e); 1340 if ( (group % 2) !=0 ) 1341 group ++; 1342 1343 if (this.isDateGroupFull(this.oldValue, group)) 1344 { 1345 if(this.isPositionAtEndOfGroup(this.oldValue, this.selection.start, group)) 1346 { 1347 if(group == this.lastDateGroup) 1348 { 1349 this.redTextFlash(); return false; 1350 } 1351 else 1352 { 1353 // add or jump over autocomplete delimiter 1354 var autocomplete = this.dateAutocompleteCharacters[group+1]; 1355 1356 if (this.nextDateDelimiterExists(this.oldValue, this.selection.start, group)) 1357 { 1358 var autocomplete = this.dateAutocompleteCharacters[group+1]; 1359 1360 this.selection.moveTo(this.selection.start + autocomplete.length, this.selection.start + autocomplete.length); 1361 if (pressed == autocomplete) 1362 return false; 1363 1364 if (this.isDateGroupFull(this.oldValue, group+2)) 1365 // need to overwrite first char in the next digit group 1366 futureValue = this.oldValue.substring(0, this.selection.start) + pressed + this.oldValue.substring(this.selection.start + 1); 1367 else 1368 futureValue = this.oldValue.substring(0, this.selection.start) + pressed + this.oldValue.substring(this.selection.start); 1369 1370 if (!this.isValueValid(futureValue, this.selection.start + 1, group +2 )) 1371 { 1372 this.redTextFlash(); return false; 1373 } 1374 else 1375 { 1376 this.setValue (futureValue); 1377 this.selection.moveTo(this.selection.start + 1, this.selection.start + 1); 1378 } 1379 return false; 1380 } 1381 else 1382 { 1383 var autocomplete = this.dateAutocompleteCharacters[group+1]; 1384 1385 var insertedValue = autocomplete + pressed; 1386 futureValue = this.oldValue.substring(0, this.selection.start) + insertedValue + this.oldValue.substring(this.selection.start); 1387 if (!this.isValueValid(futureValue, this.selection.start + insertedValue.length, group +2 )) 1388 { 1389 // block this type 1390 insertedValue = autocomplete; 1391 futureValue = this.oldValue.substring(0, this.selection.start) + insertedValue + this.oldValue.substring(this.selection.start); 1392 this.setValue (futureValue); 1393 this.selection.moveTo(this.selection.start + insertedValue.length, this.selection.start + insertedValue.length); 1394 this.redTextFlash(); return false;
1395 } 1396 else 1397 { 1398 this.setValue (futureValue); 1399 this.selection.moveTo(this.selection.start + insertedValue.length, this.selection.start + insertedValue.length); 1400 return false; 1401 } 1402 } 1403 1404 } 1405 } 1406 else 1407 { 1408 // it's not the end of the full digits group 1409 1410 // overwrite 1411 var movePosition = 1; 1412 futureValue = this.oldValue.substring(0, this.selection.start) + pressed + this.oldValue.substring(this.selection.start + 1); 1413 if (!this.isValueValid(futureValue, this.selection.start + 1, group)) 1414 { 1415 this.redTextFlash(); return false; 1416 } 1417 else 1418 { 1419 if(this.isPositionAtEndOfGroup(futureValue, this.selection.start+1, group)) 1420 { 1421 if (group != this.lastDateGroup) 1422 { 1423 if (this.nextDateDelimiterExists(futureValue, this.selection.start + 1, group)) 1424 { 1425 var autocomplete = this.dateAutocompleteCharacters[group+1]; 1426 movePosition = 1 + autocomplete.length; 1427 } 1428 else 1429 { 1430 var autocomplete = this.dateAutocompleteCharacters[group+1]; 1431 futureValue = this.oldValue.substring(0, this.selection.start) + pressed + autocomplete + this.oldValue.substring(this.selection.start + 1); 1432 movePosition = 1 + autocomplete.length; 1433 } 1434 } 1435 } 1436 this.setValue (futureValue); 1437 this.selection.moveTo(this.selection.start + movePosition, this.selection.start + movePosition); 1438 return false; 1439 } 1440 } 1441 } 1442 else 1443 { 1444 // date group is not full 1445 // insert 1446 futureValue = this.oldValue.substring(0, this.selection.start) + pressed + this.oldValue.substring(this.selection.start); 1447 var movePosition = 1; 1448 if (!this.isValueValid(futureValue, this.selection.start + 1, group) && !this.isValueValid(futureValue, this.selection.start + 1, group+1)) 1449 { 1450 this.redTextFlash(); return false; 1451 } 1452 else 1453 { 1454 var autocomplete = this.dateAutocompleteCharacters[group+1]; 1455 if (pressed == autocomplete) 1456 { 1457 if (this.nextDateDelimiterExists(this.oldValue, this.selection.start, group)) 1458 { 1459 futureValue = this.oldValue; 1460 movePosition = 1; 1461 } 1462 } 1463 else 1464 { 1465 if(this.isPositionAtEndOfGroup(futureValue, this.selection.start+1, group)) 1466 { 1467 if (group != this.lastDateGroup) 1468 { 1469 if (this.nextDateDelimiterExists(futureValue, this.selection.start + 1, group)) 1470 { 1471 var autocomplete = this.dateAutocompleteCharacters[group+1]; 1472 movePosition = 1 + autocomplete.length; 1473 } 1474 else 1475 { 1476 var autocomplete = this.dateAutocompleteCharacters[group+1]; 1477 futureValue = this.oldValue.substring(0, this.selection.start) + pressed + autocomplete + this.oldValue.substring(this.selection.start + 1); 1478 movePosition = 1 + autocomplete.length; 1479 } 1480 } 1481 } 1482 } 1483 this.setValue (futureValue); 1484 this.selection.moveTo(this.selection.start + movePosition, this.selection.start + movePosition); 1485 return false; 1486 } 1487 } 1488 } 1489 return false; 1490 } 1491 1492}; 1493 1494Spry.Widget.ValidationTextField.prototype.onKeyDown = function(e) 1495{ 1496 this.saveState(); 1497 this.keyCode = e.keyCode; 1498 1499 if (Spry.is.opera) { 1500 if (this.flags.operaPasteOperation) { 1501 window.clearInterval(this.flags.operaPasteOperation); 1502 this.flags.operaPasteOperation = null; 1503 } 1504 if (e.ctrlKey) { 1505 var pressed = Spry.Widget.Utils.getCharacterFromEvent(e); 1506 if (pressed && 'vx'.indexOf(pressed.toLowerCase()) != -1) { 1507 var self = this; 1508 this.flags.operaPasteOperation = window.setInterval(function() { self.operaPasteMonitor();}, 1); 1509 return true; 1510 } 1511 } 1512 } 1513 1514 if (this.keyCode != 8 && this.keyCode != 46 && Spry.Widget.Utils.isSpecialKey(e)) { 1515 return true; 1516 } 1517 if (this.keyCode == 8 || this.keyCode == 46 ) { 1518 var mr = this.doValidations(this.input.value, this.input.value); 1519 if (mr) { 1520 return true; 1521 } 1522 } 1523 1524 //DELETE 1525 if (this.useCharacterMasking && this.pattern && this.keyCode == 46) { 1526 if (e.ctrlKey) { 1527 //delete from selection until end 1528 this.setValue(this.input.value.substring(0, this.selection.start)); 1529 } else if (this.selection.end == this.input.value.length || this.selection.start == this.input.value.length-1){ 1530 //allow key if selection is at end (will delete selection) 1531 return true; 1532 } else { 1533 this.flags.operaRevertOnKeyUp = true; 1534 } 1535 if (Spry.is.mozilla && Spry.is.mac) { 1536 this.flags.skp = true; 1537 } 1538 Spry.Widget.Utils.stopEvent(e); 1539 return false;
1540 } 1541 1542 //BACKSPACE 1543 if (this.useCharacterMasking && this.pattern && !e.ctrlKey && this.keyCode == 8) { 1544 if (this.selection.start == this.input.value.length) { 1545 //delete with BACKSPACE from the end of the input value only 1546 var n = this.getAutoComplete(this.selection.start, -1); 1547 this.setValue(this.input.value.substring(0, this.input.value.length - (Spry.is.opera?0:1) - n.length)); 1548 if (Spry.is.opera) { 1549 //cant stop the event on Opera, we'll just preserve the selection so delete will act on it 1550 this.selection.start = this.selection.start - 1 - n.length; 1551 this.selection.end = this.selection.end - 1 - n.length; 1552 } 1553 } else if (this.selection.end == this.input.value.length){ 1554 //allow BACKSPACE if selection is at end (will delete selection) 1555 return true; 1556 } else { 1557 this.flags.operaRevertOnKeyUp = true; 1558 } 1559 if (Spry.is.mozilla && Spry.is.mac) { 1560 this.flags.skp = true; 1561 } 1562 Spry.Widget.Utils.stopEvent(e); 1563 return false; 1564 } 1565 1566 return true; 1567}; 1568 1569Spry.Widget.ValidationTextField.prototype.onMouseDown = function(e) 1570{ 1571 if (this.flags.active) { 1572 //mousedown fires before focus 1573 //avoid double saveState on first focus by mousedown by checking if the control has focus 1574 //do nothing if it's not focused because saveState will be called onfocus 1575 this.saveState(); 1576 } 1577}; 1578 1579Spry.Widget.ValidationTextField.prototype.onDrop = function(e) 1580{ 1581 //mark that a drop operation is in progress to avoid race conditions with event handlers for other events 1582 //especially onchange and onfocus 1583 this.flags.drop = true; 1584 this.removeHint(); 1585 this.saveState(); 1586 this.flags.active = true; 1587 this.addClassName(this.element, this.focusClass); 1588 this.addClassName(this.additionalError, this.focusClass); 1589}; 1590 1591Spry.Widget.ValidationTextField.prototype.onFocus = function(e) 1592{ 1593 if (this.flags.drop) { 1594 return; 1595 } 1596 this.removeHint(); 1597 1598 if (this.pattern && this.useCharacterMasking) { 1599 var autocomplete = this.getAutoComplete(this.selection.start); 1600 this.setValue(this.input.value + autocomplete); 1601 this.selection.moveTo(this.input.value.length, this.input.value.length); 1602 } 1603 1604 this.saveState(); 1605 this.flags.active = true; 1606 this.addClassName(this.element, this.focusClass); 1607 this.addClassName(this.additionalError, this.focusClass); 1608}; 1609 1610Spry.Widget.ValidationTextField.prototype.onBlur = function(e) 1611{ 1612 this.flags.active = false; 1613 this.removeClassName(this.element, this.focusClass); 1614 this.removeClassName(this.additionalError, this.focusClass); 1615 this.flags.restoreSelection = false; 1616 var mustRevert = this.doValidations(this.input.value, this.input.value); 1617 this.flags.restoreSelection = true; 1618 1619 if (this.validateOn & Spry.Widget.ValidationTextField.ONBLUR) { 1620 this.validate(); 1621 } 1622 var self = this; 1623 setTimeout(function() {self.putHint();}, 10); 1624 return true; 1625}; 1626 1627Spry.Widget.ValidationTextField.prototype.compilePattern = function() { 1628 if (!this.pattern) { 1629 return; 1630 } 1631 var compiled = []; 1632 var regexps = []; 1633 var patternCharacters = []; 1634 var idx = 0; 1635 var c = '', p = ''; 1636 for (var i=0; i<this.pattern.length; i++) { 1637 c = this.pattern.charAt(i); 1638 if (p == '\\') { 1639 if (/[0ABXY\?]/i.test(c)) { 1640 regexps[idx - 1] = c; 1641 } else { 1642 regexps[idx - 1] = Spry.Widget.ValidationTextField.regExpFromChars(c); 1643 } 1644 compiled[idx - 1] = c; 1645 patternCharacters[idx - 1] = null; 1646 p = ''; 1647 continue; 1648 } 1649 regexps[idx] = Spry.Widget.ValidationTextField.regExpFromChars(c); 1650 if (/[0ABXY\?]/i.test(c)) { 1651 compiled[idx] = null; 1652 patternCharacters[idx] = c; 1653 } else if (c == '\\') { 1654 compiled[idx] = c; 1655 patternCharacters[idx] = '\\'; 1656 } else { 1657 compiled[idx] = c; 1658 patternCharacters[idx] = null; 1659 } 1660 idx++; 1661 p = c; 1662 } 1663 1664 this.autoCompleteCharacters = compiled; 1665 this.compiledPattern = regexps; 1666 this.patternCharacters = patternCharacters; 1667 this.patternLength = compiled.length; 1668}; 1669 1670Spry.Widget.ValidationTextField.prototype.getAutoComplete = function(from, direction) { 1671 if (direction == -1) { 1672 var n = '', m = ''; 1673 while(from && (n = this.getAutoComplete(--from) )) { 1674 m = n; 1675 } 1676 return m; 1677 } 1678 var ret = '', c = ''; 1679 for (var i=from; i<this.autoCompleteCharacters.length; i++) { 1680 c = this.autoCompleteCharacters[i]; 1681 if (c) { 1682 ret += c; 1683 } else { 1684 break; 1685 } 1686 } 1687 return ret; 1688}; 1689 1690Spry.Widget.ValidationTextField.regExpFromChars = function (string) { 1691 //string contains pattern characters 1692 var ret = '', character = ''; 1693 for (var i = 0; i<string.length; i++) { 1694 character = string.charAt(i); 1695 switch (character) { 1696 case '0': ret += '\\d';break; 1697 case 'A': ret += '[A-Z]';break;
1698// case 'A': ret += '[\u0041-\u005A\u0061-\u007A\u0100-\u017E\u0180-\u0233\u0391-\u03CE\u0410-\u044F\u05D0-\u05EA\u0621-\u063A\u0641-\u064A\u0661-\u06D3\u06F1-\u06FE]';break; 1699 case 'a': ret += '[a-z]';break; 1700// case 'a': ret += '[\u0080-\u00FF]';break; 1701 case 'B': case 'b': ret += '[a-zA-Z]';break; 1702 case 'x': ret += '[0-9a-z]';break; 1703 case 'X': ret += '[0-9A-Z]';break; 1704 case 'Y': case 'y': ret += '[0-9a-zA-Z]';break; 1705 case '?': ret += '.';break; 1706 case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9': 1707 ret += character; 1708 break; 1709 case 'c': case 'C': case 'e': case 'E': case 'f': case 'F':case 'r':case 'd': case 'D':case 'n':case 's':case 'S':case 'w':case 'W':case 't':case 'v': 1710 ret += character; 1711 break; 1712 default: ret += '\\' + character; 1713 } 1714 } 1715 return ret; 1716}; 1717 1718Spry.Widget.ValidationTextField.prototype.patternToRegExp = function(len) { 1719 var ret = '^'; 1720 var end = Math.min(this.compiledPattern.length, len); 1721 for (var i=0; i < end; i++) { 1722 ret += this.compiledPattern[i]; 1723 } 1724 ret += '$'; 1725 ret = new RegExp(ret, ""); 1726 return ret; 1727}; 1728 1729Spry.Widget.ValidationTextField.prototype.resetClasses = function() { 1730 var classes = [this.requiredClass, this.invalidFormatClass, this.invalidRangeMinClass, this.invalidRangeMaxClass, this.invalidCharsMinClass, this.invalidCharsMaxClass, this.validClass]; 1731 for (var i=0; i < classes.length; i++) 1732 { 1733 this.removeClassName(this.element, classes[i]); 1734 this.removeClassName(this.additionalError, classes[i]); 1735 } 1736}; 1737 1738Spry.Widget.ValidationTextField.prototype.reset = function() { 1739 this.removeHint(); 1740 this.oldValue = this.input.defaultValue; 1741 1742 this.resetClasses(); 1743 if (Spry.is.ie) { 1744 //this will fire the onpropertychange event right after the className changed on the container element 1745 //IE6 will not fire the first onpropertychange on an input type text after a onreset handler if inside that handler the className of one of the elements inside the form has been changed 1746 //to reproduce: change the className of one of the elements inside the form from within the onreset handler; then the onpropertychange does not fire the first time 1747 this.input.forceFireFirstOnPropertyChange = true; 1748 this.input.removeAttribute("forceFireFirstOnPropertyChange"); 1749 } 1750 var self = this; 1751 setTimeout(function() {self.putHint();}, 10); 1752}; 1753 1754/* ã¨ã©ã¼åé¿ç¨ã«è¿½å */ 1755Spry.Widget.ValidationTextField.prototype.hasClassName = function(ele, className) 1756{ 1757 if (!ele || !className || !ele.className || ele.className.search(new RegExp("\\b" + className + "\\b")) == -1) 1758 return false; 1759 return true; 1760}; 1761 1762Spry.Widget.ValidationTextField.prototype.validate = function() { 1763 1764 this.resetClasses(); 1765 1766 //ã¨ã©ã¼ç¡å¹ã«ãã§ãã¯ããã¦ããå ´åã¯å®è¡ããªãï¼ãªã»ããã®å¾ãã«è¨è¿°ï¼ 1767 if(document.getElementById("conf_error_check") != null){if(document.getElementById("conf_error_check").checked == true){return true;}} 1768 1769 //ãã§ãã¯ãç¡å¹ã«ãããSpryInvalidClassããè¨å®ããã¦ããå ´å 1770 if(this.hasClassName(this.element,'SpryInvalidClass')){return true;} 1771 1772 //possible states: required, format, rangeMin, rangeMax, charsMin, charsMax 1773 if (this.validateOn & Spry.Widget.ValidationTextField.ONSUBMIT) { 1774 1775 this.removeHint(); 1776 this.doValidations(this.input.value, this.input.value); 1777 1778 if(!this.flags.active) { 1779 var self = this; 1780 setTimeout(function() {self.putHint();}, 10); 1781 } 1782 } 1783 1784 if (this.isRequired && this.errors & Spry.Widget.ValidationTextField.ERROR_REQUIRED) { 1785 this.addClassName(this.element, this.requiredClass); 1786 this.addClassName(this.additionalError, this.requiredClass); 1787 return false; 1788 } 1789 1790 if (this.errors & Spry.Widget.ValidationTextField.ERROR_FORMAT) { 1791 this.addClassName(this.element, this.invalidFormatClass); 1792 this.addClassName(this.additionalError, this.invalidFormatClass); 1793 return false; 1794 } 1795 1796 if (this.errors & Spry.Widget.ValidationTextField.ERROR_RANGE_MIN) { 1797 this.addClassName(this.element, this.invalidRangeMinClass); 1798 this.addClassName(this.additionalError, this.invalidRangeMinClass); 1799 return false; 1800 } 1801 1802 if (this.errors & Spry.Widget.ValidationTextField.ERROR_RANGE_MAX) { 1803 this.addClassName(this.element, this.invalidRangeMaxClass); 1804 this.addClassName(this.additionalError, this.invalidRangeMaxClass); 1805 return false;
1806 } 1807 1808 if (this.errors & Spry.Widget.ValidationTextField.ERROR_CHARS_MIN) { 1809 this.addClassName(this.element, this.invalidCharsMinClass); 1810 this.addClassName(this.additionalError, this.invalidCharsMinClass); 1811 return false; 1812 } 1813 1814 if (this.errors & Spry.Widget.ValidationTextField.ERROR_CHARS_MAX) { 1815 this.addClassName(this.element, this.invalidCharsMaxClass); 1816 this.addClassName(this.additionalError, this.invalidCharsMaxClass); 1817 return false; 1818 } 1819 1820 this.addClassName(this.element, this.validClass); 1821 this.addClassName(this.additionalError, this.validClass); 1822 return true; 1823}; 1824 1825Spry.Widget.ValidationTextField.prototype.addClassName = function(ele, className) 1826{ 1827 if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1)) 1828 return; 1829 ele.className += (ele.className ? " " : "") + className; 1830}; 1831 1832Spry.Widget.ValidationTextField.prototype.removeClassName = function(ele, className) 1833{ 1834 if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) == -1)) 1835 return; 1836 ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), ""); 1837}; 1838Spry.Widget.ValidationTextField.prototype.showError = function(msg) 1839{ 1840 alert('Spry.Widget.TextField ERR: ' + msg); 1841}; 1842/** 1843 * SelectionDescriptor is a wrapper for input type text selection methods and properties 1844 * as implemented by various browsers 1845 */ 1846Spry.Widget.SelectionDescriptor = function (element) 1847{ 1848 this.element = element; 1849 this.update(); 1850}; 1851 1852Spry.Widget.SelectionDescriptor.prototype.update = function() 1853{ 1854 if (Spry.is.ie && Spry.is.windows) { 1855 var sel = this.element.ownerDocument.selection; 1856 if (this.element.nodeName == "TEXTAREA") { 1857 if (sel.type != 'None') { 1858 try{var range = sel.createRange();}catch(err){return;} 1859 if (range.parentElement() == this.element){ 1860 var range_all = this.element.ownerDocument.body.createTextRange(); 1861 range_all.moveToElementText(this.element); 1862 for (var sel_start = 0; range_all.compareEndPoints('StartToStart', range) < 0; sel_start ++){ 1863 range_all.moveStart('character', 1); 1864 } 1865 this.start = sel_start; 1866 // create a selection of the whole this.element 1867 range_all = this.element.ownerDocument.body.createTextRange(); 1868 range_all.moveToElementText(this.element); 1869 for (var sel_end = 0; range_all.compareEndPoints('StartToEnd', range) < 0; sel_end++){ 1870 range_all.moveStart('character', 1); 1871 } 1872 this.end = sel_end; 1873 this.length = this.end - this.start; 1874 // get selected and surrounding text 1875 this.text = range.text; 1876 } 1877 } 1878 } else if (this.element.nodeName == "INPUT"){ 1879 try{this.range = sel.createRange();}catch(err){return;} 1880 this.length = this.range.text.length; 1881 var clone = this.range.duplicate(); 1882 this.start = -clone.moveStart("character", -10000); 1883 clone = this.range.duplicate(); 1884 clone.collapse(false); 1885 this.end = -clone.moveStart("character", -10000); 1886 this.text = this.range.text; 1887 } 1888 } else { 1889 var tmp = this.element; 1890 var selectionStart = 0; 1891 var selectionEnd = 0; 1892 1893 try { selectionStart = tmp.selectionStart;} catch(err) {} 1894 try { selectionEnd = tmp.selectionEnd;} catch(err) {} 1895 1896 if (Spry.is.safari) { 1897 if (selectionStart == 2147483647) { 1898 selectionStart = 0; 1899 } 1900 if (selectionEnd == 2147483647) { 1901 selectionEnd = 0; 1902 } 1903 } 1904 this.start = selectionStart; 1905 this.end = selectionEnd; 1906 this.length = selectionEnd - selectionStart; 1907 this.text = this.element.value.substring(selectionStart, selectionEnd); 1908 } 1909}; 1910 1911Spry.Widget.SelectionDescriptor.prototype.destroy = function() { 1912 try { delete this.range} catch(err) {} 1913 try { delete this.element} catch(err) {} 1914}; 1915 1916Spry.Widget.SelectionDescriptor.prototype.move = function(amount) 1917{ 1918 if (Spry.is.ie && Spry.is.windows) { 1919 this.range.move("character", amount); 1920 this.range.select(); 1921 } else { 1922 try { this.element.selectionStart++;}catch(err) {} 1923 } 1924 this.update(); 1925}; 1926 1927Spry.Widget.SelectionDescriptor.prototype.moveTo = function(start, end) 1928{ 1929 if (Spry.is.ie && Spry.is.windows) { 1930 if (this.element.nodeName == "TEXTAREA") { 1931 var ta_range = this.element.createTextRange(); 1932 this.range = this.element.createTextRange(); 1933 this.range.move("character", start); 1934 this.range.moveEnd("character", end - start); 1935 1936 var c1 = this.range.compareEndPoints("StartToStart", ta_range); 1937 if (c1 < 0) { 1938 this.range.setEndPoint("StartToStart", ta_range); 1939 } 1940 1941 var c2 = this.range.compareEndPoints("EndToEnd", ta_range); 1942 if (c2 > 0) { 1943 this.range.setEndPoint("EndToEnd", ta_range); 1944 } 1945 } else if (this.element.nodeName == "INPUT"){ 1946 this.range = this.element.ownerDocument.selection.createRange(); 1947 this.range.move("character", -10000); 1948 this.start = this.range.moveStart("character", start); 1949 this.end = this.start + this.range.moveEnd("character", end - start); 1950 } 1951 this.range.select(); 1952 } else { 1953 this.start = start; 1954 try { this.element.selectionStart = start;} catch(err) {} 1955 this.end = end; 1956 try { this.element.selectionEnd = end;} catch(err) {} 1957 } 1958 this.ignore = true; 1959 this.update(); 1960}; 1961 1962Spry.Widget.SelectionDescriptor.prototype.moveEnd = function(amount) 1963{ 1964 if (Spry.is.ie && Spry.is.windows) { 1965 this.range.moveEnd("character", amount); 1966 this.range.select(); 1967 } else { 1968 try { this.element.selectionEnd++;} catch(err) {} 1969 } 1970 this.update(); 1971}; 1972 1973Spry.Widget.SelectionDescriptor.prototype.collapse = function(begin) 1974{ 1975 if (Spry.is.ie && Spry.is.windows) { 1976 this.range = this.element.ownerDocument.selection.createRange(); 1977 this.range.collapse(begin); 1978 this.range.select(); 1979 } else { 1980 if (begin) { 1981 try { this.element.selectionEnd = this.element.selectionStart;} catch(err) {} 1982 } else { 1983 try { this.element.selectionStart = this.element.selectionEnd;} catch(err) {} 1984 } 1985 } 1986 1987 this.update(); 1988}; 1989 1990////////////////////////////////////////////////////////////////////// 1991// 1992// Spry.Widget.Form - common for all widgets 1993// 1994////////////////////////////////////////////////////////////////////// 1995 1996if (!Spry.Widget.Form) Spry.Widget.Form = {}; 1997if (!Spry.Widget.Form.onSubmitWidgetQueue) Spry.Widget.Form.onSubmitWidgetQueue = []; 1998 1999if (!Spry.Widget.Form.validate) { 2000 Spry.Widget.Form.validate = function(vform) { 2001 var isValid = true; 2002 var isElementValid = true; 2003 var q = Spry.Widget.Form.onSubmitWidgetQueue; 2004 var qlen = q.length; 2005 for (var i = 0; i < qlen; i++) { 2006 if (!q[i].isDisabled() && q[i].form == vform) { 2007 isElementValid = q[i].validate(); 2008 isValid = isElementValid && isValid; 2009 } 2010 } 2011 return isValid; 2012 } 2013}; 2014 2015if (!Spry.Widget.Form.onSubmit) { 2016 Spry.Widget.Form.onSubmit = function(e, form) 2017 { 2018 if (Spry.Widget.Form.validate(form) == false) { 2019 return false;
2020 } 2021 return true; 2022 }; 2023}; 2024 2025if (!Spry.Widget.Form.onReset) { 2026 Spry.Widget.Form.onReset = function(e, vform) 2027 { 2028 var q = Spry.Widget.Form.onSubmitWidgetQueue; 2029 var qlen = q.length; 2030 for (var i = 0; i < qlen; i++) { 2031 if (!q[i].isDisabled() && q[i].form == vform && typeof(q[i].reset) == 'function') { 2032 q[i].reset(); 2033 } 2034 } 2035 return true; 2036 }; 2037}; 2038 2039if (!Spry.Widget.Form.destroy) { 2040 Spry.Widget.Form.destroy = function(form) 2041 { 2042 var q = Spry.Widget.Form.onSubmitWidgetQueue; 2043 for (var i = 0; i < Spry.Widget.Form.onSubmitWidgetQueue.length; i++) { 2044 if (q[i].form == form && typeof(q[i].destroy) == 'function') { 2045 q[i].destroy(); 2046 i--; 2047 } 2048 } 2049 } 2050}; 2051 2052if (!Spry.Widget.Form.destroyAll) { 2053 Spry.Widget.Form.destroyAll = function() 2054 { 2055 var q = Spry.Widget.Form.onSubmitWidgetQueue; 2056 for (var i = 0; i < Spry.Widget.Form.onSubmitWidgetQueue.length; i++) { 2057 if (typeof(q[i].destroy) == 'function') { 2058 q[i].destroy(); 2059 i--; 2060 } 2061 } 2062 } 2063}; 2064 2065////////////////////////////////////////////////////////////////////// 2066// 2067// Spry.Widget.Utils 2068// 2069////////////////////////////////////////////////////////////////////// 2070 2071if (!Spry.Widget.Utils) Spry.Widget.Utils = {}; 2072 2073Spry.Widget.Utils.punycode_constants = { 2074 base : 36, tmin : 1, tmax : 26, skew : 38, damp : 700, 2075 initial_bias : 72, initial_n : 0x80, delimiter : 0x2D, 2076 maxint : 2<<26-1 2077}; 2078 2079Spry.Widget.Utils.punycode_encode_digit = function (d) { 2080 return String.fromCharCode(d + 22 + 75 * (d < 26)); 2081}; 2082 2083Spry.Widget.Utils.punycode_adapt = function (delta, numpoints, firsttime) { 2084 delta = firsttime ? delta / this.punycode_constants.damp : delta >> 1; 2085 delta += delta / numpoints; 2086 2087 for (var k = 0; delta > ((this.punycode_constants.base - this.punycode_constants.tmin) * this.punycode_constants.tmax) / 2; k += this.punycode_constants.base) { 2088 delta /= this.punycode_constants.base - this.punycode_constants.tmin; 2089 } 2090 return k + (this.punycode_constants.base - this.punycode_constants.tmin + 1) * delta / (delta + this.punycode_constants.skew); 2091}; 2092 2093/** 2094 * returns a Punicode representation of a UTF-8 string 2095 * adapted from http://tools.ietf.org/html/rfc3492 2096 */ 2097Spry.Widget.Utils.punycode_encode = function (input, max_out) { 2098 var inputc = input.split(""); 2099 input = []; 2100 for(var i=0; i<inputc.length; i++) { 2101 input.push(inputc[i].charCodeAt(0)); 2102 } 2103 var output = ''; 2104 2105 var h, b, j, m, q, k, t; 2106 var input_len = input.length; 2107 var n = this.punycode_constants.initial_n; 2108 var delta = 0; 2109 var bias = this.punycode_constants.initial_bias; 2110 var out = 0; 2111 2112 for (j = 0; j < input_len; j++) { 2113 if (input[j] < 128) { 2114 if (max_out - out < 2) { 2115 return false; 2116 } 2117 output += String.fromCharCode(input[j]); 2118 out++; 2119 } 2120 } 2121 2122 h = b = out; 2123 if (b > 0) { 2124 output += String.fromCharCode(this.punycode_constants.delimiter); 2125 out++; 2126 } 2127 2128 while (h < input_len) { 2129 for (m = this.punycode_constants.maxint, j = 0; j < input_len; j++) { 2130 if (input[j] >= n && input[j] < m) { 2131 m = input[j]; 2132 } 2133 } 2134 if (m - n > (this.punycode_constants.maxint - delta) / (h + 1)) { 2135 return false; 2136 } 2137 2138 delta += (m - n) * (h + 1); 2139 n = m; 2140 2141 for (j = 0; j < input_len; j++) { 2142 if (input[j] < n ) { 2143 if (++delta == 0) { 2144 return false; 2145 } 2146 } 2147 2148 if (input[j] == n) { 2149 for (q = delta, k = this.punycode_constants.base; true; k += this.punycode_constants.base) { 2150 if (out >= max_out) { 2151 return false; 2152 } 2153 2154 t = k <= bias ? this.punycode_constants.tmin : k >= bias + this.punycode_constants.tmax ? this.punycode_constants.tmax : k - bias; 2155 if (q < t) { 2156 break; 2157 } 2158 2159 output += this.punycode_encode_digit(t + (q - t) % (this.punycode_constants.base - t)); 2160 out++; 2161 q = (q - t) / (this.punycode_constants.base - t); 2162 } 2163 2164 output += this.punycode_encode_digit(q); 2165 out++; 2166 bias = this.punycode_adapt(delta, h + 1, h == b); 2167 delta = 0; 2168 h++; 2169 } 2170 } 2171 delta++, n++; 2172 } 2173 2174 return output; 2175}; 2176 2177Spry.Widget.Utils.setOptions = function(obj, optionsObj, ignoreUndefinedProps) 2178{ 2179 if (!optionsObj) 2180 return; 2181 for (var optionName in optionsObj) 2182 { 2183 if (ignoreUndefinedProps && optionsObj[optionName] == undefined) 2184 continue; 2185 obj[optionName] = optionsObj[optionName]; 2186 } 2187}; 2188 2189Spry.Widget.Utils.firstValid = function() { 2190 var ret = null; 2191 for(var i=0; i<Spry.Widget.Utils.firstValid.arguments.length; i++) { 2192 if (typeof(Spry.Widget.Utils.firstValid.arguments[i]) != 'undefined') { 2193 ret = Spry.Widget.Utils.firstValid.arguments[i]; 2194 break; 2195 } 2196 } 2197 return ret; 2198}; 2199 2200 2201Spry.Widget.Utils.specialCharacters = ",8,9,16,17,18,20,27,33,34,35,36,37,38,40,45,144,192,63232,"; 2202Spry.Widget.Utils.specialSafariNavKeys = "63232,63233,63234,63235,63272,63273,63275,63276,63277,63289,"; 2203Spry.Widget.Utils.specialNotSafariCharacters = "39,46,91,92,93,"; 2204 2205Spry.Widget.Utils.specialCharacters += Spry.Widget.Utils.specialSafariNavKeys; 2206 2207if (!Spry.is.safari) { 2208 Spry.Widget.Utils.specialCharacters += Spry.Widget.Utils.specialNotSafariCharacters; 2209} 2210 2211Spry.Widget.Utils.isSpecialKey = function (ev) { 2212 return Spry.Widget.Utils.specialCharacters.indexOf("," + ev.keyCode + ",") != -1; 2213}; 2214 2215Spry.Widget.Utils.getCharacterFromEvent = function(e){ 2216 var keyDown = e.type == "keydown"; 2217 2218 var code = null; 2219 var character = null; 2220 if(Spry.is.mozilla && !keyDown){ 2221 if(e.charCode){ 2222 character = String.fromCharCode(e.charCode); 2223 } else {
2224 code = e.keyCode; 2225 } 2226 } else { 2227 code = e.keyCode || e.which; 2228 if (code != 13) { 2229 character = String.fromCharCode(code); 2230 } 2231 } 2232 2233 if (Spry.is.safari) { 2234 if (keyDown) { 2235 code = e.keyCode || e.which; 2236 character = String.fromCharCode(code); 2237 } else { 2238 code = e.keyCode || e.which; 2239 if (Spry.Widget.Utils.specialCharacters.indexOf("," + code + ",") != -1) { 2240 character = null; 2241 } else { 2242 character = String.fromCharCode(code); 2243 } 2244 } 2245 } 2246 2247 if(Spry.is.opera) { 2248 if (Spry.Widget.Utils.specialCharacters.indexOf("," + code + ",") != -1) { 2249 character = null; 2250 } else { 2251 character = String.fromCharCode(code); 2252 } 2253 } 2254 2255 return character; 2256}; 2257 2258Spry.Widget.Utils.getFirstChildWithNodeNameAtAnyLevel = function(node, nodeName) 2259{ 2260 var elements = node.getElementsByTagName(nodeName); 2261 if (elements) { 2262 return elements[0]; 2263 } 2264 return null; 2265}; 2266 2267Spry.Widget.Utils.getFirstParentWithNodeName = function(node, nodeName) 2268{ 2269 while (node.parentNode 2270 && node.parentNode.nodeName.toLowerCase() != nodeName.toLowerCase() 2271 && node.parentNode.nodeName != 'BODY') { 2272 node = node.parentNode; 2273 } 2274 2275 if (node.parentNode && node.parentNode.nodeName.toLowerCase() == nodeName.toLowerCase()) { 2276 return node.parentNode; 2277 } else { 2278 return null; 2279 } 2280}; 2281 2282Spry.Widget.Utils.destroyWidgets = function (container) 2283{ 2284 if (typeof container == 'string') { 2285 container = document.getElementById(container); 2286 } 2287 2288 var q = Spry.Widget.Form.onSubmitWidgetQueue; 2289 for (var i = 0; i < Spry.Widget.Form.onSubmitWidgetQueue.length; i++) { 2290 if (typeof(q[i].destroy) == 'function' && Spry.Widget.Utils.contains(container, q[i].element)) { 2291 q[i].destroy(); 2292 i--; 2293 } 2294 } 2295}; 2296 2297Spry.Widget.Utils.contains = function (who, what) 2298{ 2299 if (typeof who.contains == 'object') { 2300 return what && who && (who == what || who.contains(what)); 2301 } else { 2302 var el = what; 2303 while(el) { 2304 if (el == who) { 2305 return true; 2306 } 2307 el = el.parentNode; 2308 } 2309 return false; 2310 } 2311}; 2312 2313Spry.Widget.Utils.addEventListener = function(element, eventType, handler, capture) 2314{ 2315 try 2316 { 2317 if (element.addEventListener) 2318 element.addEventListener(eventType, handler, capture); 2319 else if (element.attachEvent) 2320 element.attachEvent("on" + eventType, handler, capture); 2321 } 2322 catch (e) {} 2323}; 2324 2325Spry.Widget.Utils.removeEventListener = function(element, eventType, handler, capture) 2326{ 2327 try 2328 { 2329 if (element.removeEventListener) 2330 element.removeEventListener(eventType, handler, capture); 2331 else if (element.detachEvent) 2332 element.detachEvent("on" + eventType, handler, capture); 2333 } 2334 catch (e) {} 2335}; 2336 2337Spry.Widget.Utils.stopEvent = function(ev) 2338{ 2339 try 2340 { 2341 this.stopPropagation(ev); 2342 this.preventDefault(ev); 2343 } 2344 catch (e) {} 2345}; 2346 2347/** 2348 * Stops event propagation 2349 * @param {Event} ev the event 2350 */ 2351Spry.Widget.Utils.stopPropagation = function(ev) 2352{ 2353 if (ev.stopPropagation) 2354 { 2355 ev.stopPropagation(); 2356 } 2357 else 2358 { 2359 ev.cancelBubble = true; 2360 } 2361}; 2362 2363/** 2364 * Prevents the default behavior of the event 2365 * @param {Event} ev the event 2366 */ 2367Spry.Widget.Utils.preventDefault = function(ev) 2368{ 2369 if (ev.preventDefault) 2370 { 2371 ev.preventDefault(); 2372 } 2373 else 2374 { 2375 ev.returnValue = false; 2376 } 2377}; 2378 2379})(); // EndSpryComponent
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.