diff --git a/components/date.inc b/components/date.inc index 6121046..d311643 100644 --- a/components/date.inc +++ b/components/date.inc @@ -25,6 +25,7 @@ function _webform_defaults_date() { 'title_display' => 0, 'description' => '', 'private' => FALSE, + 'required_error' => '', ), ); } @@ -275,7 +276,13 @@ function webform_validate_date($element, $form_state) { // Check if the user filled the required fields. foreach (array('day', 'month', 'year') as $field_type) { if (!is_numeric($element[$field_type]['#value']) && $element['#required']) { - form_error($element, t('!name field is required.', array('!name' => $element['#title']))); + $component = $element['#webform_component']; + if (isset($component['extra']['required_error']) && drupal_strlen($component['extra']['required_error'])) { + form_error($element, $component['extra']['required_error']); + } + else { + form_error($element, t('!name field is required.', array('!name' => $element['#title']))); + } return; } } diff --git a/components/email.inc b/components/email.inc index a096709..b35a1da 100644 --- a/components/email.inc +++ b/components/email.inc @@ -24,6 +24,7 @@ function _webform_defaults_email() { 'description' => '', 'attributes' => array(), 'private' => FALSE, + 'required_error' => '', ), ); } @@ -143,6 +144,11 @@ function _webform_render_email($component, $value = NULL, $filter = TRUE) { $element['#size'] = $component['extra']['width']; } + // If needed set custom validation error for mandatory element. + if ($component['mandatory'] && isset($component['extra']['required_error']) && drupal_strlen($component['extra']['required_error'])) { + $element['#required_error'] = $component['extra']['required_error']; + } + return $element; } diff --git a/components/file.inc b/components/file.inc index c44541c..5a415fe 100644 --- a/components/file.inc +++ b/components/file.inc @@ -27,6 +27,7 @@ function _webform_defaults_file() { 'description' => '', 'attributes' => array(), 'private' => FALSE, + 'required_error' => '', ), ); } @@ -417,7 +418,12 @@ function _webform_required_file($element, $form_state) { if (!$found || (empty($values['_fid']) && empty($values['_old']))) { if (empty($_FILES['files']['name'][$form_key]) && $component['mandatory']) { - form_error($element, t('%field field is required.', array('%field' => $component['name']))); + if (isset($component['extra']['required_error']) && drupal_strlen($component['extra']['required_error'])) { + form_error($element, $component['extra']['required_error']); + } + else { + form_error($element, t('%field field is required.', array('%field' => $component['name']))); + } } } } diff --git a/components/grid.inc b/components/grid.inc index 548999d..e696a93 100644 --- a/components/grid.inc +++ b/components/grid.inc @@ -28,6 +28,7 @@ function _webform_defaults_grid() { 'custom_question_keys' => 0, 'description' => '', 'private' => FALSE, + 'required_error' => '', ), ); } @@ -163,6 +164,11 @@ function _webform_render_grid($component, $value = NULL, $filter = TRUE) { $element['#default_value'] = $value; } + // If needed set custom validation error for mandatory element. + if ($component['mandatory'] && isset($component['extra']['required_error']) && drupal_strlen($component['extra']['required_error'])) { + $element['#required_error'] = $component['extra']['required_error']; + } + return $element; } diff --git a/components/select.inc b/components/select.inc index 5f32b72..ed5d2b0 100644 --- a/components/select.inc +++ b/components/select.inc @@ -28,6 +28,7 @@ function _webform_defaults_select() { 'custom_keys' => FALSE, 'options_source' => '', 'private' => FALSE, + 'required_error' => '', ), ); } @@ -378,6 +379,11 @@ function _webform_render_select($component, $value = NULL, $filter = TRUE) { } } + // If needed set custom validation error for mandatory element. + if ($component['mandatory'] && isset($component['extra']['required_error']) && drupal_strlen($component['extra']['required_error'])) { + $element['#required_error'] = $component['extra']['required_error']; + } + return $element; } diff --git a/components/textarea.inc b/components/textarea.inc index b60c382..754dfc8 100644 --- a/components/textarea.inc +++ b/components/textarea.inc @@ -25,6 +25,7 @@ function _webform_defaults_textarea() { 'description' => '', 'attributes' => array(), 'private' => FALSE, + 'required_error' => '', ), ); } @@ -122,6 +123,11 @@ function _webform_render_textarea($component, $value = NULL, $filter = TRUE) { $element['#default_value'] = $value[0]; } + // If needed set custom validation error for mandatory element. + if ($component['mandatory'] && isset($component['extra']['required_error']) && drupal_strlen($component['extra']['required_error'])) { + $element['#required_error'] = $component['extra']['required_error']; + } + return $element; } diff --git a/components/textfield.inc b/components/textfield.inc index 7c45881..ab9d6cc 100644 --- a/components/textfield.inc +++ b/components/textfield.inc @@ -27,6 +27,7 @@ function _webform_defaults_textfield() { 'description' => '', 'attributes' => array(), 'private' => FALSE, + 'required_error' => '', ), ); } @@ -158,6 +159,11 @@ function _webform_render_textfield($component, $value = NULL, $filter = TRUE) { $element['#default_value'] = $value[0]; } + // If needed set custom validation error for mandatory element. + if ($component['mandatory'] && isset($component['extra']['required_error']) && drupal_strlen($component['extra']['required_error'])) { + $element['#required_error'] = $component['extra']['required_error']; + } + return $element; } diff --git a/components/time.inc b/components/time.inc index f417020..0de1f22 100644 --- a/components/time.inc +++ b/components/time.inc @@ -25,6 +25,7 @@ function _webform_defaults_time() { 'title_display' => 0, 'description' => '', 'private' => FALSE, + 'required_error' => '', ), ); } @@ -201,7 +202,13 @@ function webform_validate_time($element, $form_state) { // Check if the user filled the required fields. foreach ($element['#hourformat'] == '12-hour' ? array('hour', 'minute', 'ampm') : array('hour', 'minute') as $field_type) { if ($element[$field_type]['#value'] === '' && $element['#required']) { - form_error($element, t('%field field is required.', array('%field' => $name))); + $component = $element['#webform_component']; + if (isset($component['extra']['required_error']) && drupal_strlen($component['extra']['required_error'])) { + form_error($element, $component['extra']['required_error']); + } + else { + form_error($element, t('%field field is required.', array('%field' => $name))); + } return; } } diff --git a/includes/webform.components.inc b/includes/webform.components.inc index 18e74bd..5b809ec 100644 --- a/includes/webform.components.inc +++ b/includes/webform.components.inc @@ -454,6 +454,14 @@ function webform_component_edit_form($form, $form_state, $node, $component, $clo '#weight' => -1, '#parents' => array('mandatory'), ); + $form['validation']['required_error'] = array( + '#type' => 'textfield', + '#title' => t('Mandatory error message'), + '#default_value' => isset($component['extra']['required_error']) ? $component['extra']['required_error'] : '', + '#description' => t('This is used as a custom validation error for mandatory element.'), + '#weight' => 0, + '#parents' => array('extra', 'required_error'), + ); } // Position settings, only shown if JavaScript is disabled. diff --git a/webform.module b/webform.module index 7c90051..9d3b137 100644 --- a/webform.module +++ b/webform.module @@ -2063,15 +2063,23 @@ function _webform_client_form_validate($elements, &$form_state, $first_run = TRU // checkboxes, can return a valid value of '0'. Instead, check the // length if it's a string, and the item count if it's an array. For // radios, FALSE means that no value was submitted, so check that too. - if ($elements['#required'] && (!count($elements['#value']) || (is_string($elements['#value']) && strlen(trim($elements['#value'])) == 0) || $elements['#value'] === FALSE)) { - form_error($elements, t('!name field is required.', array('!name' => $elements['#title']))); + if ($elements['#required']) { + $is_empty_multiple = (!count($elements['#value'])); + $is_empty_string = (is_string($elements['#value']) && strlen(trim($elements['#value'])) === 0); + $is_empty_value = ($elements['#value'] === FALSE); + if ($is_empty_multiple || $is_empty_string || $is_empty_value) { + // Flag this element as #required_is_empty to allow #element_validate + // handlers to set a custom required error message, but without having + // to re-implement the complex logic to figure out whether the field + // value is empty. + $elements['#required_is_empty'] = TRUE; + } } // Verify that the value is not longer than #maxlength. if (isset($elements['#maxlength']) && drupal_strlen($elements['#value']) > $elements['#maxlength']) { form_error($elements, t('!name cannot be longer than %max characters but is currently %length characters long.', array('!name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title'], '%max' => $elements['#maxlength'], '%length' => drupal_strlen($elements['#value'])))); } - if (isset($elements['#options']) && isset($elements['#value'])) { if ($elements['#type'] == 'select') { $options = form_options_flatten($elements['#options']); @@ -2088,7 +2096,7 @@ function _webform_client_form_validate($elements, &$form_state, $first_run = TRU } } } - elseif ($elements['#value'] !== '' && !isset($options[$elements['#value']])) { + elseif ($elements['#value'] !== FALSE && !isset($options[$elements['#value']])) { form_error($elements, t('An illegal choice has been detected. Please contact the site administrator.')); watchdog('form', 'Illegal choice %choice in %name element.', array('%choice' => $elements['#value'], '%name' => empty($elements['#title']) ? $elements['#parents'][0] : $elements['#title']), WATCHDOG_ERROR); } @@ -2104,6 +2112,20 @@ function _webform_client_form_validate($elements, &$form_state, $first_run = TRU } } } + + // Ensure that a #required form error is thrown, regardless of whether + // #element_validate handlers changed any properties. If $is_empty_value + // is defined, then above #required validation code ran, so the other + // variables are also known to be defined and we can test them again. + if (isset($is_empty_value) && ($is_empty_multiple || $is_empty_string || $is_empty_value)) { + if (isset($elements['#required_error']) && drupal_strlen($elements['#required_error'])) { + form_error($elements, $elements['#required_error']); + } + else { + form_error($elements, t('!name field is required.', array('!name' => $elements['#title']))); + } + } + $elements['#webform_validated'] = TRUE; } } diff --git a/webform_hooks.php b/webform_hooks.php index a90a732..34fa99c 100644 --- a/webform_hooks.php +++ b/webform_hooks.php @@ -401,6 +401,7 @@ function _webform_defaults_component() { 'optrand' => 0, 'qrand' => 0, 'description' => '', + 'required_error' => '', ), ); }