diff --git a/core/includes/form.inc b/core/includes/form.inc index a555bf0..fea8eb5 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -856,7 +856,10 @@ function drupal_process_form($form_id, &$form, &$form_state) { // cache when a form is processed, so scenarios that result in // the form being built behind the scenes and again for the // browser don't increment all the element IDs needlessly. - drupal_static_reset('drupal_html_id'); + if (!form_get_errors()) { + // In case of errors no rebuild happens so elements still the same. + drupal_static_reset('drupal_html_id'); + } if ($form_state['submitted'] && !form_get_errors() && !$form_state['rebuild']) { // Execute form submit handlers. diff --git a/core/modules/system/tests/form.test b/core/modules/system/tests/form.test index fe5f922..294be66 100644 --- a/core/modules/system/tests/form.test +++ b/core/modules/system/tests/form.test @@ -2011,3 +2011,35 @@ class FormUrlTestCase extends WebTestBase { $this->assertEqual($values['url_required'], $edit['url_required']); } } + +/** + * Tests html id element unique. + */ +class FormHtmlIdTestCase extends WebTestBase { + protected $profile = 'testing'; + + public static function getInfo() { + return array( + 'name' => 'Form API html id', + 'description' => 'Tests the form API html id unique.', + 'group' => 'Form API', + ); + } + + public function setUp() { + parent::setUp('form_test'); + } + + /** + * Tests that #type 'url' fields are properly validated and trimmed. + */ + function testHtmlId() { + // Tests that element ID's don't get duplicated when form validation fails. + $this->drupalGet('form-test/double-form'); + // Submit second node form with empty title. + $edit = array(); + $this->drupalPost(NULL, $edit, 'Save', array(), array(), 'form-test-html-id--2'); + $this->assertNoDuplicateIds('There are no duplicate IDs'); + + } +} diff --git a/core/modules/system/tests/modules/form_test/form_test.module b/core/modules/system/tests/modules/form_test/form_test.module index f681c75..3cc9b08 100644 --- a/core/modules/system/tests/modules/form_test/form_test.module +++ b/core/modules/system/tests/modules/form_test/form_test.module @@ -241,6 +241,12 @@ function form_test_menu() { 'type' => MENU_CALLBACK, ); } + $items['form-test/double-form'] = array( + 'title' => 'Double form test', + 'page callback' => 'form_test_double_form', + 'access callback' => TRUE, + 'type' => MENU_CALLBACK, + ); $items['form-test/load-include-menu'] = array( 'title' => 'FAPI test loading includes', @@ -2164,3 +2170,35 @@ function form_test_required_attribute($form, &$form_state) { return $form; } + +/** + * Menu callback that returns two instances of the same form. + */ +function form_test_double_form() { + return array( + 'form1' => drupal_get_form('form_test_html_id'), + 'form2' => drupal_get_form('form_test_html_id', TRUE), + ); +} + +/** + * Builds a form to test html IDs. + */ +function form_test_html_id($form, &$form_state, $has_file_field = FALSE) { + $form['name'] = array( + '#type' => 'textfield', + '#title' => 'name', + '#required' => TRUE, + ); + if ($has_file_field) { + $form['file'] = array( + '#type' => 'file', + '#title' => 'file', + ); + } + $form['submit'] = array( + '#type' => 'submit', + '#value' => 'Save', + ); + return $form; +}