[ Index ] |
|
Code source de PRADO 3.0.6 |
1 2 /** 3 * Prado client-side javascript validation fascade. 4 * 5 * There are 4 basic classes, Validation, ValidationManager, ValidationSummary 6 * and TBaseValidator, that interact together to perform validation. 7 * The <tt>Prado.Validation</tt> class co-ordinates together the 8 * validation scheme and is responsible for maintaining references 9 * to ValidationManagers. 10 * 11 * The ValidationManager class is responsible for maintaining refereneces 12 * to individual validators, validation summaries and their associated 13 * groupings. 14 * 15 * The ValidationSummary take cares of display the validator error messages 16 * as html output or an alert output. 17 * 18 * The TBaseValidator is the base class for all validators and contains 19 * methods to interact with the actual inputs, data type conversion. 20 * 21 * An instance of ValidationManager must be instantiated first for a 22 * particular form before instantiating validators and summaries. 23 * 24 * Usage example: adding a required field to a text box input with 25 * ID "input1" in a form with ID "form1". 26 * <code> 27 * <script type="text/javascript" src="../prado.js"></script> 28 * <script type="text/javascript" src="../validator.js"></script> 29 * <form id="form1" action="..."> 30 * <div> 31 * <input type="text" id="input1" /> 32 * <span id="validator1" style="display:none; color:red">*</span> 33 * <input type="submit text="submit" /> 34 * <script type="text/javascript"> 35 * new Prado.ValidationManager({FormID : 'form1'}); 36 * var options = 37 * { 38 * ID : 'validator1', 39 * FormID : 'form1', 40 * ErrorMessage : '*', 41 * ControlToValidate : 'input1' 42 * } 43 * new Prado.WebUI.TRequiredFieldValidator(options); 44 * new Prado.WebUI.TValidationSummary({ID:'summary1',FormID:'form1'}); 45 * 46 * //watch the form onsubmit event, check validators, stop if not valid. 47 * Event.observe("form1", "submit" function(ev) 48 * { 49 * if(Prado.WebUI.Validation.isValid("form1") == false) 50 * Event.stop(ev); 51 * }); 52 * </script> 53 * </div> 54 * </form> 55 * </code> 56 */ 57 Prado.Validation = Class.create(); 58 59 /** 60 * A global validation manager. 61 * To validate the inputs of a particular form, call 62 * <code>Prado.Validation.validate(formID, groupID)</code> 63 * where <tt>formID</tt> is the HTML form ID, and the optional 64 * <tt>groupID</tt> if present will only validate the validators 65 * in a particular group. 66 */ 67 Object.extend(Prado.Validation, 68 { 69 managers : {}, 70 71 /** 72 * Validate the validators (those that <strong>DO NOT</strong> 73 * belong to a particular group) the form specified by the 74 * <tt>formID</tt> parameter. If <tt>groupID</tt> is specified 75 * then only validators belonging to that group will be validated. 76 * @param string ID of the form to validate 77 * @param string ID of the group to validate. 78 * @param HTMLElement element that calls for validation 79 */ 80 validate : function(formID, groupID, invoker) 81 { 82 if(this.managers[formID]) 83 { 84 return this.managers[formID].validate(groupID, invoker); 85 } 86 else 87 { 88 throw new Error("Form '"+form+"' is not registered with Prado.Validation"); 89 } 90 }, 91 92 /** 93 * Check if the validators are valid for a particular form (and group). 94 * The validators states will not be changed. 95 * The <tt>validate</tt> function should be called first. 96 * @param string ID of the form to validate 97 * @param string ID of the group to validate. 98 */ 99 isValid : function(formID, groupID) 100 { 101 if(this.managers[formID]) 102 return this.managers[formID].isValid(groupID); 103 return true; 104 }, 105 106 /** 107 * Add a new validator to a particular form. 108 * @param string the form that the validator belongs. 109 * @param object a validator 110 * @return object the manager 111 */ 112 addValidator : function(formID, validator) 113 { 114 if(this.managers[formID]) 115 this.managers[formID].addValidator(validator); 116 else 117 throw new Error("A validation manager for form '"+formID+"' needs to be created first."); 118 return this.managers[formID]; 119 }, 120 121 /** 122 * Add a new validation summary. 123 * @param string the form that the validation summary belongs. 124 * @param object a validation summary 125 * @return object manager 126 */ 127 addSummary : function(formID, validator) 128 { 129 if(this.managers[formID]) 130 this.managers[formID].addSummary(validator); 131 else 132 throw new Error("A validation manager for form '"+formID+"' needs to be created first."); 133 return this.managers[formID]; 134 } 135 }); 136 137 Prado.ValidationManager = Class.create(); 138 /** 139 * Validation manager instances. Manages validators for a particular 140 * HTML form. The manager contains references to all the validators 141 * summaries, and their groupings for a particular form. 142 * Generally, <tt>Prado.Validation</tt> methods should be called rather 143 * than calling directly the ValidationManager. 144 */ 145 Prado.ValidationManager.prototype = 146 { 147 validators : [], // list of validators 148 summaries : [], // validation summaries 149 groups : [], // validation groups 150 options : {}, 151 152 /** 153 * <code> 154 * options['FormID']* The ID of HTML form to manage. 155 * </code> 156 */ 157 initialize : function(options) 158 { 159 this.options = options; 160 Prado.Validation.managers[options.FormID] = this; 161 }, 162 163 /** 164 * Validate the validators managed by this validation manager. 165 * @param string only validate validators belonging to a group (optional) 166 * @param HTMLElement element that calls for validation 167 * @return boolean true if all validators are valid, false otherwise. 168 */ 169 validate : function(group, invoker) 170 { 171 if(group) 172 return this._validateGroup(group, invoker); 173 else 174 return this._validateNonGroup(invoker); 175 }, 176 177 /** 178 * Validate a particular group of validators. 179 * @param string ID of the form 180 * @param HTMLElement element that calls for validation 181 * @return boolean false if group is not valid, true otherwise. 182 */ 183 _validateGroup: function(groupID, invoker) 184 { 185 var valid = true; 186 if(this.groups.include(groupID)) 187 { 188 this.validators.each(function(validator) 189 { 190 if(validator.group == groupID) 191 valid = valid & validator.validate(invoker); 192 else 193 validator.hide(); 194 }); 195 } 196 this.updateSummary(groupID, true); 197 return valid; 198 }, 199 200 /** 201 * Validate validators that doesn't belong to any group. 202 * @return boolean false if not valid, true otherwise. 203 * @param HTMLElement element that calls for validation 204 */ 205 _validateNonGroup : function(invoker) 206 { 207 var valid = true; 208 this.validators.each(function(validator) 209 { 210 if(!validator.group) 211 valid = valid & validator.validate(invoker); 212 else 213 validator.hide(); 214 }); 215 this.updateSummary(null, true); 216 return valid; 217 }, 218 219 /** 220 * Gets the state of all the validators, true if they are all valid. 221 * @return boolean true if the validators are valid. 222 */ 223 isValid : function(group) 224 { 225 if(group) 226 return this._isValidGroup(group); 227 else 228 return this._isValidNonGroup(); 229 }, 230 231 /** 232 * @return boolean true if all validators not belonging to a group are valid. 233 */ 234 _isValidNonGroup : function() 235 { 236 var valid = true; 237 this.validators.each(function(validator) 238 { 239 if(!validator.group) 240 valid = valid & validator.isValid; 241 }); 242 return valid; 243 }, 244 245 /** 246 * @return boolean true if all validators belonging to the group are valid. 247 */ 248 _isValidGroup : function(groupID) 249 { 250 var valid = true; 251 if(this.groups.include(groupID)) 252 { 253 this.validators.each(function(validator) 254 { 255 if(validator.group == groupID) 256 valid = valid & validator.isValid; 257 }); 258 } 259 return valid; 260 }, 261 262 /** 263 * Add a validator to this manager. 264 * @param Prado.WebUI.TBaseValidator a new validator 265 */ 266 addValidator : function(validator) 267 { 268 this.validators.push(validator); 269 if(validator.group && !this.groups.include(validator.group)) 270 this.groups.push(validator.group); 271 }, 272 273 /** 274 * Add a validation summary. 275 * @param Prado.WebUI.TValidationSummary validation summary. 276 */ 277 addSummary : function(summary) 278 { 279 this.summaries.push(summary); 280 }, 281 282 /** 283 * Gets all validators that belong to a group or that the validator 284 * group is null and the validator validation was false. 285 * @return array list of validators with error. 286 */ 287 getValidatorsWithError : function(group) 288 { 289 var validators = this.validators.findAll(function(validator) 290 { 291 var notValid = !validator.isValid; 292 var inGroup = group && validator.group == group; 293 var noGroup = validator.group == null; 294 return notValid && (inGroup || noGroup); 295 }); 296 return validators; 297 }, 298 299 /** 300 * Update the summary of a particular group. 301 * @param string validation group to update. 302 */ 303 updateSummary : function(group, refresh) 304 { 305 var validators = this.getValidatorsWithError(group); 306 this.summaries.each(function(summary) 307 { 308 var inGroup = group && summary.group == group; 309 var noGroup = !group && !summary.group; 310 if(inGroup || noGroup) 311 summary.updateSummary(validators, refresh); 312 else 313 summary.hideSummary(true); 314 }); 315 } 316 }; 317 318 /** 319 * TValidationSummary displays a summary of validation errors inline on a Web page, 320 * in a message box, or both. By default, a validation summary will collect 321 * <tt>ErrorMessage</tt> of all failed validators on the page. If 322 * <tt>ValidationGroup</tt> is not empty, only those validators who belong 323 * to the group will show their error messages in the summary. 324 * 325 * The summary can be displayed as a list, as a bulleted list, or as a single 326 * paragraph based on the <tt>DisplayMode</tt> option. 327 * The messages shown can be prefixed with <tt>HeaderText</tt>. 328 * 329 * The summary can be displayed on the Web page and in a message box by setting 330 * the <tt>ShowSummary</tt> and <tt>ShowMessageBox</tt> 331 * options, respectively. 332 */ 333 Prado.WebUI.TValidationSummary = Class.create(); 334 Prado.WebUI.TValidationSummary.prototype = 335 { 336 group : null, 337 options : {}, 338 visible : false, 339 messages : null, 340 341 /** 342 * <code> 343 * options['ID']* Validation summary ID, i.e., an HTML element ID 344 * options['FormID']* HTML form that this summary belongs. 345 * options['ShowMessageBox'] True to show the summary in an alert box. 346 * options['ShowSummary'] True to show the inline summary. 347 * options['HeaderText'] Summary header text 348 * options['DisplayMode'] Summary display style, 'BulletList', 'List', 'SingleParagraph' 349 * options['Refresh'] True to update the summary upon validator state change. 350 * options['ValidationGroup'] Validation summary group 351 * options['Display'] Display mode, 'None', 'Fixed', 'Dynamic'. 352 * options['ScrollToSummary'] True to scroll to the validation summary upon refresh. 353 * </code> 354 */ 355 initialize : function(options) 356 { 357 this.options = options; 358 this.group = options.ValidationGroup; 359 this.messages = $(options.ID); 360 this.visible = this.messages.style.visibility != "hidden" 361 this.visible = this.visible && this.messages.style.display != "none"; 362 Prado.Validation.addSummary(options.FormID, this); 363 }, 364 365 /** 366 * Update the validation summary to show the error message from 367 * validators that failed validation. 368 * @param array list of validators that failed validation. 369 * @param boolean update the summary; 370 */ 371 updateSummary : function(validators, update) 372 { 373 if(validators.length <= 0) 374 { 375 if(update || this.options.Refresh != false) 376 { 377 return this.hideSummary(validators); 378 } 379 return; 380 } 381 382 var refresh = update || this.visible == false || this.options.Refresh != false; 383 384 if(this.options.ShowSummary != false && refresh) 385 { 386 this.updateHTMLMessages(this.getMessages(validators)); 387 this.showSummary(validators); 388 } 389 390 if(this.options.ScrollToSummary != false && refresh) 391 window.scrollTo(this.messages.offsetLeft-20, this.messages.offsetTop-20); 392 393 if(this.options.ShowMessageBox == true && refresh) 394 { 395 this.alertMessages(this.getMessages(validators)); 396 this.visible = true; 397 } 398 }, 399 400 /** 401 * Display the validator error messages as inline HTML. 402 */ 403 updateHTMLMessages : function(messages) 404 { 405 while(this.messages.childNodes.length > 0) 406 this.messages.removeChild(this.messages.lastChild); 407 new Insertion.Bottom(this.messages, this.formatSummary(messages)); 408 }, 409 410 /** 411 * Display the validator error messages as an alert box. 412 */ 413 alertMessages : function(messages) 414 { 415 var text = this.formatMessageBox(messages); 416 setTimeout(function(){ alert(text); },20); 417 }, 418 419 /** 420 * @return array list of validator error messages. 421 */ 422 getMessages : function(validators) 423 { 424 var messages = []; 425 validators.each(function(validator) 426 { 427 var message = validator.getErrorMessage(); 428 if(typeof(message) == 'string' && message.length > 0) 429 messages.push(message); 430 }) 431 return messages; 432 }, 433 434 /** 435 * Hides the validation summary. 436 */ 437 hideSummary : function(validators) 438 { if(typeof(this.options.OnHideSummary) == "function") 439 { 440 this.messages.style.visibility="visible"; 441 this.options.OnHideSummary(this,validators) 442 } 443 else 444 { 445 this.messages.style.visibility="hidden"; 446 if(this.options.Display == "None" || this.options.Display == "Dynamic") 447 this.messages.hide(); 448 } 449 this.visible = false; 450 }, 451 452 /** 453 * Shows the validation summary. 454 */ 455 showSummary : function(validators) 456 { 457 this.messages.style.visibility="visible"; 458 if(typeof(this.options.OnShowSummary) == "function") 459 this.options.OnShowSummary(this,validators); 460 else 461 this.messages.show(); 462 this.visible = true; 463 }, 464 465 /** 466 * Return the format parameters for the summary. 467 * @param string format type, "List", "SingleParagraph" or "BulletList" 468 * @type array formatting parameters 469 */ 470 formats : function(type) 471 { 472 switch(type) 473 { 474 case "List": 475 return { header : "<br />", first : "", pre : "", post : "<br />", last : ""}; 476 case "SingleParagraph": 477 return { header : " ", first : "", pre : "", post : " ", last : "<br />"}; 478 case "BulletList": 479 default: 480 return { header : "", first : "<ul>", pre : "<li>", post : "</li>", last : "</ul>"}; 481 } 482 }, 483 484 /** 485 * Format the message summary. 486 * @param array list of error messages. 487 * @type string formatted message 488 */ 489 formatSummary : function(messages) 490 { 491 var format = this.formats(this.options.DisplayMode); 492 var output = this.options.HeaderText ? this.options.HeaderText + format.header : ""; 493 output += format.first; 494 messages.each(function(message) 495 { 496 output += message.length > 0 ? format.pre + message + format.post : ""; 497 }); 498 // for(var i = 0; i < messages.length; i++) 499 // output += (messages[i].length>0) ? format.pre + messages[i] + format.post : ""; 500 output += format.last; 501 return output; 502 }, 503 /** 504 * Format the message alert box. 505 * @param array a list of error messages. 506 * @type string format message for alert. 507 */ 508 formatMessageBox : function(messages) 509 { 510 var output = this.options.HeaderText ? this.options.HeaderText + "\n" : ""; 511 for(var i = 0; i < messages.length; i++) 512 { 513 switch(this.options.DisplayMode) 514 { 515 case "List": 516 output += messages[i] + "\n"; 517 break; 518 case "BulletList": 519 default: 520 output += " - " + messages[i] + "\n"; 521 break; 522 case "SingleParagraph": 523 output += messages[i] + " "; 524 break; 525 } 526 } 527 return output; 528 } 529 }; 530 531 /** 532 * TBaseValidator serves as the base class for validator controls. 533 * 534 * Validation is performed when a postback control, such as a TButton, 535 * a TLinkButton or a TTextBox (under AutoPostBack mode) is submitting 536 * the page and its <tt>CausesValidation</tt> option is true. 537 * The input control to be validated is specified by <tt>ControlToValidate</tt> 538 * option. 539 */ 540 Prado.WebUI.TBaseValidator = Class.create(); 541 Prado.WebUI.TBaseValidator.prototype = 542 { 543 enabled : true, 544 visible : false, 545 isValid : true, 546 options : {}, 547 _isObserving : {}, 548 group : null, 549 manager : null, 550 message : null, 551 552 /** 553 * <code> 554 * options['ID']* Validator ID, e.g. span with message 555 * options['FormID']* HTML form that the validator belongs 556 * options['ControlToValidate']*HTML form input to validate 557 * options['Display'] Display mode, 'None', 'Fixed', 'Dynamic' 558 * options['ErrorMessage'] Validation error message 559 * options['FocusOnError'] True to focus on validation error 560 * options['FocusElementID'] Element to focus on error 561 * options['ValidationGroup'] Validation group 562 * options['ControlCssClass'] Css class to use on the input upon error 563 * options['OnValidate'] Function to call immediately after validation 564 * options['OnSuccess'] Function to call upon after successful validation 565 * options['OnError'] Function to call upon after error in validation. 566 * options['ObserveChanges'] True to observe changes in input 567 * </code> 568 */ 569 initialize : function(options) 570 { 571 /* options.OnValidate = options.OnValidate || Prototype.emptyFunction; 572 options.OnSuccess = options.OnSuccess || Prototype.emptyFunction; 573 options.OnError = options.OnError || Prototype.emptyFunction; 574 */ 575 this.options = options; 576 this.control = $(options.ControlToValidate); 577 this.message = $(options.ID); 578 this.group = options.ValidationGroup; 579 580 this.manager = Prado.Validation.addValidator(options.FormID, this); 581 }, 582 583 /** 584 * @return string validation error message. 585 */ 586 getErrorMessage : function() 587 { 588 return this.options.ErrorMessage; 589 }, 590 591 /** 592 * Update the validator span, input CSS class, and focus particular 593 * element. Updating the validator control will set the validator 594 * <tt>visible</tt> property to true. 595 */ 596 updateControl: function(focus) 597 { 598 this.refreshControlAndMessage(); 599 600 if(this.options.FocusOnError && !this.isValid ) 601 Prado.Element.focus(this.options.FocusElementID); 602 }, 603 604 refreshControlAndMessage : function() 605 { 606 this.visible = true; 607 if(this.message) 608 { 609 if(this.options.Display == "Dynamic") 610 this.isValid ? this.message.hide() : this.message.show(); 611 this.message.style.visibility = this.isValid ? "hidden" : "visible"; 612 } 613 if(this.control) 614 this.updateControlCssClass(this.control, this.isValid); 615 }, 616 617 /** 618 * Add a css class to the input control if validator is invalid, 619 * removes the css class if valid. 620 * @param object html control element 621 * @param boolean true to remove the css class, false to add. 622 */ 623 updateControlCssClass : function(control, valid) 624 { 625 var CssClass = this.options.ControlCssClass; 626 if(typeof(CssClass) == "string" && CssClass.length > 0) 627 { 628 if(valid) 629 control.removeClassName(CssClass); 630 else 631 control.addClassName(CssClass); 632 } 633 }, 634 635 /** 636 * Hides the validator messages and remove any validation changes. 637 */ 638 hide : function() 639 { 640 this.isValid = true; 641 this.updateControl(); 642 this.visible = false; 643 }, 644 645 /** 646 * Calls evaluateIsValid() function to set the value of isValid property. 647 * Triggers onValidate event and onSuccess or onError event. 648 * @param HTMLElement element that calls for validation 649 * @return boolean true if valid. 650 */ 651 validate : function(invoker) 652 { 653 if(typeof(this.options.OnValidate) == "function") 654 this.options.OnValidate(this, invoker); 655 656 if(this.enabled) 657 this.isValid = this.evaluateIsValid(); 658 else 659 this.isValid = true; 660 661 if(this.isValid) 662 { 663 if(typeof(this.options.OnSuccess) == "function") 664 { 665 this.refreshControlAndMessage(); 666 this.options.OnSuccess(this, invoker); 667 } 668 else 669 this.updateControl(); 670 } 671 else 672 { 673 if(typeof(this.options.OnError) == "function") 674 { 675 this.refreshControlAndMessage(); 676 this.options.OnError(this, invoker); 677 } 678 else 679 this.updateControl(); 680 } 681 682 this.observeChanges(this.control); 683 684 return this.isValid; 685 }, 686 687 /** 688 * Observe changes to the control input, re-validate upon change. If 689 * the validator is not visible, no updates are propagated. 690 * @param HTMLElement element that calls for validation 691 */ 692 observeChanges : function(control) 693 { 694 if(!control) return; 695 696 var canObserveChanges = this.options.ObserveChanges != false; 697 var currentlyObserving = this._isObserving[control.id+this.options.ID]; 698 699 if(canObserveChanges && !currentlyObserving) 700 { 701 var validator = this; 702 703 Event.observe(control, 'change', function() 704 { 705 if(validator.visible) 706 { 707 validator.validate(); 708 validator.manager.updateSummary(validator.group); 709 } 710 }); 711 this._isObserving[control.id+this.options.ID] = true; 712 } 713 }, 714 715 /** 716 * @return string trims the string value, empty string if value is not string. 717 */ 718 trim : function(value) 719 { 720 return typeof(value) == "string" ? value.trim() : ""; 721 }, 722 723 /** 724 * Convert the value to a specific data type. 725 * @param {string} the data type, "Integer", "Double", "Date" or "String" 726 * @param {string} the value to convert. 727 * @type {mixed|null} the converted data value. 728 */ 729 convert : function(dataType, value) 730 { 731 if(typeof(value) == "undefined") 732 value = this.getValidationValue(); 733 var string = new String(value); 734 switch(dataType) 735 { 736 case "Integer": 737 return string.toInteger(); 738 case "Double" : 739 case "Float" : 740 return string.toDouble(this.options.DecimalChar); 741 case "Date": 742 if(typeof(value) != "string") 743 return value; 744 else 745 { 746 var value = string.toDate(this.options.DateFormat); 747 if(value && typeof(value.getTime) == "function") 748 return value.getTime(); 749 else 750 return null; 751 } 752 case "String": 753 return string.toString(); 754 } 755 return value; 756 }, 757 758 /** 759 * The ControlType property comes from TBaseValidator::getClientControlClass() 760 * Be sure to update the TBaseValidator::$_clientClass if new cases are added. 761 * @return mixed control value to validate 762 */ 763 getValidationValue : function(control) 764 { 765 if(!control) 766 control = this.control 767 switch(this.options.ControlType) 768 { 769 case 'TDatePicker': 770 if(control.type == "text") 771 { 772 value = this.trim($F(control)); 773 774 if(this.options.DateFormat) 775 { 776 date = value.toDate(this.options.DateFormat); 777 return date == null ? value : date; 778 } 779 else 780 return value; 781 } 782 else 783 { 784 this.observeDatePickerChanges(); 785 786 return Prado.WebUI.TDatePicker.getDropDownDate(control).getTime(); 787 } 788 case 'THtmlArea': 789 if(typeof tinyMCE != "undefined") 790 tinyMCE.triggerSave(); 791 return this.trim($F(control)); 792 case 'TRadioButton': 793 if(this.options.GroupName) 794 return this.getRadioButtonGroupValue(); 795 default: 796 if(this.isListControlType()) 797 return this.getFirstSelectedListValue(); 798 else 799 return this.trim($F(control)); 800 } 801 }, 802 803 getRadioButtonGroupValue : function() 804 { 805 name = this.control.name; 806 value = ""; 807 $A(document.getElementsByName(name)).each(function(el) 808 { 809 if(el.checked) 810 value = el.value; 811 }); 812 return value; 813 }, 814 815 /** 816 * Observe changes in the drop down list date picker, IE only. 817 */ 818 observeDatePickerChanges : function() 819 { 820 if(Prado.Browser().ie) 821 { 822 var DatePicker = Prado.WebUI.TDatePicker; 823 this.observeChanges(DatePicker.getDayListControl(this.control)); 824 this.observeChanges(DatePicker.getMonthListControl(this.control)); 825 this.observeChanges(DatePicker.getYearListControl(this.control)); 826 } 827 }, 828 829 /** 830 * Gets numeber selections and their values. 831 * @return object returns selected values in <tt>values</tt> property 832 * and number of selections in <tt>checks</tt> property. 833 */ 834 getSelectedValuesAndChecks : function(elements, initialValue) 835 { 836 var checked = 0; 837 var values = []; 838 var isSelected = this.isCheckBoxType(elements[0]) ? 'checked' : 'selected'; 839 elements.each(function(element) 840 { 841 if(element[isSelected] && element.value != initialValue) 842 { 843 checked++; 844 values.push(element.value); 845 } 846 }); 847 return {'checks' : checked, 'values' : values}; 848 }, 849 850 /** 851 * Gets an array of the list control item input elements, for TCheckBoxList 852 * checkbox inputs are returned, for TListBox HTML option elements are returned. 853 * @return array list control option elements. 854 */ 855 getListElements : function() 856 { 857 switch(this.options.ControlType) 858 { 859 case 'TCheckBoxList': case 'TRadioButtonList': 860 var elements = []; 861 for(var i = 0; i < this.options.TotalItems; i++) 862 { 863 var element = $(this.options.ControlToValidate+"_c"+i); 864 if(this.isCheckBoxType(element)) 865 elements.push(element); 866 } 867 return elements; 868 case 'TListBox': 869 var elements = []; 870 var element = $(this.options.ControlToValidate); 871 if(element && (type = element.type.toLowerCase())) 872 { 873 if(type == "select-one" || type == "select-multiple") 874 elements = $A(element.options); 875 } 876 return elements; 877 default: 878 return []; 879 } 880 }, 881 882 /** 883 * @return boolean true if element is of checkbox or radio type. 884 */ 885 isCheckBoxType : function(element) 886 { 887 if(element && element.type) 888 { 889 var type = element.type.toLowerCase(); 890 return type == "checkbox" || type == "radio"; 891 } 892 return false; 893 }, 894 895 /** 896 * @return boolean true if control to validate is of some of the TListControl type. 897 */ 898 isListControlType : function() 899 { 900 var list = ['TCheckBoxList', 'TRadioButtonList', 'TListBox']; 901 return list.include(this.options.ControlType); 902 }, 903 904 /** 905 * @return string gets the first selected list value, initial value if none found. 906 */ 907 getFirstSelectedListValue : function() 908 { 909 var initial = ""; 910 if(typeof(this.options.InitialValue) != "undefined") 911 initial = this.options.InitialValue; 912 var elements = this.getListElements(); 913 var selection = this.getSelectedValuesAndChecks(elements, initial); 914 return selection.values.length > 0 ? selection.values[0] : initial; 915 } 916 } 917 918 919 /** 920 * TRequiredFieldValidator makes the associated input control a required field. 921 * The input control fails validation if its value does not change from 922 * the <tt>InitialValue<tt> option upon losing focus. 923 * <code> 924 * options['InitialValue'] Validation fails if control input equals initial value. 925 * </code> 926 */ 927 Prado.WebUI.TRequiredFieldValidator = Class.extend(Prado.WebUI.TBaseValidator, 928 { 929 /** 930 * @return boolean true if the input value is not empty nor equal to the initial value. 931 */ 932 evaluateIsValid : function() 933 { 934 var inputType = this.control.getAttribute("type"); 935 if(inputType == 'file') 936 { 937 return true; 938 } 939 else 940 { 941 var a = this.getValidationValue(); 942 var b = this.trim(this.options.InitialValue); 943 return(a != b); 944 } 945 } 946 }); 947 948 949 /** 950 * TCompareValidator compares the value entered by the user into an input 951 * control with the value entered into another input control or a constant value. 952 * To compare the associated input control with another input control, 953 * set the <tt>ControlToCompare</tt> option to the ID path 954 * of the control to compare with. To compare the associated input control with 955 * a constant value, specify the constant value to compare with by setting the 956 * <tt>ValueToCompare</tt> option. 957 * 958 * The <tt>DataType</tt> property is used to specify the data type 959 * of both comparison values. Both values are automatically converted to this data 960 * type before the comparison operation is performed. The following value types are supported: 961 * - <b>Integer</b> A 32-bit signed integer data type. 962 * - <b>Float</b> A double-precision floating point number data type. 963 * - <b>Date</b> A date data type. The format can be by the <tt>DateFormat</tt> option. 964 * - <b>String</b> A string data type. 965 * 966 * Use the <tt>Operator</tt> property to specify the type of comparison 967 * to perform. Valid operators include Equal, NotEqual, GreaterThan, GreaterThanEqual, 968 * LessThan and LessThanEqual. 969 * <code> 970 * options['ControlToCompare'] 971 * options['ValueToCompare'] 972 * options['Operator'] 973 * options['Type'] 974 * options['DateFormat'] 975 * </code> 976 */ 977 Prado.WebUI.TCompareValidator = Class.extend(Prado.WebUI.TBaseValidator, 978 { 979 //_observingComparee : false, 980 981 /** 982 * Compares the input to another input or a given value. 983 */ 984 evaluateIsValid : function() 985 { 986 var value = this.getValidationValue(); 987 if (value.length <= 0) 988 return true; 989 990 var comparee = $(this.options.ControlToCompare); 991 992 if(comparee) 993 var compareTo = this.getValidationValue(comparee); 994 else 995 var compareTo = this.options.ValueToCompare || ""; 996 997 var isValid = this.compare(value, compareTo); 998 999 if(comparee) 1000 { 1001 this.updateControlCssClass(comparee, isValid); 1002 this.observeChanges(comparee); 1003 } 1004 return isValid; 1005 }, 1006 1007 /** 1008 * Compares two values, their values are casted to type defined 1009 * by <tt>DataType</tt> option. False is returned if the first 1010 * operand converts to null. Returns true if the second operand 1011 * converts to null. The comparision is done based on the 1012 * <tt>Operator</tt> option. 1013 */ 1014 compare : function(operand1, operand2) 1015 { 1016 var op1, op2; 1017 if((op1 = this.convert(this.options.DataType, operand1)) == null) 1018 return false; 1019 if ((op2 = this.convert(this.options.DataType, operand2)) == null) 1020 return true; 1021 switch (this.options.Operator) 1022 { 1023 case "NotEqual": 1024 return (op1 != op2); 1025 case "GreaterThan": 1026 return (op1 > op2); 1027 case "GreaterThanEqual": 1028 return (op1 >= op2); 1029 case "LessThan": 1030 return (op1 < op2); 1031 case "LessThanEqual": 1032 return (op1 <= op2); 1033 default: 1034 return (op1 == op2); 1035 } 1036 } 1037 }); 1038 1039 /** 1040 * TCustomValidator performs user-defined client-side validation on an 1041 * input component. 1042 * 1043 * To create a client-side validation function, add the client-side 1044 * validation javascript function to the page template. 1045 * The function should have the following signature: 1046 * <code> 1047 * <script type="text/javascript"><!-- 1048 * function ValidationFunctionName(sender, parameter) 1049 * { 1050 * // if(parameter == ...) 1051 * // return true; 1052 * // else 1053 * // return false; 1054 * } 1055 * --> 1056 * </script> 1057 * </code> 1058 * Use the <tt>ClientValidationFunction</tt> option 1059 * to specify the name of the client-side validation script function associated 1060 * with the TCustomValidator. 1061 * <code> 1062 * options['ClientValidationFunction'] custom validation function. 1063 * </code> 1064 */ 1065 Prado.WebUI.TCustomValidator = Class.extend(Prado.WebUI.TBaseValidator, 1066 { 1067 /** 1068 * Calls custom validation function. 1069 */ 1070 evaluateIsValid : function() 1071 { 1072 var value = this.getValidationValue(); 1073 var clientFunction = this.options.ClientValidationFunction; 1074 if(typeof(clientFunction) == "string" && clientFunction.length > 0) 1075 { 1076 validate = clientFunction.toFunction(); 1077 return validate(this, value); 1078 } 1079 return true; 1080 } 1081 }); 1082 1083 /** 1084 * TRangeValidator tests whether an input value is within a specified range. 1085 * 1086 * TRangeValidator uses three key properties to perform its validation. 1087 * The <tt>MinValue</tt> and <tt>MaxValue</tt> options specify the minimum 1088 * and maximum values of the valid range. The <tt>DataType</tt> option is 1089 * used to specify the data type of the value and the minimum and maximum range values. 1090 * These values are converted to this data type before the validation 1091 * operation is performed. The following value types are supported: 1092 * - <b>Integer</b> A 32-bit signed integer data type. 1093 * - <b>Float</b> A double-precision floating point number data type. 1094 * - <b>Date</b> A date data type. The date format can be specified by 1095 * setting <tt>DateFormat</tt> option, which must be recognizable 1096 * by <tt>Date.SimpleParse</tt> javascript function. 1097 * - <b>String</b> A string data type. 1098 * <code> 1099 * options['MinValue'] Minimum range value 1100 * options['MaxValue'] Maximum range value 1101 * options['DataType'] Value data type 1102 * options['DateFormat'] Date format for date data type. 1103 * </code> 1104 */ 1105 Prado.WebUI.TRangeValidator = Class.extend(Prado.WebUI.TBaseValidator, 1106 { 1107 /** 1108 * Compares the input value with a minimum and/or maximum value. 1109 * @return boolean true if the value is empty, returns false if conversion fails. 1110 */ 1111 evaluateIsValid : function() 1112 { 1113 var value = this.getValidationValue(); 1114 if(value.length <= 0) 1115 return true; 1116 if(typeof(this.options.DataType) == "undefined") 1117 this.options.DataType = "String"; 1118 1119 if(this.options.DataType != "StringLength") 1120 { 1121 var min = this.convert(this.options.DataType, this.options.MinValue || null); 1122 var max = this.convert(this.options.DataType, this.options.MaxValue || null); 1123 value = this.convert(this.options.DataType, value); 1124 } 1125 else 1126 { 1127 var min = this.options.MinValue || 0; 1128 var max = this.options.MaxValue || Number.POSITIVE_INFINITY; 1129 value = value.length; 1130 } 1131 1132 if(value == null) 1133 return false; 1134 1135 var valid = true; 1136 1137 if(min != null) 1138 valid = valid && value >= min; 1139 if(max != null) 1140 valid = valid && value <= max; 1141 return valid; 1142 } 1143 }); 1144 1145 /** 1146 * TRegularExpressionValidator validates whether the value of an associated 1147 * input component matches the pattern specified by a regular expression. 1148 * <code> 1149 * options['ValidationExpression'] regular expression to match against. 1150 * </code> 1151 */ 1152 Prado.WebUI.TRegularExpressionValidator = Class.extend(Prado.WebUI.TBaseValidator, 1153 { 1154 /** 1155 * Compare the control input against a regular expression. 1156 */ 1157 evaluateIsValid : function() 1158 { 1159 var value = this.getValidationValue(); 1160 if (value.length <= 0) 1161 return true; 1162 1163 var rx = new RegExp(this.options.ValidationExpression); 1164 var matches = rx.exec(value); 1165 return (matches != null && value == matches[0]); 1166 } 1167 }); 1168 1169 /** 1170 * TEmailAddressValidator validates whether the value of an associated 1171 * input component is a valid email address. 1172 */ 1173 Prado.WebUI.TEmailAddressValidator = Prado.WebUI.TRegularExpressionValidator; 1174 1175 1176 /** 1177 * TListControlValidator checks the number of selection and their values 1178 * for a TListControl that allows multiple selections. 1179 */ 1180 Prado.WebUI.TListControlValidator = Class.extend(Prado.WebUI.TBaseValidator, 1181 { 1182 /** 1183 * @return true if the number of selections and/or their values 1184 * match the requirements. 1185 */ 1186 evaluateIsValid : function() 1187 { 1188 var elements = this.getListElements(); 1189 if(elements && elements.length <= 0) 1190 return true; 1191 1192 this.observeListElements(elements); 1193 1194 var selection = this.getSelectedValuesAndChecks(elements); 1195 return this.isValidList(selection.checks, selection.values); 1196 }, 1197 1198 /** 1199 * Observe list elements for IE browsers of changes 1200 */ 1201 observeListElements : function(elements) 1202 { 1203 if(Prado.Browser().ie && this.isCheckBoxType(elements[0])) 1204 { 1205 var validator = this; 1206 elements.each(function(element) 1207 { 1208 validator.observeChanges(element); 1209 }); 1210 } 1211 }, 1212 1213 /** 1214 * Determine if the number of checked and the checked values 1215 * satisfy the required number of checks and/or the checked values 1216 * equal to the required values. 1217 * @return boolean true if checked values and number of checks are satisfied. 1218 */ 1219 isValidList : function(checked, values) 1220 { 1221 var exists = true; 1222 1223 //check the required values 1224 var required = this.getRequiredValues(); 1225 if(required.length > 0) 1226 { 1227 if(values.length < required.length) 1228 return false; 1229 required.each(function(requiredValue) 1230 { 1231 exists = exists && values.include(requiredValue); 1232 }); 1233 } 1234 1235 var min = typeof(this.options.Min) == "undefined" ? 1236 Number.NEGATIVE_INFINITY : this.options.Min; 1237 var max = typeof(this.options.Max) == "undefined" ? 1238 Number.POSITIVE_INFINITY : this.options.Max; 1239 return exists && checked >= min && checked <= max; 1240 }, 1241 1242 /** 1243 * @return array list of required options that must be selected. 1244 */ 1245 getRequiredValues : function() 1246 { 1247 var required = []; 1248 if(this.options.Required && this.options.Required.length > 0) 1249 required = this.options.Required.split(/,\s*/); 1250 return required; 1251 } 1252 }); 1253 1254 1255 /** 1256 * TDataTypeValidator verifies if the input data is of the type specified 1257 * by <tt>DataType</tt> option. 1258 * The following data types are supported: 1259 * - <b>Integer</b> A 32-bit signed integer data type. 1260 * - <b>Float</b> A double-precision floating point number data type. 1261 * - <b>Date</b> A date data type. 1262 * - <b>String</b> A string data type. 1263 * For <b>Date</b> type, the option <tt>DateFormat</tt> 1264 * will be used to determine how to parse the date string. 1265 */ 1266 Prado.WebUI.TDataTypeValidator = Class.extend(Prado.WebUI.TBaseValidator, 1267 { 1268 evaluateIsValid : function() 1269 { 1270 value = this.getValidationValue(); 1271 if(value.length <= 0) 1272 return true; 1273 return this.convert(this.options.DataType, value) != null; 1274 } 1275 }); 1276 1277 1278
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 21:07:04 2007 | par Balluche grâce à PHPXref 0.7 |