1/* SpryValidationSelect.js - Revision: Spry Preview Release 1.4 */ 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 30var Spry; 31if (!Spry) Spry = {}; 32if (!Spry.Widget) Spry.Widget = {}; 33 34Spry.Widget.ValidationSelect = function(element, opts) 35{ 36 this.init(element); 37 38 Spry.Widget.Utils.setOptions(this, opts); 39 40 // set validateOn flags 41 var validateOn = ['submit'].concat(this.validateOn || []); 42 validateOn = validateOn.join(","); 43 this.validateOn = 0 | (validateOn.indexOf('submit') != -1 ? Spry.Widget.ValidationSelect.ONSUBMIT : 0); 44 this.validateOn = this.validateOn | (validateOn.indexOf('blur') != -1 ? Spry.Widget.ValidationSelect.ONBLUR : 0); 45 this.validateOn = this.validateOn | (validateOn.indexOf('change') != -1 ? Spry.Widget.ValidationSelect.ONCHANGE : 0); 46 47 48 // Unfortunately in some browsers like Safari, the Stylesheets our 49 // page depends on may not have been loaded at the time we are called. 50 // This means we have to defer attaching our behaviors until after the 51 // onload event fires, since some of our behaviors rely on dimensions 52 // specified in the CSS. 53 54 if (Spry.Widget.ValidationSelect.onloadDidFire) 55 this.attachBehaviors(); 56 else 57 Spry.Widget.ValidationSelect.loadQueue.push(this); 58}; 59 60Spry.Widget.ValidationSelect.ONCHANGE = 1; 61Spry.Widget.ValidationSelect.ONBLUR = 2; 62Spry.Widget.ValidationSelect.ONSUBMIT = 4; 63 64Spry.Widget.ValidationSelect.prototype.init = function(element) 65{ 66 this.element = this.getElement(element); 67 this.selectElement = null; 68 this.form = null; 69 this.event_handlers = []; 70 71 // this.element can be either the container (<span>) 72 // or the <select> element, when no error messages are used. 73 74 this.requiredClass = "selectRequiredState"; 75 this.invalidClass = "selectInvalidState"; 76 this.focusClass = "selectFocusState"; 77 this.validClass = "selectValidState"; 78 79 this.emptyValue = ""; 80 this.invalidValue = null; 81 this.isRequired = true; 82 83 this.validateOn = ["submit"]; // change, blur, submit 84 // flag used to avoid cascade validation when both 85 // onChange and onBlur events are used to trigger validation 86 this.validatedByOnChangeEvent = false; 87}; 88 89Spry.Widget.ValidationSelect.prototype.destroy = function() { 90 for (var i=0; i<this.event_handlers.length; i++) { 91 Spry.Widget.Utils.removeEventListener(this.event_handlers[i][0], this.event_handlers[i][1], this.event_handlers[i][2], false); 92 } 93 try { delete this.element; } catch(err) {} 94 try { delete this.selectElement; } catch(err) {} 95 try { delete this.form; } catch(err) {} 96 try { delete this.event_handlers; } catch(err) {} 97 98 var q = Spry.Widget.Form.onSubmitWidgetQueue; 99 var qlen = q.length; 100 for (var i = 0; i < qlen; i++) { 101 if (q[i] == this) { 102 q.splice(i, 1); 103 break; 104 } 105 } 106}; 107 108Spry.Widget.ValidationSelect.onloadDidFire = false;
109Spry.Widget.ValidationSelect.loadQueue = []; 110 111Spry.Widget.ValidationSelect.prototype.getElement = function(ele) 112{ 113 if (ele && typeof ele == "string") 114 return document.getElementById(ele); 115 return ele; 116}; 117 118Spry.Widget.ValidationSelect.processLoadQueue = function(handler) 119{ 120 Spry.Widget.ValidationSelect.onloadDidFire = true; 121 var q = Spry.Widget.ValidationSelect.loadQueue; 122 var qlen = q.length; 123 for (var i = 0; i < qlen; i++) 124 q[i].attachBehaviors(); 125}; 126 127Spry.Widget.ValidationSelect.addLoadListener = function(handler) 128{ 129 if (typeof window.addEventListener != 'undefined') 130 window.addEventListener('load', handler, false); 131 else if (typeof document.addEventListener != 'undefined') 132 document.addEventListener('load', handler, false); 133 else if (typeof window.attachEvent != 'undefined') 134 window.attachEvent('onload', handler); 135}; 136 137Spry.Widget.ValidationSelect.addLoadListener(Spry.Widget.ValidationSelect.processLoadQueue); 138Spry.Widget.ValidationSelect.addLoadListener(function(){ 139 Spry.Widget.Utils.addEventListener(window, "unload", Spry.Widget.Form.destroyAll, false); 140}); 141 142Spry.Widget.ValidationSelect.prototype.attachBehaviors = function() 143{ 144 // find the SELECT element inside current container 145 if (this.element.nodeName == "SELECT") { 146 this.selectElement = this.element; 147 } else { 148 this.selectElement = Spry.Widget.Utils.getFirstChildWithNodeNameAtAnyLevel(this.element, "SELECT"); 149 } 150 151 if (this.selectElement) { 152 var self = this; 153 this.event_handlers = []; 154 // focus 155 // attach on beforeactivate instead of focus for IE 7 (to overcome this bug: setting a class name, closes the select) 156 var focusEventName = "focus"; 157 if (navigator.userAgent.toLowerCase().indexOf("msie 7.") != -1) { 158 focusEventName = "beforeactivate"; 159 } 160 this.event_handlers.push([this.selectElement, focusEventName, function(e) { if (self.isDisabled()) return true; return self.onFocus(e); }]); 161 // blur 162 this.event_handlers.push([this.selectElement, "blur", function(e) { if (self.isDisabled()) return true; return self.onBlur(e); }]); 163 // change 164 if (this.validateOn & Spry.Widget.ValidationSelect.ONCHANGE) { 165 this.event_handlers.push([this.selectElement, "change", function(e) { if (self.isDisabled()) return true; return self.onChange(e); }]); 166 this.event_handlers.push([this.selectElement, "keypress", function(e) { if (self.isDisabled()) return true; return self.onChange(e); }]); 167 } 168 169 for (var i=0; i<this.event_handlers.length; i++) { 170 Spry.Widget.Utils.addEventListener(this.event_handlers[i][0], this.event_handlers[i][1], this.event_handlers[i][2], false); 171 } 172 173 // submit 174 this.form = Spry.Widget.Utils.getFirstParentWithNodeName(this.selectElement, "FORM"); 175 if (this.form) { 176 // if no "onSubmit" handler has been attached to the current form, attach one 177 if (!this.form.attachedSubmitHandler && !this.form.onsubmit) { 178 this.form.onsubmit = function(e) { e = e || event; return Spry.Widget.Form.onSubmit(e, e.srcElement || e.currentTarget) }; 179 this.form.attachedSubmitHandler = true; 180 } 181 if (!this.form.attachedResetHandler) { 182 Spry.Widget.Utils.addEventListener(this.form, "reset", function(e) { e = e || event; return Spry.Widget.Form.onReset(e, e.srcElement || e.currentTarget) }, false); 183 this.form.attachedResetHandler = true; 184 } 185 // add the currrent widget to the "onSubmit" check queue; 186 Spry.Widget.Form.onSubmitWidgetQueue.push(this); 187 } 188 } 189}; 190 191 192Spry.Widget.ValidationSelect.prototype.addClassName = function(ele, className) 193{ 194 if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1)) 195 return; 196 ele.className += (ele.className ? " " : "") + className; 197}; 198 199Spry.Widget.ValidationSelect.prototype.removeClassName = function(ele, className) 200{ 201 if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) == -1)) 202 return; 203 ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), ""); 204}; 205 206 207 208Spry.Widget.ValidationSelect.prototype.onFocus = function(e) 209{ 210 this.hasFocus = true; 211 this.validatedByOnChangeEvent = false;
212 this.addClassName(this.element, this.focusClass); 213}; 214 215Spry.Widget.ValidationSelect.prototype.onBlur = function(e) 216{ 217 this.hasFocus = false; 218 var doValidation = false; 219 if (this.validateOn & Spry.Widget.ValidationSelect.ONBLUR) 220 doValidation = true; 221 if (doValidation && !this.validatedByOnChangeEvent) 222 this.validate(); 223 this.removeClassName(this.element, this.focusClass); 224}; 225 226Spry.Widget.ValidationSelect.prototype.onChange = function(e) 227{ 228 this.hasFocus = false; 229 this.validate(); 230 this.validatedByOnChangeEvent = true; 231}; 232 233Spry.Widget.ValidationSelect.prototype.reset = function() { 234 this.removeClassName(this.element, this.requiredClass); 235 this.removeClassName(this.element, this.invalidClass); 236 this.removeClassName(this.element, this.validClass); 237}; 238 239Spry.Widget.ValidationSelect.prototype.validate = function() { 240 this.removeClassName(this.element, this.requiredClass); 241 this.removeClassName(this.element, this.invalidClass); 242 this.removeClassName(this.element, this.validClass); 243 // check isRequired 244 if (this.isRequired) { 245 // there are no options, or no option has been selected 246 if (this.selectElement.options.length == 0 || this.selectElement.selectedIndex == -1) { 247 this.addClassName(this.element, this.requiredClass); 248 return false; 249 } 250 // the current selected option has no "value" attribute 251 // when no value is set, browsers implement different behaviour for the value property 252 // IE: value = blank string ("") 253 // FF, Opera: value = option text 254 if (this.selectElement.options[this.selectElement.selectedIndex].getAttribute("value") == null) { 255 this.addClassName(this.element, this.requiredClass); 256 return false; 257 } 258 // the current selected option has blank string ("") value 259 if (this.selectElement.options[this.selectElement.selectedIndex].value == this.emptyValue) { 260 this.addClassName(this.element, this.requiredClass); 261 return false; 262 } 263 // the current selected option has "disabled" attribute 264 // IE 6 allows to select such options 265 if (this.selectElement.options[this.selectElement.selectedIndex].disabled) { 266 this.addClassName(this.element, this.requiredClass); 267 return false; 268 } 269 } 270 if (this.invalidValue) { 271 if (this.selectElement.options.length > 0 && 272 this.selectElement.selectedIndex != -1 && 273 this.selectElement.options[this.selectElement.selectedIndex].value == this.invalidValue) { 274 this.addClassName(this.element, this.invalidClass); 275 return false; 276 } 277 } 278 this.addClassName(this.element, this.validClass); 279 return true; 280} 281 282Spry.Widget.ValidationSelect.prototype.isDisabled = function() { 283 return this.selectElement.disabled; 284} 285 286////////////////////////////////////////////////////////////////////// 287// 288// Spry.Widget.Form - common for all widgets 289// 290////////////////////////////////////////////////////////////////////// 291 292if (!Spry.Widget.Form) Spry.Widget.Form = {}; 293if (!Spry.Widget.Form.onSubmitWidgetQueue) Spry.Widget.Form.onSubmitWidgetQueue = []; 294 295if (!Spry.Widget.Form.validate) { 296 Spry.Widget.Form.validate = function(vform) { 297 var isValid = true; 298 var isElementValid = true; 299 var q = Spry.Widget.Form.onSubmitWidgetQueue; 300 var qlen = q.length; 301 for (var i = 0; i < qlen; i++) { 302 if (!q[i].isDisabled() && q[i].form == vform) { 303 isElementValid = q[i].validate(); 304 isValid = isElementValid && isValid; 305 } 306 } 307 return isValid; 308 } 309}; 310 311if (!Spry.Widget.Form.onSubmit) { 312 Spry.Widget.Form.onSubmit = function(e, form) 313 { 314 if (Spry.Widget.Form.validate(form) == false) { 315 return false; 316 } 317 return true; 318 }; 319}; 320 321if (!Spry.Widget.Form.onReset) { 322 Spry.Widget.Form.onReset = function(e, vform) 323 { 324 var q = Spry.Widget.Form.onSubmitWidgetQueue; 325 var qlen = q.length; 326 for (var i = 0; i < qlen; i++) { 327 if (!q[i].isDisabled() && q[i].form == vform && typeof(q[i].reset) == 'function') { 328 q[i].reset(); 329 } 330 } 331 return true; 332 }; 333}; 334 335if (!Spry.Widget.Form.destroy) { 336 Spry.Widget.Form.destroy = function(form) 337 { 338 var q = Spry.Widget.Form.onSubmitWidgetQueue; 339 for (var i = 0; i < Spry.Widget.Form.onSubmitWidgetQueue.length; i++) { 340 if (q[i].form == form && typeof(q[i].destroy) == 'function') { 341 q[i].destroy(); 342 i--; 343 } 344 } 345 } 346}; 347 348if (!Spry.Widget.Form.destroyAll) { 349 Spry.Widget.Form.destroyAll = function() 350 { 351 var q = Spry.Widget.Form.onSubmitWidgetQueue; 352 for (var i = 0; i < Spry.Widget.Form.onSubmitWidgetQueue.length; i++) { 353 if (typeof(q[i].destroy) == 'function') { 354 q[i].destroy(); 355 i--; 356 } 357 } 358 } 359}; 360 361////////////////////////////////////////////////////////////////////// 362// 363// Spry.Widget.Utils 364// 365////////////////////////////////////////////////////////////////////// 366 367if (!Spry.Widget.Utils) Spry.Widget.Utils = {}; 368 369Spry.Widget.Utils.setOptions = function(obj, optionsObj, ignoreUndefinedProps) 370{ 371 if (!optionsObj) 372 return; 373 for (var optionName in optionsObj) 374 { 375 if (ignoreUndefinedProps && optionsObj[optionName] == undefined) 376 continue; 377 obj[optionName] = optionsObj[optionName]; 378 } 379}; 380 381 382Spry.Widget.Utils.getFirstChildWithNodeNameAtAnyLevel = function(node, nodeName) 383{
384 var elements = node.getElementsByTagName(nodeName); 385 if (elements) { 386 return elements[0]; 387 } 388 return null; 389}; 390 391Spry.Widget.Utils.getFirstParentWithNodeName = function(node, nodeName) 392{ 393 while (node.parentNode 394 && node.parentNode.nodeName.toLowerCase() != nodeName.toLowerCase() 395 && node.parentNode.nodeName != 'BODY') { 396 node = node.parentNode; 397 } 398 399 if (node.parentNode && node.parentNode.nodeName.toLowerCase() == nodeName.toLowerCase()) { 400 return node.parentNode; 401 } else { 402 return null; 403 } 404}; 405 406Spry.Widget.Utils.destroyWidgets = function (container) 407{ 408 if (typeof container == 'string') { 409 container = document.getElementById(container); 410 } 411 412 var q = Spry.Widget.Form.onSubmitWidgetQueue; 413 for (var i = 0; i < Spry.Widget.Form.onSubmitWidgetQueue.length; i++) { 414 if (typeof(q[i].destroy) == 'function' && Spry.Widget.Utils.contains(container, q[i].element)) { 415 q[i].destroy(); 416 i--; 417 } 418 } 419}; 420 421Spry.Widget.Utils.contains = function (who, what) 422{ 423 if (typeof who.contains == 'object') { 424 return what && who && (who == what || who.contains(what)); 425 } else { 426 var el = what; 427 while(el) { 428 if (el == who) { 429 return true; 430 } 431 el = el.parentNode; 432 } 433 return false; 434 } 435}; 436 437Spry.Widget.Utils.addEventListener = function(element, eventType, handler, capture) 438{ 439 try 440 { 441 if (element.addEventListener) 442 element.addEventListener(eventType, handler, capture); 443 else if (element.attachEvent) 444 element.attachEvent("on" + eventType, handler, capture); 445 } 446 catch (e) {} 447}; 448 449Spry.Widget.Utils.removeEventListener = function(element, eventType, handler, capture) 450{ 451 try 452 { 453 if (element.removeEventListener) 454 element.removeEventListener(eventType, handler, capture); 455 else if (element.detachEvent) 456 element.detachEvent("on" + eventType, handler, capture); 457 } 458 catch (e) {} 459}; 460 461
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.