diff --git a/core/includes/form.inc b/core/includes/form.inc index a555bf0..85fd10c 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 do not break HTML IDs of other forms. + 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..bdb1e67 100644 --- a/core/modules/system/tests/form.test +++ b/core/modules/system/tests/form.test @@ -2011,3 +2011,34 @@ 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 HTML IDs does not get duplicated when form validation fails. + */ + function testHtmlId() { + $this->drupalGet('form-test/double-form'); + $this->assertNoDuplicateIds('There are no duplicate IDs'); + // 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..f653343 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,29 @@ function form_test_required_attribute($form, &$form_state) { return $form; } + +/** + * Menu callback 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'), + ); +} + +/** + * Builds a simple form to test duplicate HTML IDs. + */ +function form_test_html_id($form, &$form_state) { + $form['name'] = array( + '#type' => 'textfield', + '#title' => 'name', + '#required' => TRUE, + ); + $form['submit'] = array( + '#type' => 'submit', + '#value' => 'Save', + ); + return $form; +}