]> Dogcows Code - chaz/p5-CGI-Ex/blobdiff - lib/CGI/Ex/validate.js
CGI::Ex 2.32
[chaz/p5-CGI-Ex] / lib / CGI / Ex / validate.js
index ad80759bdce2a6f822ed4c2f2662aae775852ad2..7b469115ba07c99fc76b2498ccf5f64454201544 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2007 - Paul Seamons - $Revision: 1.73 $
+// Copyright 2008 - Paul Seamons - $Revision: 1.18 $
 // Distributed under the Perl Artistic License without warranty
 // See perldoc CGI::Ex::Validate for usage
 
@@ -18,65 +18,63 @@ function ValidateError (errors, extra) {
 
 function v_error (err) { alert (err); return 1 }
 
-function v_clean_val_hash (val_hash) {
+function v_get_ordered_fields (val_hash) {
  if (typeof(val_hash) != 'object') return {error: v_error("Validation must be an associative array (hash)")};
 
- var order  = [];
+ var ARGS = {};
+ var field_keys = [];
+ var m;
  for (var key in val_hash) {
   if (key == 'extend') continue; // Protoype Array()
-  if (key.match(/^general\s/)) {
-    var new_key = key.replace(/^general\s+/, 'group ');
-    val_hash[new_key] = val_hash[key];
-    delete(val_hash[key]);
-    key = new_key;
+  if (m = key.match(/^(general|group)\s+(\w+)/)) {
+    ARGS[m[2]] = val_hash[key];
+    continue;
   }
-  order.push(key);
+  field_keys.push(key);
  }
order = order.sort();
field_keys = field_keys.sort();
 
- var f = val_hash['group set_hook'];
if (f && typeof(f) == 'string') eval("val_hash['group set_hook'] = "+f);
- f = val_hash['group clear_hook'];
if (f && typeof(f) == 'string') eval("val_hash['group clear_hook'] = "+f);
+ var f = ARGS.set_hook;   if (f && typeof(f) == 'string') eval("ARGS.set_hook = "+f);
f = ARGS.clear_hook;     if (f && typeof(f) == 'string') eval("ARGS.clear_hook = "+f);
+ f = ARGS.set_all_hook;   if (f && typeof(f) == 'string') eval("ARGS.set_all_hook = "+f);
f = ARGS.clear_all_hook; if (f && typeof(f) == 'string') eval("ARGS.clear_all_hook = "+f);
 
- if (f = val_hash['group validate_if']) {
+ if (f = ARGS.validate_if) {
    if (typeof(f) == 'string' || ! f.length) f = [f];
    var deps = v_clean_cond(f);
  }
 
- var fields = val_hash['group fields'];
- if (fields) {
-  if (typeof(fields) != 'object' || ! fields.length)
+ var fields = [];
+ var ref;
+ if (ref = ARGS.fields || ARGS['order']) {
+  if (typeof(ref) != 'object' || ! ref.length)
    return {error:v_error("'group fields' must be a non-empty array")};
} else {
-  fields = [];
-  var _order = (val_hash['group order']) ? val_hash['group order'] : order;
-  if (typeof(_order) != 'object' || ! _order.length)
-   return {error:v_error("'group order' must be a non-empty array")};
-  for (var i = 0; i < _order.length; i++) {
-   var field = _order[i];
-   if (field.match(/^group\s/)) continue;
-   var field_val = val_hash[field];
-   if (! field_val) {
-    if (field == 'OR') field_val = 'OR';
-    else return {error:v_error('No element found in group for '+field)};
 for (var i = 0; i < ref.length; i++) {
+   var field = ref[i];
+   if (typeof(field) == 'object') {
+    if (! field.field) return {error:v_error("Missing field key in validation")};
+    fields.push(field);
+   } else if (field == 'OR') {
+    fields.push('OR');
+   } else {
+    var field_val = val_hash[field];
+    if (! field_val) return {error:v_error('No element found in group for '+field)};
+    if (typeof(field_val) == 'object' && ! field_val['field']) field_val['field'] = field;
+    fields.push(field_val);
    }
-   if (typeof(field_val) == 'object' && ! field_val['field']) field_val['field'] = field;
-   fields.push(field_val);
   }
  }
 
  var found = {};
  for (var i = 0; i < fields.length; i++) {
   var field_val = fields[i];
-  var field = field_val.field;
-  if (! field) return {error:v_error("Missing field key in validation")};
-  found[field] = 1;
+  if (typeof(field_val) != 'object') continue;
+  found[field_val.field] = 1;
  }
 
- for (var i = 0; i < order.length; i++) {
-  var field = order[i];
-  if (found[field] || field.match(/^group\s/)) continue;
+ for (var i = 0; i < field_keys.length; i++) {
+  var field = field_keys[i];
+  if (found[field]) continue;
   var field_val = val_hash[field];
   if (typeof(field_val) != 'object' || field_val.length) return {error:v_error('Found a non-hash value on field '+field)};
   if (! field_val.field) field_val.field = field;
@@ -89,7 +87,7 @@ function v_clean_val_hash (val_hash) {
  val_hash['group was_valid'] = {};
  val_hash['group had_error'] = {};
 
- return {'fields':fields, 'order':order};
+ return {'fields':fields, 'args':ARGS};
 }
 
 function v_clean_field_val (field_val, N_level) {
@@ -158,9 +156,8 @@ function v_clean_cond (ifs, N_level, ifs_match) {
 }
 
 function v_validate (form, val_hash) {
- var clean  = v_clean_val_hash(val_hash);
+ var clean  = v_get_ordered_fields(val_hash);
  if (clean.error) return;
- var order  = clean.order;
  var fields = clean.fields;
 
  var ERRORS = [];
@@ -210,12 +207,9 @@ function v_validate (form, val_hash) {
   for (var j = 0; j < errors.length; j++) ERRORS.push(errors[j]);
  }
 
- var m;
- for (var j = 0; j < order.length; j++) {
-  var field = order[j];
-  if (! (m = field.match(/^group\s+(\w+)$/))) continue;
-  if (errors.length == 0 || m[1].match(/^(field|order|title|validate_if)$/)) continue;
-   EXTRA[m[1]] = val_hash[field];
+ for (var field in clean.args) {
+  if (errors.length == 0 || field.match(/^(field|order|title|validate_if)$/)) continue;
+  EXTRA[field] = clean.args[field];
  }
 
  if (ERRORS.length) return new ValidateError(ERRORS, EXTRA);
@@ -316,7 +310,10 @@ function v_validate_buddy (form, field, field_val, val_hash, ifs_match) {
  for (var i = 0; i < values.length; i++) {
   if (typeof(values[i]) == 'undefined') continue;
   var orig = values[i];
-  if (! field_val.do_not_trim)      values[i] = values[i].replace(/^\s+/,'').replace(/\s+$/,'');
+  if (! field_val.do_not_trim) {
+    values[i] = values[i].replace(/^\s+/,'');
+    if (v_event != 'change') values[i] = values[i].replace(/\s+$/,'');
+  }
   if (field_val.trim_control_chars) values[i] = values[i].replace(/\t/g,' ').replace(/[\x00-\x1F]/g,'');
   if (field_val.to_upper_case) values[i] = values[i].toUpperCase();
   if (field_val.to_lower_case) values[i] = values[i].toLowerCase();
@@ -515,10 +512,8 @@ function v_check_type (value, type, field, form) {
  } else if (type == 'LOCAL_PART') {
   if (typeof(value) == 'undefined' || ! value.length) return 0;
   if (typeof(v_local_part) != 'undefined') return (value.match(v_local_part) ? 1 : 0);
-  if (value.match(/[^a-z0-9.\-!&+]/)) return 0;
-  if (value.match(/^[.\-]/))          return 0;
-  if (value.match(/[.\-&]$/))         return 0;
-  if (value.match(/(\.-|-\.|\.\.)/))  return 0;
+  // ignoring all valid quoted string local parts
+  if (value.match(/[^\w.~!\#\$%\^&*\-=+?]/)) return 0;
 
  } else if (type == 'IP') {
   if (! value) return 0;
@@ -533,10 +528,7 @@ function v_check_type (value, type, field, form) {
   if (value.match(/^[.\-]/))             return 0;
   if (value.match(/(\.-|-\.|\.\.)/))  return 0;
   if (! (m = value.match(/^(.+\.)([a-z]{2,10})$/))) return 0;
-  if (m[2] == 'name') {
-   if (! m[1].match(/^([a-z0-9\-]{1,62}\.){2}$/)) return 0;
-  } else
-   if (! m[1].match(/^([a-z0-9\-]{1,62}\.)+$/)) return 0;
+  if (! m[1].match(/^([a-z0-9\-]{1,63}\.)+$/)) return 0;
 
  } else if (type == 'URL') {
   if (! value) return 0;
@@ -668,7 +660,11 @@ function v_get_error_text (err, extra1, extra2) {
   });
  }
 
- var name = field_val.name || "The field " +field;
+ var name = field_val.name;
+ if (! name && (field.match(/\W/) || (field.match(/\d/) && field.match(/\D/)))) {
+  name = "The field " +field;
+ }
+ if (! name) name = field.replace(/_/g, ' ').replace(/\b(\w)/g, function(all,str){return str.toUpperCase()});
  name = name.replace(/\$(\d+)/g, function (all, N) {
   if (typeof(ifs_match) != 'object'
     || typeof(ifs_match[N]) == 'undefined') return ''
@@ -679,6 +675,7 @@ function v_get_error_text (err, extra1, extra2) {
  if (! msg) {
    if (dig.length) msg = field_val[type + dig + '_error'];
    if (! msg)      msg = field_val[type +       '_error'];
+   if (! msg)      msg = field_val['error'];
  }
  if (msg) {
   msg = msg.replace(/\$(\d+)/g, function (all, N) {
@@ -829,7 +826,14 @@ document.validate = function (form, val_hash) {
  }
 
  var err_obj = v_validate(form, val_hash);
- if (! err_obj) return true;
+ if (! err_obj) {
+   var f = val_hash['group clear_all_hook'] || document.validate_clear_all_hook;
+   if (f) f();
+   return true;
+ }
+
+ var f = val_hash['group set_all_hook'] || document.validate_set_all_hook;
+ if (f) f(err_obj, val_hash, form);
 
  var field = err_obj.first_field();
  if (field && form[field]) {
@@ -933,7 +937,7 @@ document.check_form = function (form, val_hash) {
  val_hash['group onevent'] = types;
 
  if (types.change || types.blur) {
-  var clean = v_clean_val_hash(val_hash);
+  var clean = v_get_ordered_fields(val_hash);
   if (clean.error) return clean.error;
   var h = {};
   _add = function (k, v) { if (! h[k]) h[k] = []; h[k].push(v) };
@@ -945,7 +949,9 @@ document.check_form = function (form, val_hash) {
    if (k == 'extend') continue; // Protoype Array()
    var el = form[k];
    if (! el) return v_error("No form element by the name "+k);
-   v_el_attach(el, h[k], form, val_hash);
+   var _change = !types.change ? 0 : typeof(types.change) == 'object' ? types.change[k] : 1;
+   var _blur   = !types.blur   ? 0 : typeof(types.blur)   == 'object' ? types.blur[k]   : 1;
+   v_el_attach(el, h[k], form, val_hash, _change, _blur);
   }
  }
 
@@ -957,9 +963,10 @@ document.check_form = function (form, val_hash) {
  if (types.load) { v_event = 'load'; document.validate(form) }
 }
 
-function v_el_attach (el, fvs, form, val_hash) {
+function v_el_attach (el, fvs, form, val_hash, _change, _blur) {
+ if (!_change && !_blur) return;
  if (! el.type) {
-  if (el.length) for (var i = 0; i < el.length; i++) v_el_attach(el[i], fvs, form, val_hash);
+  if (el.length) for (var i = 0; i < el.length; i++) v_el_attach(el[i], fvs, form, val_hash, _change, _blur);
   return;
  }
  var types = val_hash['group onevent'];
@@ -994,8 +1001,8 @@ function v_el_attach (el, fvs, form, val_hash) {
    v_inline_error_set(k, e[k], val_hash, form);
   }
  };
- if (types.blur) el.onblur = func;
- if (types.change && ! (''+el).match(/HTMLCollection/)) { // find better way on opera
+ if (_blur) el.onblur = func;
+ if (_change && ! (''+el).match(/HTMLCollection/)) { // find better way on opera
   var type = el.type ? el.type.toLowerCase() : '';
   if (type.match(/(password|text|textarea)/)) el.onkeyup = func;
   else if (type.match(/(checkbox|radio)/)) el.onclick = func;
This page took 0.028257 seconds and 4 git commands to generate.