]>
Dogcows Code - chaz/p5-CGI-Ex/blob - lib/CGI/Ex/validate.js
1 // Copyright 2003-2012 - Paul Seamons - ver 2.37
2 // Distributed under the Perl Artistic License without warranty
3 // See perldoc CGI::Ex::Validate for usage
8 function ValidateError (errors
, extra
) {
11 this.as_string
= eob_as_string
;
12 this.as_array
= eob_as_array
;
13 this.as_hash
= eob_as_hash
;
14 this.first_field
= eob_first_field
;
19 function v_error (err
) { alert (err
); return 1 }
21 function v_get_ordered_fields (val_hash
) {
22 if (typeof(val_hash
) != 'object') return {error: v_error("Validation must be an associative array (hash)")};
27 for (var key
in val_hash
) {
28 if (!val_hash
.hasOwnProperty(key
)) continue;
29 if (m
= key
.match(/^(general|group)\s+(\w+)/)) {
30 ARGS
[m
[2]] = val_hash
[key
];
35 field_keys
= field_keys
.sort();
37 var f
= ARGS
.set_hook
; if (f
&& typeof(f
) == 'string') eval("ARGS.set_hook = "+f
);
38 f
= ARGS
.clear_hook
; if (f
&& typeof(f
) == 'string') eval("ARGS.clear_hook = "+f
);
39 f
= ARGS
.set_all_hook
; if (f
&& typeof(f
) == 'string') eval("ARGS.set_all_hook = "+f
);
40 f
= ARGS
.clear_all_hook
; if (f
&& typeof(f
) == 'string') eval("ARGS.clear_all_hook = "+f
);
42 if (f
= ARGS
.validate_if
) {
43 if (typeof(f
) == 'string' || ! f
.length
) f
= [f
];
44 var deps
= v_clean_cond(f
);
49 if (ref
= ARGS
.fields
|| ARGS
['order']) {
50 if (typeof(ref
) != 'object' || ! ref
.length
)
51 return {error:v_error("'group fields' must be a non-empty array")};
52 for (var i
= 0; i
< ref
.length
; i
++) {
54 if (typeof(field
) == 'object') {
55 if (! field
.field
) return {error:v_error("Missing field key in validation")};
57 } else if (field
== 'OR') {
60 var field_val
= val_hash
[field
];
61 if (! field_val
) return {error:v_error('No element found in group for '+field
)};
62 if (typeof(field_val
) == 'object' && ! field_val
['field']) field_val
['field'] = field
;
63 fields
.push(field_val
);
69 for (var i
= 0; i
< fields
.length
; i
++) {
70 var field_val
= fields
[i
];
71 if (typeof(field_val
) != 'object') continue;
72 found
[field_val
.field
] = 1;
75 for (var i
= 0; i
< field_keys
.length
; i
++) {
76 var field
= field_keys
[i
];
77 if (found
[field
]) continue;
78 var field_val
= val_hash
[field
];
79 if (typeof(field_val
) != 'object' || field_val
.length
) return {error:v_error('Found a non-hash value on field '+field
)};
80 if (! field_val
.field
) field_val
.field
= field
;
81 fields
.push(field_val
);
84 for (var i
= 0; i
< fields
.length
; i
++) v_clean_field_val(fields
[i
]);
86 val_hash
['group was_checked'] = {};
87 val_hash
['group was_valid'] = {};
88 val_hash
['group had_error'] = {};
90 return {'fields':fields
, 'args':ARGS
};
93 function v_clean_field_val (field_val
, N_level
) {
94 if (! field_val
.order
) field_val
.order
= v_field_order(field_val
);
95 if (! field_val
.deps
) field_val
.deps
= {};
96 for (var i
= 0; i
< field_val
.order
.length
; i
++) {
97 var k
= field_val
.order
[i
];
99 if (typeof(v
) == 'undefined') return {error:v_error('No matching validation found on field '+field
+' for type '+k
)};
100 if (k
.match(/^(min|max)_in_set_?(\d*)$/)) {
101 if (typeof(v
) == 'string') {
102 if (! (m
= v
.match(/^\s*(\d+)(?:\s*[oO][fF])?\s+(.+)\s*$/))) return {error:v_error("Invalid "+k
+" check "+v
)};
103 field_val
[k
] = m
[2].split(/[\s,]+/);
104 field_val
[k
].unshift(m
[1]);
106 for (var j
= 1; j
< field_val
[k
].length
; j
++) if (field_val
[k
][j
] != field_val
.field
) field_val
.deps
[field_val
[k
][j
]] = 1;
107 } else if (k
.match(/^(enum|compare)_?\d*$/)) {
108 if (typeof(v
) == 'string') field_val
[k
] = v
.split(/\s*\|\|\s*/);
109 } else if (k
.match(/^match_?\d*$/)) {
110 if (typeof(v
) == 'string') v
= field_val
[k
] = v
.split(/\s*\|\|\s*/);
111 for (var j
= 0; j
< v
.length
; j
++) {
112 if (typeof(v
[j
]) != 'string' || v
[j
] == '!') continue;
113 var m
= v
[j
].match(/^\s*(!\s*|)m([^\s\w])(.*)\2([eigsmx]*)\s*$/);
114 if (! m
) return {error:v_error("Not sure how to parse that match ("+v
[j
]+")")};
118 if (opt
.indexOf('e') != -1) return {error:v_error("The e option cannot be used on field "+field_val
.field
+", test "+k
)};
119 opt
= opt
.replace(/[sg]/g,'');
120 v
[j
] = new RegExp(pat
, opt
);
121 if (not
) v
.splice(j
, 0, '!');
123 } else if (k
.match(/^custom_js_?\d*$/)) {
124 if (typeof(v
) == 'string' && v
.match(/^\s*function\s*\(/)) eval("field_val[k] = "+v
);
125 } else if (k
.match(/^(validate|required)_if_?\d*$/)) {
126 if (typeof(v
) == 'string' || ! v
.length
) v
= field_val
[k
] = [v
];
127 var deps
= v_clean_cond(v
, N_level
);
128 for (var k
in deps
) field_val
.deps
[k
] = 2;
133 function v_clean_cond (ifs
, N_level
, ifs_match
) {
134 if (typeof(ifs
) != 'object') { v_error("Need reference v_clean_cond "+typeof(ifs
)); return [] }
135 if (! N_level
) N_level
= 0;
136 if (++N_level
> 10) { v_error("Max dependency level reached " + N_level
); return [] }
140 for (var i
= 0; i
< ifs
.length
; i
++) {
141 if (typeof(ifs
[i
]) == 'string') {
142 if (ifs
[i
].match(/^\s*function\s*\(/)) eval("ifs[i] = "+ifs
[i
]);
143 else if (m
= ifs
[i
].match(/^(.+?)\s+was_valid$/)) ifs
[i
] = {field: m
[1], was_valid:1}
144 else if (m
= ifs
[i
].match(/^(.+?)\s+had_error$/)) ifs
[i
] = {field: m
[1], had_error:1}
145 else if (m
= ifs
[i
].match(/^(.+?)\s+was_checked$/)) ifs
[i
] = {field: m
[1], was_checked:1}
146 else if (m
= ifs
[i
].match(/^(\s*!\s*)(.+)\s*$/)) ifs
[i
] = {field: m
[2], max_in_set: [0, m
[2]]};
147 else if (ifs
[i
] != 'OR') ifs
[i
] = {field: ifs
[i
], required: 1};
149 if (typeof(ifs
[i
]) != 'object') continue;
150 if (! ifs
[i
].field
) { v_error("Missing field key during validate_if"); return [] }
151 deps
[ifs
[i
].field
] = 2;
152 v_clean_field_val(ifs
[i
], N_level
);
153 for (var k
in ifs
[i
].deps
) deps
[k
] = 2;
158 function v_validate (form
, val_hash
) {
159 var clean
= v_get_ordered_fields(val_hash
);
160 if (clean
.error
) return;
161 var fields
= clean
.fields
;
165 var title
= val_hash
['group title'];
166 var v_if
= val_hash
['group validate_if'];
167 if (v_if
&& ! v_check_conditional(form
, v_if
, val_hash
)) return;
174 for (var j
= 0; j
< fields
.length
; j
++) {
176 if (typeof(ref
) != 'object' && ref
== 'OR') {
185 val_hash
['group was_checked'][f
] = 1;
186 val_hash
['group was_valid'][f
] = 1;
187 val_hash
['group had_error'][f
] = 0;
189 var err
= v_validate_buddy(form
, f
, ref
, val_hash
);
191 val_hash
['group had_error'][f
] = 1;
192 val_hash
['group was_valid'][f
] = 0;
193 if (j
<= fields
.length
&& typeof(fields
[j
+ 1] != 'object') && fields
[j
+ 1] == 'OR') {
196 if (hold_error
) err
= hold_error
;
197 for (var k
= 0; k
< err
.length
; k
++) errors
.push(err
[k
]);
206 if (title
) ERRORS
.push(title
);
207 for (var j
= 0; j
< errors
.length
; j
++) ERRORS
.push(errors
[j
]);
210 for (var field
in clean
.args
) {
211 if (errors
.length
== 0 || field
.match(/^(field|order|title|validate_if)$/)) continue;
212 EXTRA
[field
] = clean
.args
[field
];
215 if (ERRORS
.length
) return new ValidateError(ERRORS
, EXTRA
);
219 function v_check_conditional (form
, ifs
, val_hash
, ifs_match
) {
221 for (var i
= 0; i
< ifs
.length
; i
++) {
222 if (typeof(ifs
[i
]) == 'function') {
224 if (! ifs
[i
]({'form':form
})) is_ok
= 0;
225 } else if (typeof(ifs
[i
]) == 'string') {
226 if (ifs
[i
] != 'OR') { v_error("Found non-OR string"); return }
232 var field
= ifs
[i
].field
;
233 field
= field
.replace(/\$(\d+)/g, function (all
, N
) {
234 return (typeof(ifs_match
) != 'object' || typeof(ifs_match
[N
]) == 'undefined') ? '' : ifs_match
[N
];
236 var err
= v_validate_buddy(form
, field
, ifs
[i
], val_hash
);
237 if (err
.length
) is_ok
= 0;
243 function v_filter_types (type
, types
) {
245 var regexp
= new RegExp('^'+type
+'_?\\d*$');
246 for (var i
= 0; i
< types
.length
; i
++)
247 if (types
[i
].match(regexp
)) values
.push(types
[i
]);
251 function v_add_error (errors
,field
,type
,field_val
,ifs_match
,form
,custom_err
) {
252 errors
.push([field
, type
, field_val
, ifs_match
, custom_err
]);
253 if (field_val
.clear_on_error
) {
254 var el
= form
[field
];
255 if (el
&& el
.type
&& el
.type
.match(/(hidden|password|text|textarea|submit)/)) el
.value
= '';
260 function v_field_order (field_val
) {
262 for (var k
in field_val
)
263 if (field_val
.hasOwnProperty(k
) && ! k
.match(/^(field|name|required|was_valid|was_checked|had_error)$/) && ! k
.match(/_error$/)) o
.push(k
);
267 function v_validate_buddy (form
, field
, field_val
, val_hash
, ifs_match
) {
269 if (! form
.elements
|| field_val
.exclude_js
) return [];
270 var types
= field_val
.order
|| v_field_order(field_val
);
273 if (m
= field
.match(/^(!\s*|)m([^\s\w])(.*)\2([eigsmx]*)$/)) {
277 if (opt
.indexOf('e') != -1) { v_error("The e option cannot be used on field "+field
); return [] }
278 opt
= opt
.replace(/[sg]/g,'');
279 var reg
= new RegExp(pat
, opt
);
281 for (var i
= 0; i
< form
.elements
.length
; i
++) {
282 var _field
= form
.elements
[i
].name
;
283 if (! _field
) continue;
284 if ( (not
&& ! (m
= _field
.match(reg
))) || (m
= _field
.match(reg
))) {
285 var err
= v_validate_buddy(form
, _field
, field_val
, val_hash
, m
);
286 for (var j
= 0; j
< err
.length
; j
++) errors
.push(err
[j
]);
292 if (field_val
.was_valid
&& ! val_hash
['group was_valid'][field
]) return v_add_error(errors
, field
, 'was_valid', field_val
, ifs_match
, form
);
293 if (field_val
.had_error
&& ! val_hash
['group had_error'][field
]) return v_add_error(errors
, field
, 'had_error', field_val
, ifs_match
, form
);
294 if (field_val
.was_checked
&& ! val_hash
['group was_checked'][field
]) return v_add_error(errors
, field
, 'was_checked', field_val
, ifs_match
, form
);
296 var _value
= v_get_form_value(form
[field
]);
299 if (typeof(field_val
['default']) != 'undefined'
300 && (typeof(_value
) == 'undefined'
301 || (typeof(_value
) == 'object' && _value
.length
== 0)
302 || ! _value
.length
)) {
303 _value
= field_val
['default'];
307 var values
= (typeof(_value
) == 'object') ? _value : [_value
];
308 var n_values
= (typeof(_value
) == 'undefined') ? 0 : values
.length
;
310 for (var i
= 0; i
< values
.length
; i
++) {
311 if (typeof(values
[i
]) == 'undefined') continue;
312 var orig
= values
[i
];
313 if (! field_val
.do_not_trim
) {
314 values
[i
] = values
[i
].replace(/^\s+/,'');
315 if (v_event
!= 'change') values
[i
] = values
[i
].replace(/\s+$/,'');
317 if (field_val
.trim_control_chars
) values
[i
] = values
[i
].replace(/\t/g,' ').replace(/[\x00-\x1F]/g,'');
318 if (field_val
.to_upper_case
) values
[i
] = values
[i
].toUpperCase();
319 if (field_val
.to_lower_case
) values
[i
] = values
[i
].toLowerCase();
321 var tests
= v_filter_types('replace', types
);
322 for (var k
= 0; k
< tests
.length
; k
++) {
323 var ref
= field_val
[tests
[k
]];
324 ref
= (typeof(ref
) == 'object') ? ref : ref
.split(/\s*\|\|\s*/);
325 for (var j
= 0; j
< ref
.length
; j
++) {
326 if (! (m
= ref
[j
].match(/^\s*s([^\s\w])(.+)\1(.*)\1([eigmx]*)$/)))
327 return v_error("Not sure how to parse that replace "+ref
[j
]);
331 if (opt
.indexOf('e') != -1) { v_error("The e option cannot be used on field "+field
+", replace "+tests
[i
]); return [] }
332 var regexp
= new RegExp(pat
, opt
);
333 values
[i
] = values
[i
].replace(regexp
, swap
);
337 if (orig
!= values
[i
]) modified
= 1;
340 var el
= form
[field
];
341 if (el
) v_set_form_value(el
, values
);
346 var tests
= v_filter_types('validate_if', types
);
347 for (var i
= 0; i
< tests
.length
; i
++) {
348 var ifs
= field_val
[tests
[i
]];
349 var ret
= v_check_conditional(form
, ifs
, val_hash
, ifs_match
);
350 if (ret
) needs_val
++;
352 if (tests
.length
&& ! needs_val
) {
353 if (field_val
.vif_disable
&& val_hash
['group was_valid'][field
]) v_set_disable(form
[field
], true);
354 val_hash
['group was_valid'][field
] = 0;
357 if (field_val
.vif_disable
) v_set_disable(form
[field
], false);
359 var is_required
= field_val
['required'] ? 'required' : '';
361 var tests
= v_filter_types('required_if', types
);
362 for (var i
= 0; i
< tests
.length
; i
++) {
363 var ifs
= field_val
[tests
[i
]];
364 if (! v_check_conditional(form
, ifs
, val_hash
, ifs_match
)) continue;
365 is_required
= tests
[i
];
371 for (var i
= 0; i
< values
.length
; i
++) {
372 if (values
[i
].length
) {
377 if (! found
) return v_add_error(errors
, field
, is_required
, field_val
, ifs_match
, form
);
380 if (field_val
.min_values
&& n_values
< field_val
.min_values
)
381 return v_add_error(errors
, field
, 'min_values', field_val
, ifs_match
, form
);
383 if (typeof(field_val
.max_values
) == 'undefined') field_val
.max_values
= 1;
384 if (field_val
.max_values
&& n_values
> field_val
.max_values
)
385 return v_add_error(errors
, field
, 'max_values', field_val
, ifs_match
, form
);
387 for (var h
= 0; h
< 2 ; h
++) {
388 var minmax
= (h
== 0) ? 'min' : 'max';
389 var tests
= v_filter_types(minmax
+'_in_set', types
);
390 for (var i
= 0; i
< tests
.length
; i
++) {
391 var a
= field_val
[tests
[i
]];
393 for (var k
= 1; k
< a
.length
; k
++) {
394 var _value
= v_get_form_value(form
[a
[k
]]);
396 if (typeof(_value
) == 'undefined') continue;
397 _values
= (typeof(_value
) == 'object') ? _value : [_value
];
398 for (var l
= 0; l
< _values
.length
; l
++) {
399 var _value
= _values
[l
];
400 if (typeof(_value
) != 'undefined' && _value
.length
) n
--;
403 if ( (minmax
== 'min' && n
> 0)
404 || (minmax
== 'max' && n
< 0)) {
405 v_add_error(errors
, field
, tests
[i
], field_val
, ifs_match
, form
);
411 for (var n
= 0; n
< values
.length
; n
++) {
412 var value
= values
[n
];
414 if (typeof field_val
['enum'] != 'undefined') {
416 for (var j
= 0; j
< field_val
['enum'].length
; j
++) if (value
== field_val
['enum'][j
]) { is_found
= 1; break }
418 v_add_error(errors
, field
, 'enum', field_val
, ifs_match
, form
);
423 if (typeof field_val
['type'] != 'undefined')
424 if (! v_check_type(value
, field_val
['type'], field
, form
)) {
425 v_add_error(errors
, field
, 'type', field_val
, ifs_match
, form
);
429 for (var i
= 0; i
< types
.length
; i
++) {
431 var _fv
= field_val
[type
];
433 if (type
.match(/^equals_?\d*$/)) {
434 var not
= _fv
.match(/^!\s*/);
435 if (not
) _fv
= _fv
.substring(not
[0].length
);
437 if (m
= _fv
.match(/^([\"\'])(.*)\1$/)) {
438 if (value
== m
[2]) success
= 1;
440 var value2
= v_get_form_value(form
[_fv
]);
441 if (typeof(value2
) == 'undefined') value2
= '';
442 if (value
== value2
) success
= 1;
444 if (not
&& success
|| ! not
&& ! success
) {
445 v_add_error(errors
, field
, type
, field_val
, ifs_match
, form
);
450 if (type
== 'min_len' && value
.length
< _fv
) v_add_error(errors
, field
, 'min_len', field_val
, ifs_match
, form
);
451 if (type
== 'max_len' && value
.length
> _fv
) v_add_error(errors
, field
, 'max_len', field_val
, ifs_match
, form
);
453 if (type
.match(/^match_?\d*$/)) {
454 for (var j
= 0; j
< _fv
.length
; j
++) {
455 if (typeof(_fv
[j
]) == 'string') continue;
456 var not
= (j
> 0 && typeof(_fv
[j
-1]) == 'string' && _fv
[j
-1] == '!') ? 1 : 0;
457 if ( ( not
&& value
.match(_fv
[j
]))
458 || (! not
&& ! value
.match(_fv
[j
]))) v_add_error(errors
, field
, type
, field_val
, ifs_match
, form
);
462 if (type
.match(/^compare_?\d*$/)) {
463 for (var j
= 0; j
< _fv
.length
; j
++) {
465 if (! comp
) continue;
468 if (m
= comp
.match(/^\s*(>|<|[><!=]=)\s*([\d\.\-]+)\s*$/)) {
469 if (! copy
) copy
= 0;
471 if (m
[1] == '>' ) hold
= (copy
> m
[2])
472 else if (m
[1] == '<' ) hold
= (copy
< m
[2])
473 else if (m
[1] == '>=') hold
= (copy
>= m
[2])
474 else if (m
[1] == '<=') hold
= (copy
<= m
[2])
475 else if (m
[1] == '!=') hold
= (copy
!= m
[2])
476 else if (m
[1] == '==') hold
= (copy
== m
[2])
477 } else if (m
= comp
.match(/^\s*(eq|ne|gt|ge|lt|le)\s+(.+?)\s*$/)) {
478 if ( m
[2].match(/^\"/)) m
[2] = m
[2].replace(/^"(.*)"$/,'$1');
479 else if (m
[2].match(/^\'/)) m
[2] = m
[2].replace(/^'(.*)'$/,'$1');
480 if (m
[1] == 'gt') hold
= (copy
> m
[2])
481 else if (m
[1] == 'lt') hold
= (copy
< m
[2])
482 else if (m
[1] == 'ge') hold
= (copy
>= m
[2])
483 else if (m
[1] == 'le') hold
= (copy
<= m
[2])
484 else if (m
[1] == 'ne') hold
= (copy
!= m
[2])
485 else if (m
[1] == 'eq') hold
= (copy
== m
[2])
487 v_error("Not sure how to compare \""+comp
+"\"");
490 if (! hold
) v_add_error(errors
, field
, type
, field_val
, ifs_match
, form
);
496 for (var i
= 0; i
< types
.length
; i
++) {
498 var _fv
= field_val
[type
];
499 // the js is evaluated and should return 1 for success
500 // or 0 for failure - the variables field, value, and field_val (the hash) are available
501 if (type
.match(/^custom_js_?\d*$/)) {
502 var value
= values
.length
== 1 ? values
[0] : values
;
505 try { ok
= (typeof _fv
== 'function') ? _fv({'value':value
, 'field_val':field_val
, 'form':form
, 'key':field_val
.field
, 'errors':errors
, 'event':v_event
}) : eval(_fv
) } catch (e
) { err
= e
}
506 if (!ok
) v_add_error(errors
, field
, type
, field_val
, ifs_match
, form
, err
);
513 function v_check_type (value
, type
, field
, form
) {
515 type
= type
.toUpperCase();
517 if (type
== 'EMAIL') {
518 if (! value
) return 0;
519 if (! (m
= value
.match(/^(.+)@(.+?)$/))) return 0;
520 if (m
[1].length
> 60) return 0;
521 if (m
[2].length
> 100) return 0;
522 if (! v_check_type(m
[2],'DOMAIN') && ! v_check_type(m
[2],'IP')) return 0;
523 if (! v_check_type(m
[1],'LOCAL_PART')) return 0;
525 } else if (type
== 'LOCAL_PART') {
526 if (typeof(value
) == 'undefined' || ! value
.length
) return 0;
527 if (typeof(v_local_part
) != 'undefined') return (value
.match(v_local_part
) ? 1 : 0);
528 // ignoring all valid quoted string local parts
529 if (value
.match(/[^\w.~!\#\$%\^&*\-=+?]/)) return 0;
531 } else if (type
== 'IP') {
532 if (! value
) return 0;
533 var dig
= value
.split(/\./);
534 if (dig
.length
!= 4) return 0;
535 for (var i
= 0; i
< 4; i
++)
536 if (typeof(dig
[i
]) == 'undefined' || dig
[i
].match(/\D/) || dig
[i
] > 255) return 0;
538 } else if (type
== 'DOMAIN') {
539 if (! value
) return 0;
540 if (! value
.match(/^[a-z0-9.-]{4,255}$/)) return 0;
541 if (value
.match(/^[.\-]/)) return 0;
542 if (value
.match(/(\.-|-\.|\.\.)/)) return 0;
543 if (! (m
= value
.match(/^(.+\.)([a-z]{2,10})$/))) return 0;
544 if (! m
[1].match(/^([a-z0-9\-]{1,63}\.)+$/)) return 0;
546 } else if (type
== 'URL') {
547 if (! value
) return 0;
548 if (! (m
= value
.match(/^https?:\/\/([^\/]+)/i))) return 0;
549 value
= value
.substring(m
[0].length
);
550 var dom
= m
[1].replace(/:\d+$/).replace(/\.$/);
551 if (! v_check_type(dom
,'DOMAIN') && ! v_check_type(m
[1],'IP')) return 0;
552 if (value
&& ! v_check_type(value
,'URI')) return 0;
554 } else if (type
== 'URI') {
555 if (! value
) return 0;
556 if (value
.match(/\s/)) return 0;
558 } else if (type
== 'INT') {
559 if (!value
.match(/^-?(?:0|[1-9]\d*)$/)) return 0;
560 if ((value
< 0) ? value
< -Math
.pow(2,31) : value
> Math
.pow(2,31)-1) return 0;
561 } else if (type
== 'UINT') {
562 if (!value
.match(/^(?:0|[1-9]\d*)$/)) return 0;
563 if (value
> Math
.pow(2,32)-1) return 0;
564 } else if (type
== 'NUM') {
565 if (!value
.match(/^-?(?:0|[1-9]\d*(?:\.\d+)?|0?\.\d+)$/)) return 0;
567 } else if (type
== 'CC') {
568 if (! value
) return 0;
569 if (value
.match(/[^\d
\- ]/)) return 0;
570 value
= value
.replace(/[\- ]/g
, '');
571 if (value
.length
> 16 || value
.length
< 13) return 0;
575 for (var i
= value
.length
- 1; i
>= 0; i
--) {
576 if (++swc
> 2) swc
= 1;
577 var y
= value
.charAt(i
) * swc
;
581 if (sum
% 10) return 0;
587 function v_set_form_value (el
, values
, form
) {
588 if (typeof(el
) == 'string') el
= form
[el
];
589 if (typeof(values
) != 'object') values
= [values
];
591 var type
= (el
.type
&& ! (''+el
).match(/HTMLCollection/)) ? el
.type
.toLowerCase() : '';
592 if (el
.length
&& type
!= 'select-one') {
593 for (var i
= 0; i
< el
.length
; i
++) {
594 if (! el
[i
] || ! el
[i
].type
) continue;
595 v_set_form_value(el
[i
], (el
[i
].type
.match(/^(checkbox|radio)$/) ? values : i
< values
.length
? [values
[i
]] : ['']));
600 if (type
.match(/(hidden|password|text|textarea|submit)/)) return el
.value
= values
[0];
601 if (type
.indexOf('select') != -1) {
602 if (el
.length
) for (var i
= 0; i
< el
.length
; i
++) el
[i
].selected
= (el
[i
].value
== values
[0]) ? true : false;
605 if (type
== 'checkbox' || type
== 'radio') {
606 var f
; for (var i
= 0; i
< values
.length
; i
++) if (values
[i
] == el
.value
) f
= 1;
607 return el
.checked
= f
? true : false;
609 if (type
== 'file') return;
611 alert('Unknown form type for '+el
.name
+': '+type
);
615 function v_set_disable (el
, disable
) {
617 var type
= el
.type
? el
.type
.toLowerCase() : '';
618 if (el
.length
&& type
!= 'select-one') {
619 for (var j
=0;j
<el
.length
;j
++) el
[i
].disabled
= disable
;
620 } else el
.disabled
= disable
;
623 function v_get_form_value (el
, form
) {
624 if (typeof(el
) == 'string') el
= form
[el
];
626 var type
= (el
.type
&& ! (''+el
).match(/HTMLCollection/)) ? el
.type
.toLowerCase() : '';
627 if (el
.length
&& type
!= 'select-one') {
629 for (var j
=0;j
<el
.length
;j
++) {
630 if (type
.indexOf('multiple') != -1) {
631 if (el
[j
].selected
) a
.push(el
[j
].value
);
633 if (el
[j
].checked
) a
.push(v_get_form_value(el
[j
]));
636 if (a
.length
== 0) return '';
637 if (a
.length
== 1) return a
[0];
640 if (! type
) return '';
641 if (type
.match(/(hidden|password|text|textarea|submit)/)) return el
.value
;
642 if (type
.indexOf('select') != -1) {
643 if (! el
.length
) return '';
644 if (el
.selectedIndex
== -1) return '';
645 return el
[el
.selectedIndex
].value
;
647 if (type
== 'checkbox' || type
== 'radio') return el
.checked
? el
.value : '';
648 if (type
== 'file') return el
.value
;
650 alert('Unknown form type for '+el
.name
+': '+type
);
654 function v_find_val () {
655 var key
= arguments
[0];
656 for (var i
= 1; i
< arguments
.length
; i
++) {
657 if (typeof(arguments
[i
]) == 'string') return arguments
[i
];
658 if (typeof(arguments
[i
]) == 'undefined') continue;
659 if (typeof(arguments
[i
][key
]) != 'undefined') return arguments
[i
][key
];
664 function v_get_error_text (err
, extra1
, extra2
) {
667 var field_val
= err
[2];
668 var ifs_match
= err
[3];
669 if (err
.length
== 5 && typeof err
[4] != 'undefined' && err
[4].length
) return err
[4]; // custom error from throw in custom_js
673 if (m
= type
.match(/^(.+?)(_?\d+)$/)) { type
= m
[1] ; dig
= m
[2] }
674 var type_lc
= type
.toLowerCase();
675 var v
= field_val
[type
+ dig
];
677 if (field_val
.delegate_error
) {
678 field
= field_val
.delegate_error
;
679 field
= field
.replace(/\$(\d+)/g, function (all
, N
) {
680 if (typeof(ifs_match
) != 'object'
681 || typeof(ifs_match
[N
]) == 'undefined') return ''
686 var name
= field_val
.name
;
687 if (! name
&& (field
.match(/\W/) || (field
.match(/\d/) && field
.match(/\D/)))) {
688 name
= "The field " +field
;
690 if (! name
) name
= field
.replace(/_
/g
, ' ').replace(/\b(\w)/g, function(all
,str
){return str
.toUpperCase()});
691 name
= name
.replace(/\$(\d+)/g, function (all
, N
) {
692 if (typeof(ifs_match
) != 'object'
693 || typeof(ifs_match
[N
]) == 'undefined') return ''
697 var msg
= v_find_val(type
+ '_error', extra1
, extra2
);
699 if (dig
.length
) msg
= field_val
[type
+ dig
+ '_error'];
700 if (! msg
) msg
= field_val
[type
+ '_error'];
701 if (! msg
) msg
= field_val
['error'];
704 msg
= msg
.replace(/\$(\d+)/g, function (all
, N
) {
705 if (typeof(ifs_match
) != 'object' || typeof(ifs_match
[N
]) == 'undefined') return '';
708 msg
= msg
.replace(/\$field/g, field
);
709 msg
= msg
.replace(/\$name/g, name
);
710 if (v
&& typeof(v
) == 'string') msg
= msg
.replace(/\$value/g, v
);
714 if (type
== 'equals') {
715 var field2
= field_val
["equals" + dig
];
716 var name2
= field_val
["equals" +dig
+ "_name"];
717 if (! name2
) name2
= "the field " +field2
;
718 name2
= name2
.replace(/\$(\d+)/g, function (all
, N
) {
719 return (typeof(ifs_match
) != 'object' || typeof(ifs_match
[N
]) == 'undefined') ? '' : ifs_match
[N
];
721 return name
+ " did not equal " + name2
+".";
723 if (type
== 'min_in_set') return "Not enough fields were chosen from the set ("+v
[0]+' of '+v
.join(", ").replace(/^\d+,\s*/,'')+")";
724 if (type
== 'max_in_set') return "Too many fields were chosen from the set (" +v
[0]+' of '+v
.join(", ").replace(/^\d+,\s*/,'')+")";
727 (type
== 'required' || type
== 'required_if') ? " is required."
728 : type
== 'match' ? " contains invalid characters."
729 : type
== 'compare' ? " did not fit comparison."
730 : type
== 'custom_js' ? " did not match custom_js"+dig
+" check."
731 : type
== 'enum' ? " is not in the given list."
732 : type
== 'min_values' ? " had less than "+v
+" value"+(v
== 1 ? '' : 's')+"."
733 : type
== 'max_values' ? " had more than "+v
+" value"+(v
== 1 ? '' : 's')+"."
734 : type
== 'min_len' ? " was less than "+v
+" character"+(v
== 1 ? '' : 's')+"."
735 : type
== 'max_len' ? " was more than "+v
+" character"+(v
== 1 ? '' : 's')+"."
736 : type
== 'type' ? " did not match type "+v
+"."
737 : type
== 'had_error' ? " had no error (but should have had)."
738 : type
== 'was_valid' ? " was not valid."
739 : type
== 'was_checked'? " was not checked."
740 : alert("Missing error on field "+field
+" for type "+type
+dig
));
745 function eob_as_string (extra
) {
746 var joiner
= v_find_val('as_string_join', extra
, this.extra
, '\n');
747 var header
= v_find_val('as_string_header', extra
, this.extra
, '');
748 var footer
= v_find_val('as_string_footer', extra
, this.extra
, '');
749 return header
+ this.as_array(extra
).join(joiner
) + footer
;
752 function eob_as_array (extra
) {
753 var errors
= this.errors
;
754 var title
= v_find_val('as_array_title', extra
, this.extra
, 'Please correct the following items:');
757 if (title
) has_headings
= 1;
758 else for (var i
= 0; i
< errors
.length
; i
++) if (typeof(errors
[i
]) == 'string') has_headings
= 1;
760 var prefix
= v_find_val('as_array_prefix', extra
, this.extra
, (has_headings
? ' ' : ''));
763 if (title
&& title
.length
) arr
.push(title
);
766 for (var i
= 0; i
< errors
.length
; i
++) {
767 if (typeof(errors
[i
]) == 'string') {
771 var text
= v_get_error_text(errors
[i
], extra
, this.extra
);
772 if (found
[text
]) continue;
774 arr
.push(prefix
+ text
);
781 function eob_as_hash (extra
) {
782 var errors
= this.errors
;
783 var suffix
= v_find_val('as_hash_suffix', extra
, this.extra
, '_error');
784 var joiner
= v_find_val('as_hash_join', extra
, this.extra
, '<br/>');
788 for (var i
= 0; i
< errors
.length
; i
++) {
789 if (typeof(errors
[i
]) == 'string') continue;
790 if (! errors
[i
].length
) continue;
792 var field
= errors
[i
][0];
793 var type
= errors
[i
][1];
794 var field_val
= errors
[i
][2];
795 var ifs_match
= errors
[i
][3];
797 if (! field
) return alert("Missing field name");
798 if (field_val
['delegate_error']) {
799 field
= field_val
['delegate_error'];
800 field
= field
.replace(/\$(\d+)/g, function (all
, N
) {
801 if (typeof(ifs_match
) != 'object'
802 || typeof(ifs_match
[N
]) == 'undefined') return ''
807 var text
= v_get_error_text(errors
[i
], extra
, this.extra
);
808 if (! found
[field
]) found
[field
] = {};
809 if (found
[field
][text
]) continue;
810 found
[field
][text
] = 1;
813 if (! ret
[field
]) ret
[field
] = [];
814 ret
[field
].push(text
);
818 var header
= v_find_val('as_hash_header', extra
, this.extra
, '');
819 var footer
= v_find_val('as_hash_footer', extra
, this.extra
, '');
820 for (var key
in ret
) {
821 if (!ret
.hasOwnProperty(key
)) continue;
822 ret
[key
] = header
+ ret
[key
].join(joiner
) + footer
;
829 function eob_first_field () {
830 for (var i
= 0; i
< this.errors
.length
; i
++) {
831 if (typeof(this.errors
[i
]) != 'object') continue;
832 if (! this.errors
[i
][0]) continue;
833 return this.errors
[i
][0];
840 document
.validate = function (form
, val_hash
) {
841 val_hash
= document
.load_val_hash(form
, val_hash
);
842 if (typeof(val_hash
) == 'undefined') return true;
844 if (v_event
!= 'load') {
845 for (var key
in v_did_inline
) {
846 if (!v_did_inline
.hasOwnProperty(key
)) continue;
847 v_inline_error_clear(key
, val_hash
, form
);
851 var err_obj
= v_validate(form
, val_hash
);
853 var f
= val_hash
['group clear_all_hook'] || document
.validate_clear_all_hook
;
858 var f
= val_hash
['group set_all_hook'] || document
.validate_set_all_hook
;
859 if (f
) f(err_obj
, val_hash
, form
);
861 var field
= err_obj
.first_field();
862 if (field
&& form
[field
]) {
863 if (form
[field
].focus
) form
[field
].focus();
864 else if (form
[field
].length
&& form
[field
][0].focus
) form
[field
][0].focus();
867 if (! val_hash
['group no_inline']) {
868 var hash
= err_obj
.as_hash({as_hash_suffix:""});
869 for (var key
in hash
) {
870 if (!hash
.hasOwnProperty(key
)) continue;
871 v_inline_error_set(key
, hash
[key
], val_hash
, form
);
875 if (v_event
== 'load') {
877 } else if (! val_hash
['group no_confirm']) {
878 return confirm(err_obj
.as_string()) ? false : true;
879 } else if (! val_hash
['group no_alert']) {
880 alert(err_obj
.as_string());
882 } else if (! val_hash
['group no_inline']) {
889 document
.load_val_hash = function (form
, val_hash
) {
890 if (! form
) return alert('Missing form or form name');
891 if (typeof(form
) == 'string') {
892 if (! document
[form
]) return alert('No form by name '+form
);
893 form
= document
[form
];
896 if (form
.val_hash
) return form
.val_hash
;
898 if (typeof(val_hash
) != 'object') {
899 if (typeof(val_hash
) == 'function') {
900 val_hash
= val_hash(formname
);
901 } else if (typeof(val_hash
) == 'undefined') {
903 if (typeof(document
.validation
) != 'undefined') {
904 val_hash
= document
.validation
;
905 } else if (el
= document
.getElementById('validation')) {
906 val_hash
= el
.innerHTML
.replace(/</ig,'<').replace(/>/ig,'>').replace(/&/ig,'&');
910 var yaml
= form
.getAttribute('validation');
912 if (m
= yaml
.match(/^( +)/)) yaml
= yaml
.replace(new RegExp('^'+m
[1], 'g'), '');
913 yaml
= yaml
.replace(/\s*$/,'\n');
917 for (var i
= 0; i
< form
.elements
.length
; i
++) {
918 var name
= form
.elements
[i
].name
;
919 var yaml
= form
.elements
[i
].getAttribute('validation');
920 if (! name
|| ! yaml
) continue;
921 yaml
= yaml
.replace(/\s*$/,'\n').replace(/^(.)/mg,' $1').replace(/^( *[^\s
&*\[\{])/,'\n$1');
922 str
+= name
+':' + yaml
;
925 if (str
) val_hash
= str
+ "group order: [" + order
.join(', ') + "]\n";
928 if (typeof(val_hash
) == 'string') {
929 if (! document
.yaml_load
) return;
930 document
.hide_yaml_errors
= (! document
.show_yaml_errors
);
931 if (location
.search
&& location
.search
.indexOf('show_yaml_errors') != -1)
932 document
.hide_yaml_errors
= 0;
933 val_hash
= document
.yaml_load(val_hash
);
934 if (document
.yaml_error_occured
) return;
935 val_hash
= val_hash
[0];
939 form
.val_hash
= val_hash
;
940 return form
.val_hash
;
943 document
.check_form = function (form
, val_hash
) {
944 if (! form
) return alert('Missing form or form name');
945 if (typeof(form
) == 'string') {
946 if (! document
[form
]) return alert('No form by name '+form
);
947 form
= document
[form
];
950 val_hash
= document
.load_val_hash(form
, val_hash
);
951 if (! val_hash
) return;
953 var types
= val_hash
['group onevent'] || {submit:1};
954 if (typeof(types
) == 'string') types
= types
.split(/\s*,\s*/);
955 if (typeof(types
.length
) != 'undefined') {
957 for (var i
= 0; i
< types
.length
; i
++) t
[types
[i
]] = 1;
960 val_hash
['group onevent'] = types
;
962 if (types
.change
|| types
.blur
) {
963 var clean
= v_get_ordered_fields(val_hash
);
964 if (clean
.error
) return clean
.error
;
966 _add = function (k
, v
) { if (! h
[k
]) h
[k
] = []; h
[k
].push(v
) };
967 for (var i
= 0; i
< clean
.fields
.length
; i
++) {
968 _add(clean
.fields
[i
].field
, clean
.fields
[i
]);
969 for (var j
in clean
.fields
[i
].deps
) if (j
!= clean
.fields
[i
].field
) _add(j
, clean
.fields
[i
]);
972 if (!h
.hasOwnProperty(k
)) continue;
974 if (! el
) return v_error("No form element by the name "+k
);
975 var _change
= !types
.change
? 0 : typeof(types
.change
) == 'object' ? types
.change
[k
] : 1;
976 var _blur
= !types
.blur
? 0 : typeof(types
.blur
) == 'object' ? types
.blur
[k
] : 1;
977 v_el_attach(el
, h
[k
], form
, val_hash
, _change
, _blur
);
982 var orig_submit
= form
.onsubmit
|| function () { return true };
983 form
.onsubmit = function (e
) { v_event
= 'submit'; return document
.validate(this) && orig_submit(e
, this) };
986 if (types
.load
) { v_event
= 'load'; document
.validate(form
) }
989 function v_el_attach (el
, fvs
, form
, val_hash
, _change
, _blur
) {
990 if (!_change
&& !_blur
) return;
992 if (el
.length
) for (var i
= 0; i
< el
.length
; i
++) v_el_attach(el
[i
], fvs
, form
, val_hash
, _change
, _blur
);
995 var types
= val_hash
['group onevent'];
996 var func = function () {
1001 for (var i
= 0; i
< fvs
.length
; i
++) {
1002 var field_val
= fvs
[i
];
1003 var k
= field_val
.field
;
1006 val_hash
['group was_checked'][k
] = 1;
1007 val_hash
['group was_valid'][k
] = 1;
1008 val_hash
['group had_error'][k
] = 0;
1010 var _e
= v_validate_buddy(form
, k
, field_val
, val_hash
);
1012 val_hash
['group had_error'][k
] = 1;
1013 val_hash
['group was_valid'][k
] = 0;
1014 for (var j
= 0; j
< _e
.length
; j
++) e
.push(_e
[j
]);
1016 f
[field_val
.delegate_error
|| field_val
.field
] = _e
.length
? 0 : 1;
1018 for (var k
in f
) if (f
[k
]) v_inline_error_clear(k
, val_hash
, form
);
1019 if (! e
.length
) return;
1020 e
= new ValidateError(e
, {});
1021 e
= e
.as_hash({as_hash_suffix:"", first_only:(val_hash
['group first_only']?1:0)});
1023 if (!e
.hasOwnProperty(k
)) continue;
1024 v_inline_error_set(k
, e
[k
], val_hash
, form
);
1027 if (_blur
) el
.onblur
= func
;
1028 if (_change
&& ! (''+el
).match(/HTMLCollection/)) { // find better way on opera
1029 var type
= el
.type
? el
.type
.toLowerCase() : '';
1030 if (type
.match(/(password|text|textarea)/)) el
.onkeyup
= func
;
1031 else if (type
.match(/(checkbox|radio)/)) el
.onclick
= func
;
1032 else if (type
.match(/(select)/)) el
.onchange
= func
;
1036 function v_inline_error_clear (key
, val_hash
, form
) {
1037 delete(v_did_inline
[key
]);
1038 var f
= val_hash
['group clear_hook'] || document
.validate_clear_hook
;
1039 var g
= val_hash
['group was_valid'] || {};
1040 if (typeof(f
) == 'function') if (f({'key':key
, 'val_hash':val_hash
, 'form':form
, was_valid:g
[key
], 'event':v_event
})) return 1;
1041 var el
= document
.getElementById(key
+ v_find_val('as_hash_suffix', val_hash
, '_error'));
1042 if (el
) el
.innerHTML
= '';
1045 function v_inline_error_set (key
, val
, val_hash
, form
) {
1046 v_did_inline
[key
] = 1;
1047 var f
= val_hash
['group set_hook'] || document
.validate_set_hook
;
1048 if (typeof(f
) == 'function') if (f({'key':key
, 'value':val
, 'val_hash':val_hash
, 'form':form
, 'event':v_event
})) return 1;
1049 var el
= document
.getElementById(key
+ v_find_val('as_hash_suffix', val_hash
, '_error'));
1050 if (el
) el
.innerHTML
= val
;
This page took 0.12044 seconds and 4 git commands to generate.