Newer
Older
<?php
// $Id:
/**
* @file
* Add client side validation to a webform.
*/
/**
* Implementation of hook_form_alter().
*/
function clientside_validation_form_alter(&$form, &$form_state, $form_id) {
if (strpos($form_id, 'webform_client_form') !== FALSE) {
$form['#after_build'][] = 'clientside_validation_webform_after_build';
}
else {
switch ($form['#id']) {
case 'node-form':
case 'webform-component-edit-form':
$form['#after_build'][] = 'clientside_validation_form_after_build';
break;
default:
$form['#after_build'][] = 'clientside_validation_form_after_build';
break;
}
}
}
/**
* Webform.
*/
function clientside_validation_webform_after_build(&$form, &$form_state) {
$js_rules = array();
clientside_validation_webform_after_build_recurse($form['#id'], $form, $form_state, $js_rules);
if ($webform_validation_rules = clientside_validation_webform_validation($form_state['values']['details']['nid'])) {
dpm($webform_validation_rules);
foreach ($webform_validation_rules as $webform_validation_rule) {
switch ($webform_validation_rule['validator']) {
case 'min_length':
foreach ($webform_validation_rule['components'] as $component) {
$message = t('!name field has a minimum length of !minl characters.', array('!name' => $component['name'], '!minl' => $webform_validation_rule['data']));
_clientside_validation_set_minmaxlength('submitted[' . $component['form_key'] . ']', $component['name'], $webform_validation_rule['data'], '', $js_rules, $message);
}
break;
case 'max_length':
foreach ($webform_validation_rule['components'] as $component) {
$message = t('!name field has a maximum length of !maxl characters.', array('!name' => $component['name'], '!maxl' => $webform_validation_rule['data']));
_clientside_validation_set_minmaxlength('submitted[' . $component['form_key'] . ']', $component['name'], '',$webform_validation_rule['data'], $js_rules, $message);
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
}
break;
case 'numeric':
foreach ($webform_validation_rule['components'] as $component) {
$range = explode('-', $webform_validation_rule['data']);
if (!empty($range[0]) && $range[0] != '0') {
if (!isset($range[1])) {
$range[1] = $range[0];
$range[0] = 0;
}
_clientside_validation_set_minmax('submitted[' . $component['form_key'] . ']', $component['name'], $range[0], $range[1], $js_rules);
}
}
break;
case 'equal':
$others = $webform_validation_rule['components'];
$firstone = array_shift($others);
foreach ($others as $component) {
_clientside_validation_set_equal('submitted[' . $component['form_key'] . ']', $component['name'], $firstone, $js_rules);
}
break;
case 'unique':
$all = $webform_validation_rule['components'];
while (count($all) > 1) {
$firstone = array_shift($all);
foreach ($all as $component) {
$message = (isset($webform_validation_rule['error_message']) && !empty($webform_validation_rule['error_message'])) ? $webform_validation_rule['error_message'] : '';
_clientside_validation_set_not_equal('submitted[' . $component['form_key'] . ']', $component['name'], $firstone, $js_rules, $message);
}
}
break;
case 'specific_value':
foreach ($webform_validation_rule['components'] as $component) {
$value = explode(',', $webform_validation_rule['data']);
$message = (isset($webform_validation_rule['error_message']) && !empty($webform_validation_rule['error_message'])) ? $webform_validation_rule['error_message'] : '';
_clientside_validation_set_specific_value('submitted[' . $component['form_key'] . ']', $component['name'], $value, $js_rules, $message);
}
break;
case 'select_min':
foreach ($webform_validation_rule['components'] as $component) {
_clientside_validation_set_minmaxlength ('submitted[' . $component['form_key'] . ']', $component['name'], $webform_validation_rule['data'], '', $js_rules);
}
break;
case 'select_max':
foreach ($webform_validation_rule['components'] as $component) {
_clientside_validation_set_minmaxlength ('submitted[' . $component['form_key'] . ']', $component['name'], '', $webform_validation_rule['data'], $js_rules);
}
break;
case 'select_exact':
foreach ($webform_validation_rule['components'] as $component) {
_clientside_validation_set_minmaxlength ('submitted[' . $component['form_key'] . ']', $component['name'], $webform_validation_rule['data'], $webform_validation_rule['data'], $js_rules);
}
break;
case 'validEAN':
foreach ($webform_validation_rule['components'] as $component) {
$message = (isset($webform_validation_rule['error_message']) && !empty($webform_validation_rule['error_message'])) ? $webform_validation_rule['error_message'] : '';
_clientside_validation_set_ean('submitted[' . $component['form_key'] . ']', $component['name'], $js_rules, $message);
}
break;
}
}
}
if (!empty($js_rules)) {
$settings['clientsideValidation']['general'] = array (
"errorClass" => "error",
"wrapper" => "li",
);
$settings['clientsideValidation']['forms'][$form['#id']]['settings'] = array(
"errorContainer" => "#formerrors-" . $form['#id'],
"errorLabelContainer" => "#formerrors-" . $form['#id'] . " ul",
);
foreach($js_rules as $key => $rule) {
$settings['clientsideValidation']['forms'][$form['#id']]['rules'][$key] = $rule;
}
drupal_add_js(drupal_get_path('module', 'clientside_validation') . '/jquery-validate/jquery.validate.js');
drupal_add_js(drupal_get_path('module', 'clientside_validation') . '/clientside_validation.js');
drupal_add_js($settings, 'setting');
}
return $form;
}
function clientside_validation_webform_after_build_recurse($form_id, &$form, &$form_state, &$js_rules) {
if ($children = array_values(element_children($form))) {
foreach ($children as $index => $item) {
$element = &$form[$item];
if (isset($element['#title'])) {
if ($element['#required']) {
if (isset($element['#webform_component']) && $element['#webform_component']['type'] == 'time' && isset($element['hour']['#name'])) {
$message = t('Hour in !name field is required.', array('!name' => $element['#title']));
_clientside_validation_set_required($element['hour']['#name'], $element['#title'], TRUE, $js_rules, $message);
$message = t('Minute in !name field is required.', array('!name' => $element['#title']));
_clientside_validation_set_required($element['minute']['#name'], $element['#title'], TRUE, $js_rules, $message);
}
else if (isset($element['#webform_component']) && $element['#webform_component']['type'] == 'date') {
$message = t('Month in !name field is required.', array('!name' => $element['#title']));
_clientside_validation_set_required($element['#name'] . '[month]', $element['#title'], TRUE, $js_rules, $message);
$message = t('Day in !name field is required.', array('!name' => $element['#title']));
_clientside_validation_set_required($element['#name'] . '[day]', $element['#title'], TRUE, $js_rules, $message);
$message = t('Year in !name field is required.', array('!name' => $element['#title']));
_clientside_validation_set_required($element['#name'] . '[year]', $element['#title'], TRUE, $js_rules, $message);
if (is_numeric($element['#year_start']) && is_numeric($element['#year_end'])) {
$message = t('The entered date needs to be between the years @start and @end.', array('@start' => $element['#year_start'], '@end' => $element['#year_end']));
_clientside_validation_set_minmax($element['#name'] . '[year]', $element['#title'], $element['#year_start'], $element['#year_end'], $js_rules, $message);
}
}
else if ($element['#type'] == 'checkboxes') {
$count = 0;
foreach ($element['#options'] as $key => $value) {
_clientside_validation_set_checkboxgroup_minmax($element[$key]['#name'], $element['#title'], '#webform-component-' . end($element['#parents']), $count, $js_rules);
$count++;
}
}
else if ($element['#type'] == 'select' && $element['#multiple']) {
_clientside_validation_set_required($element['#name'] . '[]', $element['#title'], TRUE, $js_rules);
_clientside_validation_set_required($element['#name'], $element['#title'], TRUE, $js_rules);
}
}
if (isset($element['#webform_component']) && $element['#webform_component']['type'] == 'file' && $element['#webform_component']['mandatory'] == "1") {
_clientside_validation_set_required($element['#name'], $element['#title'], TRUE, $js_rules);
if (isset($element['#webform_component']['extra']['filtering']['types'])) {
$extensions = $element['#webform_component']['extra']['filtering']['types'];
_clientside_validation_set_extensions($element['#name'], $extensions, $js_rules);
if (isset($element['#maxlength']) && $element['#maxlength']) {
$message = t('!name field has a max length of !maxl characters.', array('!name' => $element['#title'], '!maxl' => $element['#maxlength']));
_clientside_validation_set_minmaxlength($element['#name'], $element['#title'], '', $element['#maxlength'], $js_rules, $message);
if (isset($element['#webform_component']) && $element['#webform_component']['type'] == 'email') {
_clientside_validation_set_email($element['#name'], $element['#title'], $js_rules);
}
}
clientside_validation_webform_after_build_recurse($form_id, $element, $form_state, $js_rules);
}
}
}
/**
* Implements hook_webform_validation().
*/
function clientside_validation_webform_validation($nid) {
static $webform_validation_rules;
if (!isset($webform_validation_rules[$nid])) {
if (module_exists('webform_validation')) {
$webform_validation_rules[$nid] = webform_validation_get_node_rules($nid);
}
else {
$webform_validation_rules[$nid] = NULL;
}
}
return $webform_validation_rules[$nid];
}
/**
* Regular form + CCK
*/
function clientside_validation_form_after_build(&$form, &$form_state) {
static $js_rules = array();
clientside_validation_form_after_build_recurse($form['#id'], $form, $form_state, $js_rules);
if (!empty($js_rules)) {
$settings['clientsideValidation']['general'] = array (
"errorClass" => "error",
"wrapper" => "li",
);
$settings['clientsideValidation']['forms'][$form['#id']]['settings'] = array(
"errorContainer" => "#formerrors-" . $form['#id'],
"errorLabelContainer" => "#formerrors-" . $form['#id'] . " ul",
);
foreach($js_rules as $key => $rule) {
$settings['clientsideValidation']['forms'][$form['#id']]['rules'][$key] = $rule;
}
drupal_add_js(drupal_get_path('module', 'clientside_validation') . '/jquery-validate/jquery.validate.js');
drupal_add_js(drupal_get_path('module', 'clientside_validation') . '/clientside_validation.js');
drupal_add_js($settings, 'setting');
}
return $form;
}
function clientside_validation_form_after_build_recurse($form_id, &$form, &$form_state, &$js_rules) {
if ($children = array_values(element_children($form))) {
foreach ($children as $index => $item) {
$element = &$form[$item];
$types = array(
'textfield', 'textarea', 'select', 'radio', 'checkbox', 'password', 'file', 'radios', 'checkboxes',
);
if (isset($element['#type']) && in_array($element['#type'], $types)) {
clientside_validation_regular ($form_id, $element, $js_rules);
}
clientside_validation_form_after_build_recurse($form_id, $element, $form_state, $js_rules);
}
}
}
function clientside_validation_regular ($form_id, $element, &$js_rules) {
static $multiples = array();
if (isset($element['#name']) && !isset($js_rules[$element['#name']])) {
$el_name = $element['#name'];
$el_title = $el_name;
if (isset($element['#title'])) {
$el_title = $element['#title'];
}
$is_multiple = FALSE;
if (isset($element['#multiple'])) {
$is_multiple = $element['#multiple'];
}
switch ($element['#type']) {
case 'textfield':
case 'password':
case 'textarea':
case 'file':
if ($is_multiple) {
// Only first field is required
if (!isset($multiples[$form_id][$el_name])) {
_clientside_validation_set_required ($el_name, $el_title, $element['#required'], $js_rules);
$multiples[$form_id][$el_name] = 1;
}
else {
_clientside_validation_set_required ($el_name, $el_title, $element['#required'], $js_rules);
}
if (isset($element['max_length']) && $element['max_length'] > 0) {
_clientside_validation_set_minmaxlength ($el_name, $el_title, '', $element['max_length'], $js_rules);
case 'select':
if ($is_multiple) {
$el_name .= '[]';
if(!isset($element['#minlength'])){
$element['#minlength'] = 0;
}
_clientside_validation_set_minmaxlength ($el_name, $el_title, $element['#minlength'], $is_multiple, $js_rules);
_clientside_validation_set_required ($el_name, $el_title, $element['#required'], $js_rules);
case 'radio':
case 'radios':
_clientside_validation_set_required ($el_name, $el_title, $element['#required'], $js_rules);
break;
case 'checkbox':
case 'checkboxes':
$is_multiple = (isset($element['#options']) && count($element['#options']>1));
if ($is_multiple) {
// We don't have a parent element to connect to, so no go, outer div has only a class
// The checkboxes element has the unique name, but this isn't added to the outer div
$count = 0;
foreach ($element['#options'] as $key => $value) {
$id = '#edit-' . str_replace('_', '-', $element['#parents'][0]);
_clientside_validation_set_checkboxgroup_minmax($element[$key]['#name'], $element['#title'], $id, $count, $js_rules);
$count++;
}
}
else {
_clientside_validation_set_required ($el_name, $el_title, $element['#required'], $js_rules);
}
/**
* Set validation rule for required fields.
*/
function _clientside_validation_set_required ($name, $title, $required, &$js_rules, $message = '') {
if ($required) {
$js_rules[$name]['required'] = TRUE;
$js_rules[$name]['messages']['required'] = (empty($message)) ? t('!name field is required.', array('!name' => $title)) : $message;
/**
* Set validation rule for number fields.
*/
function _clientside_validation_set_number ($name, $title, $decimalpoint, &$js_rules) {
$js_rules[$name]['digits_negative'] = TRUE;
$js_rules[$name]['messages']['digits_negative'] = t('!name field accepts only numbers.', array('!name' => $title));
}
/**
* Set validation rule for decimal fields.
*/
function _clientside_validation_set_number_decimal ($name, $title, $decimalpoint, &$js_rules) {
if ($decimalpoint == '.') {
$js_rules[$name]['number'] = TRUE;
$js_rules[$name]['messages']['number'] = t('!name field accepts only numbers (use a \'.\' as decimal point).', array('!name' => $title));
}
else {
$js_rules[$name]['numberDE'] = TRUE;
$js_rules[$name]['messages']['numberDE'] = t('!name field accepts only numbers (use a \',\' as decimal point).', array('!name' => $title));
}
}
/**
* Set validation rule for fields with a minimum and/or a maximum value.
*/
function _clientside_validation_set_minmax ($name, $title, $min, $max, &$js_rules, $message = '') {
if (isset($min) && $min != '' && isset($max) && $max != '') {
$js_rules[$name]['range'] = array($min, $max);
$js_rules[$name]['messages']['range'] = (empty($message)) ? t('!name field has to be between !min and !max.', array('!name' => $title, '!min' => $min, '!max' => $max)) : $message;
}
else if (isset($min) && $min != '') {
$js_rules[$name]['min'] = $min;
$js_rules[$name]['messages']['min'] = (empty($message)) ? t('!name field has to be greater than !min.', array('!name' => $title, '!min' => $min)) : $message;
}
else if (isset($max) && $max != '') {
$js_rules[$name]['max'] = $max;
$js_rules[$name]['messages']['max'] = (empty($message)) ? t('!name field has to be smaller than !max.', array('!name' => $title, '!max' => $max)) : $message;
/**
* Set validation rule for fields with a minimum and/or maximum length.
*/
function _clientside_validation_set_minmaxlength ($name, $title, $min, $max, &$js_rules, $message = '') {
if (isset($min) && $min != '' && isset($max) && $max != '') {
$js_rules[$name]['rangelength'] = array($min, $max);
$js_rules[$name]['messages']['rangelength'] = (empty($message)) ? t('!name field has to have between !min and !max values.', array('!name' => $title, '!min' => $min, '!max' => $max)) : $message;
}
else if (isset($min) && $min != '') {
$js_rules[$name]['minlength'] = $min;
$js_rules[$name]['messages']['minlength'] = (empty($message)) ? t('!name field has to have minimal !min values.', array('!name' => $title, '!min' => $min)) : $message;
}
else if (isset($max) && $max != '') {
$js_rules[$name]['maxlength'] = $max;
$js_rules[$name]['messages']['maxlength'] = (empty($message)) ? t('!name field has to have maximum !max values.', array('!name' => $title, '!max' => $max)) : $message;
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
/**
* Set validation rule for required fields that must equal a value from an other field.
*/
function _clientside_validation_set_equal($name, $title, $value, &$js_rules){
$js_rules[$name]['equalTo'] = ':input[name=\'submitted[' . $value['form_key'] . ']\']';
$js_rules[$name]['messages']['equalTo'] = t('!name field has to be equal to !firstone.', array('!name' => $title, '!firstone' => $value['name']));
}
/**
* Set validation rule for fields that can not be equal to a value from an other field.
*/
function _clientside_validation_set_not_equal($name, $title, $value, &$js_rules, $message = ''){
$js_rules[$name]['notEqualTo'] = ':input[name=\'submitted[' . $value['form_key'] . ']\']';
$message = empty($message) ? t('!name field has to different from !firstone.', array('!name' => $title, '!firstone' => $value['name'])) : $message;
$js_rules[$name]['messages']['notEqualTo'] = $message;
}
/**
* Set validation rule for fields that must be equal to a specific value.
*/
function _clientside_validation_set_specific_value($name, $title, $value, &$js_rules, $message = ''){
$js_rules[$name]['oneOf'] = $value;
$message = empty($message) ? t('!name field has to different from !firstone.', array('!name' => $title, '!firstone' => $value['name'])) : $message;
$js_rules[$name]['messages']['oneOf'] = $message;
}
/**
* Set validation rule for ean number fields.
*/
function _clientside_validation_set_ean($name, $title, &$js_rules, $message = ''){
$message = empty($message) ? t('!name field is not a valid EAN number.', array('!name' => $title)) : $message;
$js_rules[$name]['validEAN'] = TRUE;
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
/**
* Set validation rule for file fields that must have a certain extension.
*/
function _clientside_validation_set_extensions($name, $extensions, &$js_rules){
$extension_list = preg_replace('#,(?![^,]+,)#', ' or', implode(', ', $extensions));
$js_rules[$name]['accept'] = implode('|', $extensions);
$js_rules[$name]['messages']['accept'] = t("Only files with a %exts extension are allowed.", array('%exts' => $extension_list));
}
/**
* Set validation rule for checkboxes.
*/
function _clientside_validation_set_checkboxgroup_minmax($name, $title, $id, $count, &$js_rules, $min = 1, $max = 99){
$js_rules[$name]['checkboxgroupminmax'] = array($min, $max, $id);
if ($count == 0) {
$js_rules[$name]['messages']['checkboxgroupminmax'] = t('!name field is required.', array('!name' => $title));
}
else {
$js_rules[$name]['messages']['checkboxgroupminmax'] = false;
}
}
/**
* Set validation rule for email fields.
*/
function _clientside_validation_set_email($name, $title, &$js_rules){
$js_rules[$name]['email'] = TRUE;
$js_rules[$name]['messages']['email'] = t('The value in !name is not a valid email address.', array('!name' => $title));
}
function clientside_validation_drupal_json_encode($var) {
return str_replace(array('<', '>', '&'), array('\u003c', '\u003e', '\u0026'), json_encode($var));
}