Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.1046 diff -u -p -r1.1046 common.inc --- includes/common.inc 12 Nov 2009 20:40:27 -0000 1.1046 +++ includes/common.inc 15 Nov 2009 19:59:42 -0000 @@ -5553,6 +5553,9 @@ function drupal_common_theme() { 'form_required_marker' => array( 'arguments' => array('element' => NULL), ), + 'form_error_marker' => array( + 'render element' => 'element', + ), 'text_format_wrapper' => array( 'render element' => 'element', ), Index: includes/form.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/form.inc,v retrieving revision 1.398 diff -u -p -r1.398 form.inc --- includes/form.inc 12 Nov 2009 20:07:05 -0000 1.398 +++ includes/form.inc 15 Nov 2009 19:59:42 -0000 @@ -832,7 +832,10 @@ function _form_validate($elements, &$for // 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']))); + form_error($elements, $t('!name field is required.', array( + '!field_id' => $elements['#id'], + '!name' => $elements['#title'], + ))); } // Verify that the value is not longer than #maxlength. @@ -2767,14 +2770,15 @@ function theme_form_element($variables) $output = '
' . "\n"; $required = !empty($element['#required']) ? theme('form_required_marker', array('element' => $element)) : ''; + $error = theme('form_error_marker', array('element' => $element)); if (!empty($element['#title']) && empty($element['#form_element_skip_title'])) { $title = $element['#title']; if (!empty($element['#id'])) { - $output .= ' \n"; + $output .= ' \n"; } else { - $output .= ' \n"; + $output .= ' \n"; } } @@ -2811,6 +2815,42 @@ function theme_form_required_marker($var } /** + * Theme the error marker for form elements. + * + * @param $variables + * An associative array containing: + * - element: An associative array containing the properties of the element. + * @return + * A string with a marker to identify an error, otherwise an empty string. + * + * @ingroup themeable + */ +function theme_form_error_marker($variables) { + $element = $variables['element']; + // This is also used in the installer, pre-database setup. + $t = get_t(); + + $output = ''; + if ($raw_error = form_get_error($element)) { + // 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. + $error = ($element['#required'] && (!count($element['#value']) || + (is_string($element['#value']) && strlen(trim($element['#value'])) == 0))) ? + $t('This field is required.') : strip_tags($raw_error); + $attributes = array( + 'class' => 'error', + 'title' => $error, + ); + $output .= '!'; + $output .= ' ' . $error . ''; + $output .= ''; + } + + return $output; +} + +/** * Sets a form element's class attribute. * * Adds 'required' and 'error' classes as needed. Index: modules/field/field.test =================================================================== RCS file: /cvs/drupal/drupal/modules/field/field.test,v retrieving revision 1.67 diff -u -p -r1.67 field.test --- modules/field/field.test 12 Nov 2009 20:07:06 -0000 1.67 +++ modules/field/field.test 15 Nov 2009 19:59:42 -0000 @@ -1432,7 +1432,7 @@ class FieldFormTestCase extends FieldTes // Submit with missing required value. $edit = array(); $this->drupalPost('test-entity/add/test-bundle', $edit, t('Save')); - $this->assertRaw(t('!name field is required.', array('!name' => $this->instance['label'])), 'Required field with no value fails validation'); + $this->assertText(t('!name field is required.', array('!name' => $this->instance['label'])), 'Required field with no value fails validation'); // Create an entity $value = mt_rand(1, 127); @@ -1448,7 +1448,7 @@ class FieldFormTestCase extends FieldTes $value = ''; $edit = array("{$this->field_name}[$langcode][0][value]" => $value); $this->drupalPost('test-entity/' . $id . '/edit', $edit, t('Save')); - $this->assertRaw(t('!name field is required.', array('!name' => $this->instance['label'])), 'Required field with no value fails validation'); + $this->assertText(t('!name field is required.', array('!name' => $this->instance['label'])), 'Required field with no value fails validation'); } // function testFieldFormMultiple() { Index: modules/simpletest/tests/form.test =================================================================== RCS file: /cvs/drupal/drupal/modules/simpletest/tests/form.test,v retrieving revision 1.23 diff -u -p -r1.23 form.test --- modules/simpletest/tests/form.test 12 Nov 2009 20:07:06 -0000 1.23 +++ modules/simpletest/tests/form.test 15 Nov 2009 19:59:42 -0000 @@ -52,7 +52,7 @@ class FormsTestCase extends DrupalWebTes $elements['file']['empty_values'] = $empty_strings; // Regular expression to find the expected marker on required elements. - $required_marker_preg = '@\*@'; + $required_marker_preg = '@\*.*@'; // Go through all the elements and all the empty values for them foreach ($elements as $type => $data) {