diff --git a/components/date.inc b/components/date.inc index dfa09a5..8004efb 100644 --- a/components/date.inc +++ b/components/date.inc @@ -24,6 +24,7 @@ function _webform_defaults_date() { 'datepicker' => 1, 'title_display' => 0, 'description' => '', + 'required_error' => '', ), ); } @@ -279,7 +280,14 @@ 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' => $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('!name field is required.', array('!name' => $element['#title']))); + } + return; } } diff --git a/components/email.inc b/components/email.inc index c573ad9..7fa309f 100644 --- a/components/email.inc +++ b/components/email.inc @@ -23,6 +23,7 @@ function _webform_defaults_email() { 'title_display' => 0, 'description' => '', 'attributes' => array(), + 'required_error' => '', ), ); } @@ -141,6 +142,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 652f0a9..c3e3e66 100644 --- a/components/file.inc +++ b/components/file.inc @@ -26,6 +26,7 @@ function _webform_defaults_file() { 'title_display' => 0, 'description' => '', 'attributes' => array(), + 'required_error' => '', ), ); } @@ -405,7 +406,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 52cbb91..fee90d6 100644 --- a/components/grid.inc +++ b/components/grid.inc @@ -27,6 +27,7 @@ function _webform_defaults_grid() { 'custom_option_keys' => 0, 'custom_question_keys' => 0, 'description' => '', + 'required_error' => '', ), ); } @@ -150,6 +151,11 @@ function _webform_render_grid($component, $value = NULL, $filter = TRUE) { '#webform_component' => $component, ); + // 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']; + } + $questions = _webform_select_options_from_text($component['extra']['questions'], TRUE); $options = _webform_select_options_from_text($component['extra']['options'], TRUE); diff --git a/components/select.inc b/components/select.inc index a350c7b..0b2cb56 100644 --- a/components/select.inc +++ b/components/select.inc @@ -27,6 +27,7 @@ function _webform_defaults_select() { 'description' => '', 'custom_keys' => FALSE, 'options_source' => '', + 'required_error' => '', ), ); } @@ -360,6 +361,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 4151137..a83f05d 100644 --- a/components/textarea.inc +++ b/components/textarea.inc @@ -24,6 +24,7 @@ function _webform_defaults_textarea() { 'disabled' => 0, 'description' => '', 'attributes' => array(), + 'required_error' => '', ), ); } @@ -120,6 +121,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 8f24688..f35614f 100644 --- a/components/textfield.inc +++ b/components/textfield.inc @@ -26,6 +26,7 @@ function _webform_defaults_textfield() { 'title_display' => 0, 'description' => '', 'attributes' => array(), + 'required_error' => '', ), ); } @@ -156,6 +157,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 82f95d0..fb4f95d 100644 --- a/components/time.inc +++ b/components/time.inc @@ -24,6 +24,7 @@ function _webform_defaults_time() { 'hourformat' => '12-hour', 'title_display' => 0, 'description' => '', + 'required_error' => '', ), ); } @@ -207,7 +208,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 2ed9f48..05a1786 100644 --- a/includes/webform.components.inc +++ b/includes/webform.components.inc @@ -423,6 +423,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 612adb0..4763a70 100644 --- a/webform.module +++ b/webform.module @@ -1984,12 +1984,23 @@ function _webform_client_form_validate($elements, &$form_state, $first_run = TRU // Validate the current input. if (isset($elements['#webform_validated']) && $elements['#webform_validated'] == FALSE) { if (isset($elements['#needs_validation'])) { - // Make sure a value is passed when the field is required. - // A simple call to empty() will not cut it here as some fields, like - // 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. - if ($elements['#required'] && (!count($elements['#value']) || (is_string($elements['#value']) && strlen(trim($elements['#value'])) == 0))) { - form_error($elements, t('!name field is required.', array('!name' => $elements['#title']))); + if ($elements['#required']) { + // Make sure a value is passed when the field is required. + // A simple call to empty() will not cut it here as some fields, like + // 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. + // An unchecked checkbox has a #value of integer 0, different than string + // '0', which could be a valid value. + $is_empty_multiple = (!count($elements['#value'])); + $is_empty_string = (is_string($elements['#value']) && drupal_strlen(trim($elements['#value'])) == 0); + $is_empty_value = ($elements['#value'] === 0); + 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. @@ -2029,6 +2040,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 6faa59f..ad3f6c1 100644 --- a/webform_hooks.php +++ b/webform_hooks.php @@ -380,6 +380,7 @@ function _webform_defaults_component() { 'optrand' => 0, 'qrand' => 0, 'description' => '', + 'required_error' => '', ), ); }