diff --git a/components/date.inc b/components/date.inc index a6d9cec..ea8c992 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' => '', ), ); } @@ -274,7 +275,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 10f38f1..21054ff 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 b5ef52b..fd1eab6 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' => '', ), ); } @@ -402,7 +403,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 a5e2048..5a9b1cb 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' => '', ), ); } @@ -160,6 +161,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 67d3410..1717525 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 92fc880..b512720 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 0cb0284..4071c63 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 970ad89..738e5d0 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' => '', ), ); } @@ -200,7 +201,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 4dafc3e..8bec2f6 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 715b960..a16168e 100644 --- a/webform.module +++ b/webform.module @@ -2017,12 +2017,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. @@ -2062,6 +2073,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 855d03e..348f1c7 100644 --- a/webform_hooks.php +++ b/webform_hooks.php @@ -380,6 +380,7 @@ function _webform_defaults_component() { 'optrand' => 0, 'qrand' => 0, 'description' => '', + 'required_error' => '', ), ); }