[ Index ]

PHP Cross Reference of phpwcms V1.4.7 _r403 (01.11.10)

title

Body

[close]

/template/lib/mootools/more/Forms/ -> Form.Validator.js (source)

   1  /*
   2  ---
   3  
   4  script: Form.Validator.js
   5  
   6  name: Form.Validator
   7  
   8  description: A css-class based form validation system.
   9  
  10  license: MIT-style license
  11  
  12  authors:
  13    - Aaron Newton
  14  
  15  requires:
  16    - Core/Options
  17    - Core/Events
  18    - Core/Selectors
  19    - Core/Element.Event
  20    - Core/Element.Style
  21    - Core/JSON
  22    - /Lang
  23    - /Class.Binds
  24    - /Date 
  25    - /Element.Forms
  26    - /Form.Validator.English
  27    - /Element.Shortcuts
  28  
  29  provides: [Form.Validator, InputValidator, FormValidator.BaseValidators]
  30  
  31  ...
  32  */
  33  if (!window.Form) window.Form = {};
  34  
  35  var InputValidator = new Class({
  36  
  37      Implements: [Options],
  38  
  39      options: {
  40          errorMsg: 'Validation failed.',
  41          test: function(field){return true;}
  42      },
  43  
  44      initialize: function(className, options){
  45          this.setOptions(options);
  46          this.className = className;
  47      },
  48  
  49      test: function(field, props){
  50          if (document.id(field)) return this.options.test(document.id(field), props||this.getProps(field));
  51          else return false;
  52      },
  53  
  54      getError: function(field, props){
  55          var err = this.options.errorMsg;
  56          if ($type(err) == 'function') err = err(document.id(field), props||this.getProps(field));
  57          return err;
  58      },
  59  
  60      getProps: function(field){
  61          if (!document.id(field)) return {};
  62          return field.get('validatorProps');
  63      }
  64  
  65  });
  66  
  67  Element.Properties.validatorProps = {
  68  
  69      set: function(props){
  70          return this.eliminate('validatorProps').store('validatorProps', props);
  71      },
  72  
  73      get: function(props){
  74          if (props) this.set(props);
  75          if (this.retrieve('validatorProps')) return this.retrieve('validatorProps');
  76          if (this.getProperty('validatorProps')){
  77              try {
  78                  this.store('validatorProps', JSON.decode(this.getProperty('validatorProps')));
  79              }catch(e){
  80                  return {};
  81              }
  82          } else {
  83              var vals = this.get('class').split(' ').filter(function(cls){
  84                  return cls.test(':');
  85              });
  86              if (!vals.length){
  87                  this.store('validatorProps', {});
  88              } else {
  89                  props = {};
  90                  vals.each(function(cls){
  91                      var split = cls.split(':');
  92                      if (split[1]) {
  93                          try {
  94                              props[split[0]] = JSON.decode(split[1]);
  95                          } catch(e) {}
  96                      }
  97                  });
  98                  this.store('validatorProps', props);
  99              }
 100          }
 101          return this.retrieve('validatorProps');
 102      }
 103  
 104  };
 105  
 106  Form.Validator = new Class({
 107  
 108      Implements:[Options, Events],
 109  
 110      Binds: ['onSubmit'],
 111  
 112      options: {/*
 113          onFormValidate: $empty(isValid, form, event),
 114          onElementValidate: $empty(isValid, field, className, warn),
 115          onElementPass: $empty(field),
 116          onElementFail: $empty(field, validatorsFailed) */
 117          fieldSelectors: 'input, select, textarea',
 118          ignoreHidden: true,
 119          ignoreDisabled: true,
 120          useTitles: false,
 121          evaluateOnSubmit: true,
 122          evaluateFieldsOnBlur: true,
 123          evaluateFieldsOnChange: true,
 124          serial: true,
 125          stopOnFailure: true,
 126          warningPrefix: function(){
 127              return Form.Validator.getMsg('warningPrefix') || 'Warning: ';
 128          },
 129          errorPrefix: function(){
 130              return Form.Validator.getMsg('errorPrefix') || 'Error: ';
 131          }
 132      },
 133  
 134      initialize: function(form, options){
 135          this.setOptions(options);
 136          this.element = document.id(form);
 137          this.element.store('validator', this);
 138          this.warningPrefix = $lambda(this.options.warningPrefix)();
 139          this.errorPrefix = $lambda(this.options.errorPrefix)();
 140          if (this.options.evaluateOnSubmit) this.element.addEvent('submit', this.onSubmit);
 141          if (this.options.evaluateFieldsOnBlur || this.options.evaluateFieldsOnChange) this.watchFields(this.getFields());
 142      },
 143  
 144      toElement: function(){
 145          return this.element;
 146      },
 147  
 148      getFields: function(){
 149          return (this.fields = this.element.getElements(this.options.fieldSelectors));
 150      },
 151  
 152      watchFields: function(fields){
 153          fields.each(function(el){
 154              if (this.options.evaluateFieldsOnBlur)
 155                  el.addEvent('blur', this.validationMonitor.pass([el, false], this));
 156              if (this.options.evaluateFieldsOnChange)
 157                  el.addEvent('change', this.validationMonitor.pass([el, true], this));
 158          }, this);
 159      },
 160  
 161      validationMonitor: function(){
 162          $clear(this.timer);
 163          this.timer = this.validateField.delay(50, this, arguments);
 164      },
 165  
 166      onSubmit: function(event){
 167          if (!this.validate(event) && event) event.preventDefault();
 168          else this.reset();
 169      },
 170  
 171      reset: function(){
 172          this.getFields().each(this.resetField, this);
 173          return this;
 174      },
 175  
 176      validate: function(event){
 177          var result = this.getFields().map(function(field){
 178              return this.validateField(field, true);
 179          }, this).every(function(v){ return v;});
 180          this.fireEvent('formValidate', [result, this.element, event]);
 181          if (this.options.stopOnFailure && !result && event) event.preventDefault();
 182          return result;
 183      },
 184  
 185      validateField: function(field, force){
 186          if (this.paused) return true;
 187          field = document.id(field);
 188          var passed = !field.hasClass('validation-failed');
 189          var failed, warned;
 190          if (this.options.serial && !force){
 191              failed = this.element.getElement('.validation-failed');
 192              warned = this.element.getElement('.warning');
 193          }
 194          if (field && (!failed || force || field.hasClass('validation-failed') || (failed && !this.options.serial))){
 195              var validators = field.className.split(' ').some(function(cn){
 196                  return this.getValidator(cn);
 197              }, this);
 198              var validatorsFailed = [];
 199              field.className.split(' ').each(function(className){
 200                  if (className && !this.test(className, field)) validatorsFailed.include(className);
 201              }, this);
 202              passed = validatorsFailed.length === 0;
 203              if (validators && !field.hasClass('warnOnly')){
 204                  if (passed){
 205                      field.addClass('validation-passed').removeClass('validation-failed');
 206                      this.fireEvent('elementPass', field);
 207                  } else {
 208                      field.addClass('validation-failed').removeClass('validation-passed');
 209                      this.fireEvent('elementFail', [field, validatorsFailed]);
 210                  }
 211              }
 212              if (!warned){
 213                  var warnings = field.className.split(' ').some(function(cn){
 214                      if (cn.test('^warn-') || field.hasClass('warnOnly'))
 215                          return this.getValidator(cn.replace(/^warn-/,''));
 216                      else return null;
 217                  }, this);
 218                  field.removeClass('warning');
 219                  var warnResult = field.className.split(' ').map(function(cn){
 220                      if (cn.test('^warn-') || field.hasClass('warnOnly'))
 221                          return this.test(cn.replace(/^warn-/,''), field, true);
 222                      else return null;
 223                  }, this);
 224              }
 225          }
 226          return passed;
 227      },
 228  
 229      test: function(className, field, warn){
 230          field = document.id(field);
 231          if((this.options.ignoreHidden && !field.isVisible()) || (this.options.ignoreDisabled && field.get('disabled'))) return true;
 232          var validator = this.getValidator(className);
 233          warn = $pick(warn, false);
 234          if (field.hasClass('warnOnly')) warn = true;
 235          var isValid = field.hasClass('ignoreValidation') || (validator ? validator.test(field) : true);
 236          if (validator && field.isVisible()) this.fireEvent('elementValidate', [isValid, field, className, warn]);
 237          if (warn) return true;
 238          return isValid;
 239      },
 240  
 241      resetField: function(field){
 242          field = document.id(field);
 243          if (field){
 244              field.className.split(' ').each(function(className){
 245                  if (className.test('^warn-')) className = className.replace(/^warn-/, '');
 246                  field.removeClass('validation-failed');
 247                  field.removeClass('warning');
 248                  field.removeClass('validation-passed');
 249              }, this);
 250          }
 251          return this;
 252      },
 253  
 254      stop: function(){
 255          this.paused = true;
 256          return this;
 257      },
 258  
 259      start: function(){
 260          this.paused = false;
 261          return this;
 262      },
 263  
 264      ignoreField: function(field, warn){
 265          field = document.id(field);
 266          if (field){
 267              this.enforceField(field);
 268              if (warn) field.addClass('warnOnly');
 269              else field.addClass('ignoreValidation');
 270          }
 271          return this;
 272      },
 273  
 274      enforceField: function(field){
 275          field = document.id(field);
 276          if (field) field.removeClass('warnOnly').removeClass('ignoreValidation');
 277          return this;
 278      }
 279  
 280  });
 281  
 282  Form.Validator.getMsg = function(key){
 283      return MooTools.lang.get('Form.Validator', key);
 284  };
 285  
 286  Form.Validator.adders = {
 287  
 288      validators:{},
 289  
 290      add : function(className, options){
 291          this.validators[className] = new InputValidator(className, options);
 292          //if this is a class (this method is used by instances of Form.Validator and the Form.Validator namespace)
 293          //extend these validators into it
 294          //this allows validators to be global and/or per instance
 295          if (!this.initialize){
 296              this.implement({
 297                  validators: this.validators
 298              });
 299          }
 300      },
 301  
 302      addAllThese : function(validators){
 303          $A(validators).each(function(validator){
 304              this.add(validator[0], validator[1]);
 305          }, this);
 306      },
 307  
 308      getValidator: function(className){
 309          return this.validators[className.split(':')[0]];
 310      }
 311  
 312  };
 313  
 314  $extend(Form.Validator, Form.Validator.adders);
 315  
 316  Form.Validator.implement(Form.Validator.adders);
 317  
 318  Form.Validator.add('IsEmpty', {
 319  
 320      errorMsg: false,
 321      test: function(element){
 322          if (element.type == 'select-one' || element.type == 'select')
 323              return !(element.selectedIndex >= 0 && element.options[element.selectedIndex].value != '');
 324          else
 325              return ((element.get('value') == null) || (element.get('value').length == 0));
 326      }
 327  
 328  });
 329  
 330  Form.Validator.addAllThese([
 331  
 332      ['required', {
 333          errorMsg: function(){
 334              return Form.Validator.getMsg('required');
 335          },
 336          test: function(element){
 337              return !Form.Validator.getValidator('IsEmpty').test(element);
 338          }
 339      }],
 340  
 341      ['minLength', {
 342          errorMsg: function(element, props){
 343              if ($type(props.minLength))
 344                  return Form.Validator.getMsg('minLength').substitute({minLength:props.minLength,length:element.get('value').length });
 345              else return '';
 346          },
 347          test: function(element, props){
 348              if ($type(props.minLength)) return (element.get('value').length >= $pick(props.minLength, 0));
 349              else return true;
 350          }
 351      }],
 352  
 353      ['maxLength', {
 354          errorMsg: function(element, props){
 355              //props is {maxLength:10}
 356              if ($type(props.maxLength))
 357                  return Form.Validator.getMsg('maxLength').substitute({maxLength:props.maxLength,length:element.get('value').length });
 358              else return '';
 359          },
 360          test: function(element, props){
 361              //if the value is <= than the maxLength value, element passes test
 362              return (element.get('value').length <= $pick(props.maxLength, 10000));
 363          }
 364      }],
 365  
 366      ['validate-integer', {
 367          errorMsg: Form.Validator.getMsg.pass('integer'),
 368          test: function(element){
 369              return Form.Validator.getValidator('IsEmpty').test(element) || (/^(-?[1-9]\d*|0)$/).test(element.get('value'));
 370          }
 371      }],
 372  
 373      ['validate-numeric', {
 374          errorMsg: Form.Validator.getMsg.pass('numeric'),
 375          test: function(element){
 376              return Form.Validator.getValidator('IsEmpty').test(element) ||
 377                  (/^-?(?:0$0(?=\d*\.)|[1-9]|0)\d*(\.\d+)?$/).test(element.get('value'));
 378          }
 379      }],
 380  
 381      ['validate-digits', {
 382          errorMsg: Form.Validator.getMsg.pass('digits'),
 383          test: function(element){
 384              return Form.Validator.getValidator('IsEmpty').test(element) || (/^[\d() .:\-\+#]+$/.test(element.get('value')));
 385          }
 386      }],
 387  
 388      ['validate-alpha', {
 389          errorMsg: Form.Validator.getMsg.pass('alpha'),
 390          test: function(element){
 391              return Form.Validator.getValidator('IsEmpty').test(element) ||  (/^[a-zA-Z]+$/).test(element.get('value'));
 392          }
 393      }],
 394  
 395      ['validate-alphanum', {
 396          errorMsg: Form.Validator.getMsg.pass('alphanum'),
 397          test: function(element){
 398              return Form.Validator.getValidator('IsEmpty').test(element) || !(/\W/).test(element.get('value'));
 399          }
 400      }],
 401  
 402      ['validate-date', {
 403          errorMsg: function(element, props){
 404              if (Date.parse){
 405                  var format = props.dateFormat || '%x';
 406                  return Form.Validator.getMsg('dateSuchAs').substitute({date: new Date().format(format)});
 407              } else {
 408                  return Form.Validator.getMsg('dateInFormatMDY');
 409              }
 410          },
 411          test: function(element, props){
 412              if (Form.Validator.getValidator('IsEmpty').test(element)) return true;
 413              var d;
 414              if (Date.parse){
 415                  var format = props.dateFormat || '%x';
 416                  d = Date.parse(element.get('value'));
 417                  var formatted = d.format(format);
 418                  if (formatted != 'invalid date') element.set('value', formatted);
 419                  return !isNaN(d);
 420              } else {
 421                  var regex = /^(\d{2})\/(\d{2})\/(\d{4})$/;
 422                  if (!regex.test(element.get('value'))) return false;
 423                  d = new Date(element.get('value').replace(regex, '$1/$2/$3'));
 424                  return (parseInt(RegExp.$1, 10) == (1 + d.getMonth())) &&
 425                      (parseInt(RegExp.$2, 10) == d.getDate()) &&
 426                      (parseInt(RegExp.$3, 10) == d.getFullYear());
 427              }
 428          }
 429      }],
 430  
 431      ['validate-email', {
 432          errorMsg: Form.Validator.getMsg.pass('email'),
 433          test: function(element){
 434              return Form.Validator.getValidator('IsEmpty').test(element) || (/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i).test(element.get('value'));
 435          }
 436      }],
 437  
 438      ['validate-url', {
 439          errorMsg: Form.Validator.getMsg.pass('url'),
 440          test: function(element){
 441              return Form.Validator.getValidator('IsEmpty').test(element) || (/^(https?|ftp|rmtp|mms):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i).test(element.get('value'));
 442          }
 443      }],
 444  
 445      ['validate-currency-dollar', {
 446          errorMsg: Form.Validator.getMsg.pass('currencyDollar'),
 447          test: function(element){
 448              // [$]1[##][,###]+[.##]
 449              // [$]1###+[.##]
 450              // [$]0.##
 451              // [$].##
 452              return Form.Validator.getValidator('IsEmpty').test(element) ||  (/^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/).test(element.get('value'));
 453          }
 454      }],
 455  
 456      ['validate-one-required', {
 457          errorMsg: Form.Validator.getMsg.pass('oneRequired'),
 458          test: function(element, props){
 459              var p = document.id(props['validate-one-required']) || element.getParent(props['validate-one-required']);
 460              return p.getElements('input').some(function(el){
 461                  if (['checkbox', 'radio'].contains(el.get('type'))) return el.get('checked');
 462                  return el.get('value');
 463              });
 464          }
 465      }]
 466  
 467  ]);
 468  
 469  Element.Properties.validator = {
 470  
 471      set: function(options){
 472          var validator = this.retrieve('validator');
 473          if (validator) validator.setOptions(options);
 474          return this.store('validator:options', options);
 475      },
 476  
 477      get: function(options){
 478          if (options || !this.retrieve('validator')){
 479              if (options || !this.retrieve('validator:options')) this.set('validator', options);
 480              this.store('validator', new Form.Validator(this, this.retrieve('validator:options')));
 481          }
 482          return this.retrieve('validator');
 483      }
 484  
 485  };
 486  
 487  Element.implement({
 488  
 489      validate: function(options){
 490          if (options) this.set('validator', options);
 491          return this.get('validator', options).validate();
 492      }
 493  
 494  });
 495  //legacy
 496  var FormValidator = Form.Validator;


Generated: Tue Nov 16 22:51:00 2010 Cross-referenced by PHPXref 0.7