]>
Dogcows Code - chaz/p5-CGI-Ex/blob - lib/CGI/Ex/validate.js
1 // Copyright 2007 - Paul Seamons - $Revision: 1.62 $
2 // Distributed under the Perl Artistic License without warranty
3 // See perldoc CGI::Ex::Validate for usage
7 function ValidateError (errors
, extra
) {
10 this.as_string
= eob_as_string
;
11 this.as_array
= eob_as_array
;
12 this.as_hash
= eob_as_hash
;
13 this.first_field
= eob_first_field
;
18 function v_error (err
) { alert (err
); return 1 }
20 function v_clean_val_hash (val_hash
) {
21 if (typeof(val_hash
) != 'object') return {error: v_error("Validation must be an associative array (hash)")};
24 for (var key
in val_hash
) {
25 if (key
== 'extend') continue; // Protoype Array()
26 if (key
.match(/^general\s/)) {
27 var new_key
= key
.replace(/^general\s+/, 'group ');
28 val_hash
[new_key
] = val_hash
[key
];
29 delete(val_hash
[key
]);
36 var f
= val_hash
['group set_hook'];
37 if (f
&& typeof(f
) == 'string') val_hash
['group set_hook'] = eval(f
);
38 f
= val_hash
['group clear_hook'];
39 if (f
&& typeof(f
) == 'string') val_hash
['group clear_hook'] = eval(f
);
41 var fields
= val_hash
['group fields'];
43 if (typeof(fields
) != 'object' || ! fields
.length
)
44 return {error:v_error("'group fields' must be a non-empty array")};
47 var _order
= (val_hash
['group order']) ? val_hash
['group order'] : order
;
48 if (typeof(_order
) != 'object' || ! _order
.length
)
49 return {error:v_error("'group order' must be a non-empty array")};
50 for (var i
= 0; i
< _order
.length
; i
++) {
51 var field
= _order
[i
];
52 if (field
.match(/^group\s/)) continue;
53 var field_val
= val_hash
[field
];
55 if (field
== 'OR') field_val
= 'OR';
56 else return {error:v_error('No element found in group for '+field
)};
58 if (typeof(field_val
) == 'object' && ! field_val
['field']) field_val
['field'] = field
;
59 fields
.push(field_val
);
64 for (var i
= 0; i
< fields
.length
; i
++) {
65 var field_val
= fields
[i
];
66 var field
= field_val
.field
;
67 if (! field
) return {error:v_error("Missing field key in validation")};
71 for (var i
= 0; i
< order
.length
; i
++) {
73 if (found
[field
] || field
.match(/^group\s/)) continue;
74 var field_val
= val_hash
[field
];
75 if (typeof(field_val
) != 'object' || field_val
.length
) {debug(val_hash
);alert(field
);return {error:v_error('Found a non-hash value on field '+field
)};}
76 if (! field_val
.field
) field_val
.field
= field
;
77 fields
.push(field_val
);
80 for (var i
= 0; i
< fields
.length
; i
++) v_clean_field_val(fields
[i
]);
82 return {'fields':fields
, 'order':order
};
85 function v_clean_field_val (field_val
) {
86 if (! field_val
.order
) field_val
.order
= v_field_order(field_val
);
87 if (! field_val
.deps
) field_val
.deps
= {};
88 for (var i
= 0; i
< field_val
.order
.length
; i
++) {
89 var k
= field_val
.order
[i
];
91 if (typeof(v
) == 'undefined') return {error:v_error('No matching validation found on field '+field
+' for type '+k
)};
92 if (k
.match(/^(min|max)_in_set(\d*)$/)) {
93 if (typeof(v
) == 'string') {
94 if (! (m
= v
.match(/^\s*(\d+)(?:\s*[oO][fF])?\s+(.+)\s*$/))) return {error:v_error("Invalid "+k
+" check "+v
)};
95 field_val
[k
] = m
[2].split(/[\s,]+/);
96 field_val
[k
].unshift(m
[1]);
98 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;
99 } else if (k
.match(/^(enum|compare)\d*$/)) {
100 if (typeof(v
) == 'string') field_val
[k
] = v
.split(/\s*\|\|\s*/);
101 } else if (k
.match(/^match\d*$/)) {
102 if (typeof(v
) == 'string') v
= field_val
[k
] = v
.split(/\s*\|\|\s*/);
103 for (var j
= 0; j
< v
.length
; j
++) {
104 if (typeof(v
[j
]) != 'string' || v
[j
] == '!') continue;
105 var m
= v
[j
].match(/^\s*(!\s*|)m([^\s\w])(.*)\2([eigsmx]*)\s*$/);
106 if (! m
) return {error:v_error("Not sure how to parse that match ("+v
[j
]+")")};
110 if (opt
.indexOf('e') != -1) return {error:v_error("The e option cannot be used on field "+field_val
.field
+", test "+k
)};
111 opt
= opt
.replace(/[sg]/g,'');
112 v
[j
] = new RegExp(pat
, opt
);
113 if (not
) v
.splice(j
, 0, '!');
115 } else if (k
.match(/^custom_js\d*$/)) {
116 if (typeof(v
) == 'string' && v
.match(/^\s*function\s*/)) field_val
[k
] = eval(v
);
121 function v_validate (form
, val_hash
) {
122 var clean
= v_clean_val_hash(val_hash
);
123 if (clean
.error
) return;
124 var order
= clean
.order
;
125 var fields
= clean
.fields
;
129 var title
= val_hash
['group title'];
130 var validate_if
= val_hash
['group validate_if'];
131 if (validate_if
&& ! v_check_conditional(form
, validate_if
)) return;
137 for (var j
= 0; j
< fields
.length
; j
++) {
139 if (typeof(ref
) != 'object' && ref
== 'OR') {
145 if (! ref
.field
) return v_error("Missing field key during normal validation");
146 var err
= v_validate_buddy(form
, ref
.field
, ref
);
149 if (j
<= fields
.length
&& typeof(fields
[j
+ 1] != 'object') && fields
[j
+ 1] == 'OR') {
152 if (hold_error
) err
= hold_error
;
153 for (var k
= 0; k
< err
.length
; k
++) errors
.push(err
[k
]);
162 if (title
) ERRORS
.push(title
);
163 for (var j
= 0; j
< errors
.length
; j
++) ERRORS
.push(errors
[j
]);
167 for (var j
= 0; j
< order
.length
; j
++) {
168 var field
= order
[j
];
169 if (! (m
= field
.match(/^group\s+(\w+)$/))) continue;
170 if (errors
.length
== 0 || m
[1].match(/^(field|order|title|validate_if)$/)) continue;
171 EXTRA
[m
[1]] = val_hash
[field
];
174 if (ERRORS
.length
) return new ValidateError(ERRORS
, EXTRA
);
178 function v_check_conditional (form
, ifs
, N_level
, ifs_match
) {
179 if (! N_level
) N_level
= 0;
182 if (! ifs
) return v_error("Need reference passed to check_conditional");
183 if (typeof(ifs
) != 'object' || ! ifs
.length
) ifs
= [ifs
];
187 for (var i
= 0; i
< ifs
.length
; i
++) {
189 if (typeof(ref
) != 'object') {
197 if (m
= field
.match(/^(\s*!\s*)/)) {
198 field
= field
.substring(m
[1].length
);
199 ref
.max_in_set
= [0, field
];
206 if (! is_found
) break;
208 var field
= ref
.field
;
209 if (! field
) return v_error("Missing field key during validate_if");
210 field
= field
.replace(/\$(\d+)/g, function (all
, N
) {
211 return (typeof(ifs_match
) != 'object' || typeof(ifs_match
[N
]) == 'undefined') ? '' : ifs_match
[N
];
214 v_clean_field_val(ref
);
215 var err
= v_validate_buddy(form
, field
, ref
, N_level
);
216 if (err
.length
) is_found
= 0;
221 function v_filter_types (type
, types
) {
223 var regexp
= new RegExp('^'+type
+'_?\\d*$');
224 for (var i
= 0; i
< types
.length
; i
++)
225 if (types
[i
].match(regexp
)) values
.push(types
[i
]);
229 function v_add_error (errors
,field
,type
,field_val
,ifs_match
,form
) {
230 errors
.push([field
, type
, field_val
, ifs_match
]);
231 if (field_val
.clear_on_error
) {
232 var el
= form
[field
];
233 if (el
&& el
.type
&& el
.type
.match(/(hidden|password|text|textarea|submit)/)) el
.value
= '';
238 function v_field_order (field_val
) {
240 for (var k
in field_val
) if (! k
.match(/^(extend|field|name)$/) && ! k
.match(/_error$/)) o
.push(k
);
244 function v_validate_buddy (form
, field
, field_val
, N_level
, ifs_match
) {
246 if (! N_level
) N_level
= 0;
247 if (++N_level
> 10) { v_error("Max dependency level reached " + N_level
); return errors
}
248 if (! form
.elements
|| field_val
.exclude_js
) return errors
;
249 var types
= field_val
.order
|| v_field_order(field_val
);
252 if (m
= field
.match(/^(!\s*|)m([^\s\w])(.*)\2([eigsmx]*)$/)) {
256 if (opt
.indexOf('e') != -1) { v_error("The e option cannot be used on field "+field
); return errors
}
257 opt
= opt
.replace(/[sg]/g,'');
258 var reg
= new RegExp(pat
, opt
);
260 for (var i
= 0; i
< form
.elements
.length
; i
++) {
261 var _field
= form
.elements
[i
].name
;
262 if (! _field
) continue;
263 if ( (not
&& ! (m
= _field
.match(reg
))) || (m
= _field
.match(reg
))) {
264 var err
= v_validate_buddy(form
, _field
, field_val
, N_level
, m
);
265 for (var j
= 0; j
< err
.length
; j
++) errors
.push(err
[j
]);
271 var _value
= v_get_form_value(form
[field
]);
274 if (typeof(field_val
['default']) != 'undefined'
275 && (typeof(_value
) == 'undefined'
276 || (typeof(_value
) == 'object' && _value
.length
== 0)
277 || ! _value
.length
)) {
278 _value
= field_val
['default'];
282 var values
= (typeof(_value
) == 'object') ? _value : [_value
];
283 var n_values
= (typeof(_value
) == 'undefined') ? 0 : values
.length
;
285 for (var i
= 0; i
< values
.length
; i
++) {
286 if (typeof(values
[i
]) == 'undefined') continue;
287 var orig
= values
[i
];
288 if (! field_val
.do_not_trim
) values
[i
] = values
[i
].replace(/^\s+/,'').replace(/\s+$/,'');
289 if (field_val
.trim_control_chars
) values
[i
] = values
[i
].replace(/\t/g,' ').replace(/[\x00-\x1F]/g,'');
290 if (field_val
.to_upper_case
) values
[i
] = values
[i
].toUpperCase();
291 if (field_val
.to_lower_case
) values
[i
] = values
[i
].toLowerCase();
293 var tests
= v_filter_types('replace', types
);
294 for (var k
= 0; k
< tests
.length
; k
++) {
295 var ref
= field_val
[tests
[k
]];
296 ref
= (typeof(ref
) == 'object') ? ref : ref
.split(/\s*\|\|\s*/);
297 for (var j
= 0; j
< ref
.length
; j
++) {
298 if (! (m
= ref
[j
].match(/^\s*s([^\s\w])(.+)\1(.*)\1([eigmx]*)$/)))
299 return v_error("Not sure how to parse that replace "+ref
[j
]);
303 if (opt
.indexOf('e') != -1) { v_error("The e option cannot be used on field "+field
+", replace "+tests
[i
]); return errors
}
304 var regexp
= new RegExp(pat
, opt
);
305 values
[i
] = values
[i
].replace(regexp
, swap
);
309 if (orig
!= values
[i
]) modified
= 1;
311 if (modified
&& n_values
== 1) {
312 var el
= form
[field
];
313 if (el
&& el
.type
&& el
.type
.match(/(hidden|password|text|textarea|submit)/)) el
.value
= values
[0];
318 var tests
= v_filter_types('validate_if', types
);
319 for (var i
= 0; i
< tests
.length
; i
++) {
321 var ifs
= field_val
[tests
[i
]];
322 var ret
= v_check_conditional(form
, ifs
, N_level
, ifs_match
);
323 if (ret
) needs_val
++;
325 if (! needs_val
&& n_vif
) return errors
;
327 var is_required
= '';
328 var tests
= v_filter_types('required', types
);
329 for (var i
= 0; i
< tests
.length
; i
++) {
330 if (! field_val
[tests
[i
]] || field_val
[tests
[i
]] == 0) continue;
331 is_required
= tests
[i
];
335 var tests
= v_filter_types('required_if', types
);
336 for (var i
= 0; i
< tests
.length
; i
++) {
337 var ifs
= field_val
[tests
[i
]];
338 if (! v_check_conditional(form
, ifs
, N_level
, ifs_match
)) continue;
339 is_required
= tests
[i
];
345 for (var i
= 0; i
< values
.length
; i
++) {
346 if (values
[i
].length
) {
351 if (! found
) return v_add_error(errors
, field
, is_required
, field_val
, ifs_match
, form
);
354 if (field_val
.min_values
&& n_values
< field_val
.min_values
)
355 return v_add_error(errors
, field
, 'min_values', field_val
, ifs_match
, form
);
357 if (typeof(field_val
.max_values
) == 'undefined') field_val
.max_values
= 1;
358 if (field_val
.max_values
&& n_values
> field_val
.max_values
)
359 return v_add_error(errors
, field
, 'max_values', field_val
, ifs_match
, form
);
361 for (var h
= 0; h
< 2 ; h
++) {
362 var minmax
= (h
== 0) ? 'min' : 'max';
363 var tests
= v_filter_types(minmax
+'_in_set', types
);
364 for (var i
= 0; i
< tests
.length
; i
++) {
365 var a
= field_val
[tests
[i
]];
367 for (var k
= 1; k
< a
.length
; k
++) {
368 var _value
= v_get_form_value(form
[a
[k
]]);
370 if (typeof(_value
) == 'undefined') continue;
371 _values
= (typeof(_value
) == 'object') ? _value : [_value
];
372 for (var l
= 0; l
< _values
.length
; l
++) {
373 var _value
= _values
[l
];
374 if (typeof(_value
) != 'undefined' && _value
.length
) n
--;
377 if ( (minmax
== 'min' && n
> 0)
378 || (minmax
== 'max' && n
< 0)) {
379 v_add_error(errors
, field
, tests
[i
], field_val
, ifs_match
, form
);
385 for (var i
= 0; i
< types
.length
; i
++) {
387 var _fv
= field_val
[type
];
388 for (var n
= 0; n
< values
.length
; n
++) {
389 var value
= values
[n
];
391 if (type
.match(/^enum\d*$/)) {
393 for (var j
= 0; j
< _fv
.length
; j
++) if (value
== _fv
[j
]) { is_found
= 1; break }
394 if (! is_found
) v_add_error(errors
, field
, type
, field_val
, ifs_match
, form
);
397 if (type
.match(/^equals\d*$/)) {
398 var not
= _fv
.match(/^!\s*/);
399 if (not
) _fv
= _fv
.substring(not
[0].length
);
401 if (m
= _fv
.match(/^([\"\'])(.*)\1$/)) {
402 if (value
== m
[2]) success
= 1;
404 var value2
= v_get_form_value(form
[_fv
]);
405 if (typeof(value2
) == 'undefined') value2
= '';
406 if (value
== value2
) success
= 1;
408 if (not
&& success
|| ! not
&& ! success
)
409 v_add_error(errors
, field
, type
, field_val
, ifs_match
, form
);
412 if (type
== 'min_len' && value
.length
< _fv
) v_add_error(errors
, field
, 'min_len', field_val
, ifs_match
, form
);
413 if (type
== 'max_len' && value
.length
> _fv
) v_add_error(errors
, field
, 'max_len', field_val
, ifs_match
, form
);
415 if (type
.match(/^match\d*$/)) {
416 for (var j
= 0; j
< _fv
.length
; j
++) {
417 if (typeof(_fv
[j
]) == 'string') continue;
418 var not
= (j
> 0 && typeof(_fv
[j
-1]) == 'string' && _fv
[j
-1] == '!') ? 1 : 0;
419 if ( ( not
&& value
.match(_fv
[j
]))
420 || (! not
&& ! value
.match(_fv
[j
]))) v_add_error(errors
, field
, type
, field_val
, ifs_match
, form
);
424 if (type
.match(/^compare\d*$/)) {
425 for (var j
= 0; j
< _fv
.length
; j
++) {
427 if (! comp
) continue;
430 if (m
= comp
.match(/^\s*(>|<|[><!=]=)\s*([\d\.\-]+)\s*$/)) {
431 if (! copy
) copy
= 0;
433 if (m
[1] == '>' ) hold
= (copy
> m
[2])
434 else if (m
[1] == '<' ) hold
= (copy
< m
[2])
435 else if (m
[1] == '>=') hold
= (copy
>= m
[2])
436 else if (m
[1] == '<=') hold
= (copy
<= m
[2])
437 else if (m
[1] == '!=') hold
= (copy
!= m
[2])
438 else if (m
[1] == '==') hold
= (copy
== m
[2])
439 } else if (m
= comp
.match(/^\s*(eq|ne|gt|ge|lt|le)\s+(.+?)\s*$/)) {
440 if ( m
[2].match(/^\"/)) m
[2] = m
[2].replace(/^"(.*)"$/,'$1');
441 else if (m
[2].match(/^\'/)) m
[2] = m
[2].replace(/^'(.*)'$/,'$1');
442 if (m
[1] == 'gt') hold
= (copy
> m
[2])
443 else if (m
[1] == 'lt') hold
= (copy
< m
[2])
444 else if (m
[1] == 'ge') hold
= (copy
>= m
[2])
445 else if (m
[1] == 'le') hold
= (copy
<= m
[2])
446 else if (m
[1] == 'ne') hold
= (copy
!= m
[2])
447 else if (m
[1] == 'eq') hold
= (copy
== m
[2])
449 v_error("Not sure how to compare \""+comp
+"\"");
452 if (! hold
) v_add_error(errors
, field
, type
, field_val
, ifs_match
, form
);
456 if (type
.match(/^type\d*$/))
457 if (! v_check_type(value
, _fv
, field
, form
))
458 v_add_error(errors
, field
, type
, field_val
, ifs_match
, form
);
461 // the js is evaluated and should return 1 for success
462 // or 0 for failure - the variables field, value, and field_val (the hash) are available
463 if (type
.match(/^custom_js\d*$/)) {
464 var value
= values
.length
== 1 ? values
[0] : values
;
465 if (typeof(_fv
) == 'function'
466 ? ! _fv({'value':value
, 'field_val':field_val
, 'form':form
, 'key':field_val
.field
})
467 : ! eval(_fv
)) v_add_error(errors
, field
, type
, field_val
, ifs_match
, form
);
474 function v_check_type (value
, type
, field
, form
) {
476 type
= type
.toUpperCase();
478 if (type
== 'EMAIL') {
479 if (! value
) return 0;
480 if (! (m
= value
.match(/^(.+)@(.+?)$/))) return 0;
481 if (m
[1].length
> 60) return 0;
482 if (m
[2].length
> 100) return 0;
483 if (! v_check_type(m
[2],'DOMAIN') && ! v_check_type(m
[2],'IP')) return 0;
484 if (! v_check_type(m
[1],'LOCAL_PART')) return 0;
486 } else if (type
== 'LOCAL_PART') {
487 if (typeof(value
) == 'undefined' || ! value
.length
) return 0;
488 if (typeof(v_local_part
) != 'undefined') return (value
.match(v_local_part
) ? 1 : 0);
489 if (value
.match(/[^a-z0-9.\-!&+]/)) return 0;
490 if (value
.match(/^[.\-]/)) return 0;
491 if (value
.match(/[.\-&]$/)) return 0;
492 if (value
.match(/(\.-|-\.|\.\.)/)) return 0;
494 } else if (type
== 'IP') {
495 if (! value
) return 0;
496 var dig
= value
.split(/\./);
497 if (dig
.length
!= 4) return 0;
498 for (var i
= 0; i
< 4; i
++)
499 if (typeof(dig
[i
]) == 'undefined' || dig
[i
].match(/\D/) || dig
[i
] > 255) return 0;
501 } else if (type
== 'DOMAIN') {
502 if (! value
) return 0;
503 if (! value
.match(/^[a-z0-9.-]{4,255}$/)) return 0;
504 if (value
.match(/^[.\-]/)) return 0;
505 if (value
.match(/(\.-|-\.|\.\.)/)) return 0;
506 if (! (m
= value
.match(/\.([a-z]+)$/))) return 0;
507 value
= value
.substring(0,value
.lastIndexOf('.'));
508 if (m
[1] == 'name') {
509 if (! value
.match(/^[a-z0-9][a-z0-9\-]{0,62}\.[a-z0-9][a-z0-9\-]{0,62}$/)) return 0;
511 if (! value
.match(/^([a-z0-9][a-z0-9\-]{0,62}\.)*[a-z0-9][a-z0-9\-]{0,62}$/)) return 0;
513 } else if (type
== 'URL') {
514 if (! value
) return 0;
515 if (! (m
= value
.match(/^https?:\/\/([^\/]+)/i))) return 0;
516 value
= value
.substring(m
[0].length
);
517 var dom
= m
[1].replace(/:\d+$/).replace(/\.$/);
518 if (! v_check_type(dom
,'DOMAIN') && ! v_check_type(m
[1],'IP')) return 0;
519 if (value
&& ! v_check_type(value
,'URI')) return 0;
521 } else if (type
== 'URI') {
522 if (! value
) return 0;
523 if (value
.match(/\s/)) return 0;
525 } else if (type
== 'CC') {
526 if (! value
) return 0;
527 if (value
.match(/[^\d
\- ]/)) return 0;
528 value
= value
.replace(/[\- ]/g
, '');
529 if (value
.length
> 16 || value
.length
< 13) return 0;
533 for (var i
= value
.length
- 1; i
>= 0; i
--) {
534 if (++swc
> 2) swc
= 1;
535 var y
= value
.charAt(i
) * swc
;
539 if (sum
% 10) return 0;
545 function v_get_form_value (el
) {
547 if (el
.disabled
) return '';
548 var type
= el
.type
? el
.type
.toLowerCase() : '';
549 if (el
.length
&& type
!= 'select-one') {
551 for (var j
=0;j
<el
.length
;j
++) {
552 if (type
.indexOf('multiple') != -1) {
553 if (el
[j
].selected
) a
.push(el
[j
].value
);
555 if (el
[j
].checked
) a
.push(v_get_form_value(el
[j
]));
558 if (a
.length
== 0) return '';
559 if (a
.length
== 1) return a
[0];
562 if (! type
) return '';
563 if (type
.match(/(hidden|password|text|textarea|submit)/)) return el
.value
;
564 if (type
.indexOf('select') != -1) {
565 if (! el
.length
) return '';
566 return el
[el
.selectedIndex
].value
;
568 if (type
== 'checkbox' || type
== 'radio') return el
.checked
? el
.value : '';
569 if (type
== 'file') return el
.value
;
571 alert('Unknown form type for '+el
.name
+': '+type
);
575 function v_find_val () {
576 var key
= arguments
[0];
577 for (var i
= 1; i
< arguments
.length
; i
++) {
578 if (typeof(arguments
[i
]) == 'string') return arguments
[i
];
579 if (typeof(arguments
[i
]) == 'undefined') continue;
580 if (typeof(arguments
[i
][key
]) != 'undefined') return arguments
[i
][key
];
585 function v_get_error_text (err
, extra1
, extra2
) {
588 var field_val
= err
[2];
589 var ifs_match
= err
[3];
592 var dig
= (m
= type
.match(/(_?\d+)$/)) ? m
[1] : '';
593 var type_lc
= type
.toLowerCase();
594 var v
= field_val
[type
+ dig
];
596 if (field_val
.delegate_error
) {
597 field
= field_val
.delegate_error
;
598 field
= field
.replace(/\$(\d+)/g, function (all
, N
) {
599 if (typeof(ifs_match
) != 'object'
600 || typeof(ifs_match
[N
]) == 'undefined') return ''
605 var name
= field_val
.name
|| "The field " +field
;
606 name
= name
.replace(/\$(\d+)/g, function (all
, N
) {
607 if (typeof(ifs_match
) != 'object'
608 || typeof(ifs_match
[N
]) == 'undefined') return ''
612 var msg
= v_find_val(type
+ '_error', extra1
, extra2
);
614 if (dig
.length
) msg
= field_val
[type
+ dig
+ '_error'];
615 if (! msg
) msg
= field_val
[type
+ '_error'];
618 msg
= msg
.replace(/\$(\d+)/g, function (all
, N
) {
619 if (typeof(ifs_match
) != 'object' || typeof(ifs_match
[N
]) == 'undefined') return '';
622 msg
= msg
.replace(/\$field/g, field
);
623 msg
= msg
.replace(/\$name/g, name
);
624 if (v
&& typeof(v
) == 'string') msg
= msg
.replace(/\$value/g, v
);
628 if (type
== 'equals') {
629 var field2
= field_val
["equals" + dig
];
630 var name2
= field_val
["equals" +dig
+ "_name"];
631 if (! name2
) name2
= "the field " +field2
;
632 name2
= name2
.replace(/\$(\d+)/g, function (all
, N
) {
633 return (typeof(ifs_match
) != 'object' || typeof(ifs_match
[N
]) == 'undefined') ? '' : ifs_match
[N
];
635 return name
+ " did not equal " + name2
+".";
637 if (type
== 'min_in_set') return "Not enough fields were chosen from the set ("+v
[0]+' of '+v
.join(", ").replace(/^\d+,\s*/,'')+")";
638 if (type
== 'max_in_set') return "Too many fields were chosen from the set (" +v
[0]+' of '+v
.join(", ").replace(/^\d+,\s*/,'')+")";
641 (type
== 'required' || type
== 'required_if') ? " is required."
642 : type
== 'match' ? " contains invalid characters."
643 : type
== 'compare' ? " did not fit comparison."
644 : type
== 'custom_js' ? " did not match custom_js"+dig
+" check."
645 : type
== 'enum' ? " is not in the given list."
646 : type
== 'min_values' ? " had less than "+v
+" value"+(v
== 1 ? '' : 's')+"."
647 : type
== 'max_values' ? " had more than "+v
+" value"+(v
== 1 ? '' : 's')+"."
648 : type
== 'min_len' ? " was less than "+v
+" character"+(v
== 1 ? '' : 's')+"."
649 : type
== 'max_len' ? " was more than "+v
+" character"+(v
== 1 ? '' : 's')+"."
650 : type
== 'type' ? " did not match type "+v
+"."
651 : alert("Missing error on field "+field
+" for type "+type
+dig
));
656 function eob_as_string (extra
) {
657 var joiner
= v_find_val('as_string_join', extra
, this.extra
, '\n');
658 var header
= v_find_val('as_string_header', extra
, this.extra
, '');
659 var footer
= v_find_val('as_string_footer', extra
, this.extra
, '');
660 return header
+ this.as_array(extra
).join(joiner
) + footer
;
663 function eob_as_array (extra
) {
664 var errors
= this.errors
;
665 var title
= v_find_val('as_array_title', extra
, this.extra
, 'Please correct the following items:');
668 if (title
) has_headings
= 1;
669 else for (var i
= 0; i
< errors
.length
; i
++) if (typeof(errors
[i
]) == 'string') has_headings
= 1;
671 var prefix
= v_find_val('as_array_prefix', extra
, this.extra
, (has_headings
? ' ' : ''));
674 if (title
&& title
.length
) arr
.push(title
);
677 for (var i
= 0; i
< errors
.length
; i
++) {
678 if (typeof(errors
[i
]) == 'string') {
682 var text
= v_get_error_text(errors
[i
], extra
, this.extra
);
683 if (found
[text
]) continue;
685 arr
.push(prefix
+ text
);
692 function eob_as_hash (extra
) {
693 var errors
= this.errors
;
694 var suffix
= v_find_val('as_hash_suffix', extra
, this.extra
, '_error');
695 var joiner
= v_find_val('as_hash_join', extra
, this.extra
, '<br/>');
699 for (var i
= 0; i
< errors
.length
; i
++) {
700 if (typeof(errors
[i
]) == 'string') continue;
701 if (! errors
[i
].length
) continue;
703 var field
= errors
[i
][0];
704 var type
= errors
[i
][1];
705 var field_val
= errors
[i
][2];
706 var ifs_match
= errors
[i
][3];
708 if (! field
) return alert("Missing field name");
709 if (field_val
['delegate_error']) {
710 field
= field_val
['delegate_error'];
711 field
= field
.replace(/\$(\d+)/g, function (all
, N
) {
712 if (typeof(ifs_match
) != 'object'
713 || typeof(ifs_match
[N
]) == 'undefined') return ''
718 var text
= v_get_error_text(errors
[i
], extra
, this.extra
);
719 if (! found
[field
]) found
[field
] = {};
720 if (found
[field
][text
]) continue;
721 found
[field
][text
] = 1;
724 if (! ret
[field
]) ret
[field
] = [];
725 ret
[field
].push(text
);
729 var header
= v_find_val('as_hash_header', extra
, this.extra
, '');
730 var footer
= v_find_val('as_hash_footer', extra
, this.extra
, '');
731 for (var key
in ret
) {
732 if (key
== 'extend') continue; // Protoype Array()
733 ret
[key
] = header
+ ret
[key
].join(joiner
) + footer
;
740 function eob_first_field () {
741 for (var i
= 0; i
< this.errors
.length
; i
++) {
742 if (typeof(this.errors
[i
]) != 'object') continue;
743 if (! this.errors
[i
][0]) continue;
744 return this.errors
[i
][0];
751 document
.validate = function (form
, val_hash
) {
752 val_hash
= document
.load_val_hash(form
, val_hash
);
753 if (typeof(val_hash
) == 'undefined') return true;
755 for (var key
in v_did_inline
) {
756 if (key
== 'extend') continue; // Protoype Array()
757 v_inline_error_clear(key
, val_hash
, form
);
760 var err_obj
= v_validate(form
, val_hash
);
761 if (! err_obj
) return true;
763 var field
= err_obj
.first_field();
764 if (field
&& form
[field
]) {
765 if (form
[field
].focus
) form
[field
].focus();
766 else if (form
[field
].length
&& form
[field
][0].focus
) form
[field
][0].focus();
769 if (! val_hash
['group no_inline']) {
770 var hash
= err_obj
.as_hash({as_hash_suffix:""});
771 for (var key
in hash
) {
772 if (key
== 'extend') continue; // Protoype Array()
773 v_inline_error_set(key
, hash
[key
], val_hash
, form
);
777 if (! val_hash
['group no_confirm']) {
778 return confirm(err_obj
.as_string()) ? false : true;
779 } else if (! val_hash
['group no_alert']) {
780 alert(err_obj
.as_string());
782 } else if (! val_hash
['group no_inline']) {
789 document
.load_val_hash = function (form
, val_hash
) {
790 if (! form
) return alert('Missing form or form name');
791 if (typeof(form
) == 'string') {
792 if (! document
[form
]) return alert('No form by name '+form
);
793 form
= document
[form
];
796 if (form
.val_hash
) return form
.val_hash
;
798 if (typeof(val_hash
) != 'object') {
799 if (typeof(val_hash
) == 'function') {
800 val_hash
= val_hash(formname
);
801 } else if (typeof(val_hash
) == 'undefined') {
803 if (typeof(document
.validation
) != 'undefined') {
804 val_hash
= document
.validation
;
805 } else if (el
= document
.getElementById('validation')) {
806 val_hash
= el
.innerHTML
.replace(/</ig,'<').replace(/>/ig,'>').replace(/&/ig,'&');
810 var yaml
= form
.getAttribute('validation');
812 if (m
= yaml
.match(/^( +)/)) yaml
= yaml
.replace(new RegExp('^'+m
[1], 'g'), '');
813 yaml
= yaml
.replace(/\s*$/,'\n');
817 for (var i
= 0; i
< form
.elements
.length
; i
++) {
818 var name
= form
.elements
[i
].name
;
819 var yaml
= form
.elements
[i
].getAttribute('validation');
820 if (! name
|| ! yaml
) continue;
821 yaml
= yaml
.replace(/\s*$/,'\n').replace(/^(.)/mg,' $1').replace(/^( *[^\s
&*\[\{])/,'\n$1');
822 str
+= name
+':' + yaml
;
825 if (str
) val_hash
= str
+ "group order: [" + order
.join(', ') + "]\n";
828 if (typeof(val_hash
) == 'string') {
829 if (! document
.yaml_load
) return;
830 document
.hide_yaml_errors
= (! document
.show_yaml_errors
);
831 if (location
.search
&& location
.search
.indexOf('show_yaml_errors') != -1)
832 document
.hide_yaml_errors
= 0;
833 val_hash
= document
.yaml_load(val_hash
);
834 if (document
.yaml_error_occured
) return;
835 val_hash
= val_hash
[0];
839 form
.val_hash
= val_hash
;
840 return form
.val_hash
;
843 document
.check_form = function (form
, val_hash
) {
844 if (! form
) return alert('Missing form or form name');
845 if (typeof(form
) == 'string') {
846 if (! document
[form
]) return alert('No form by name '+form
);
847 form
= document
[form
];
850 val_hash
= document
.load_val_hash(form
, val_hash
);
851 if (! val_hash
) return;
853 var types
= val_hash
['group onevent'] || {submit:1};
854 if (typeof(types
) == 'string') types
= types
.split(/\s*,\s*/);
855 if (typeof(types
.length
) != 'undefined') {
857 for (var i
= 0; i
< types
.length
; i
++) t
[types
[i
]] = 1;
860 val_hash
['group onevent'] = types
;
862 if (types
.change
|| types
.blur
) {
863 var clean
= v_clean_val_hash(val_hash
);
864 if (clean
.error
) return clean
.error
;
866 _add = function (k
, v
) { if (! h
[k
]) h
[k
] = []; h
[k
].push(v
) };
867 for (var i
= 0; i
< clean
.fields
.length
; i
++) {
868 _add(clean
.fields
[i
].field
, clean
.fields
[i
]);
869 for (var j
in clean
.fields
[i
].deps
) if (j
!= clean
.fields
[i
].field
) _add(j
, clean
.fields
[i
]);
872 if (k
== 'extend') continue; // Protoype Array()
874 if (! el
) return v_error("No form element by the name "+k
);
875 v_el_attach(el
, h
[k
], form
, val_hash
);
880 var orig_submit
= form
.onsubmit
|| function () { return true };
881 form
.onsubmit = function (e
) { return document
.validate(this) && orig_submit(e
, this) };
885 function v_el_attach (el
, fvs
, form
, val_hash
) {
887 if (el
.length
) for (var i
= 0; i
< el
.length
; i
++) v_el_attach(el
[i
], fvs
, form
, val_hash
);
890 var types
= val_hash
['group onevent'];
891 var func = function () {
894 for (var i
= 0; i
< fvs
.length
; i
++) {
895 var field_val
= fvs
[i
];
896 var _e
= v_validate_buddy(form
, field_val
.field
, field_val
);
897 for (var j
= 0; j
< _e
.length
; j
++) e
.push(_e
[j
]);
898 f
[field_val
.delegate_error
|| field_val
.field
] = 1;
901 for (var k
in f
) v_inline_error_clear(k
, val_hash
, form
);
904 e
= new ValidateError(e
, {});
905 e
= e
.as_hash({as_hash_suffix:"", first_only:(val_hash
['group first_only']?1:0)});
907 if (k
== 'extend') continue; // Protoype Array()
908 v_inline_error_set(k
, e
[k
], val_hash
, form
);
911 if (types
.blur
) el
.onblur
= func
;
913 if (el
.type
.match(/(password|text|textarea)/)) el
.onkeyup
= func
;
914 else if (el
.type
.match(/(checkbox|radio)/)) el
.onclick
= func
;
915 else if (el
.type
.match(/(select)/)) el
.onchange
= func
;
919 function v_inline_error_clear (key
, val_hash
, form
) {
920 delete(v_did_inline
[key
]);
921 var f
= val_hash
['group clear_hook'] || document
.validate_clear_hook
;
922 if (typeof(f
) == 'function') if (f(key
, val_hash
, form
)) return 1;
923 var el
= document
.getElementById(key
+ v_find_val('as_hash_suffix', val_hash
, '_error'));
924 if (el
) el
.innerHTML
= '';
927 function v_inline_error_set (key
, val
, val_hash
, form
) {
928 v_did_inline
[key
] = 1;
929 var f
= val_hash
['group set_hook'] || document
.validate_set_hook
;
930 if (typeof(f
) == 'function') if(f(key
, val
, val_hash
, form
)) return 1;
931 var el
= document
.getElementById(key
+ v_find_val('as_hash_suffix', val_hash
, '_error'));
932 if (el
) el
.innerHTML
= val
;
This page took 0.104225 seconds and 4 git commands to generate.