summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.txt3
-rw-r--r--includes/form.inc5
-rw-r--r--modules/simpletest/tests/form.test31
-rw-r--r--modules/simpletest/tests/form_test.module32
4 files changed, 70 insertions, 1 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 5bae4736b..776237e6e 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,6 +1,9 @@
Drupal 7.17, xxxx-xx-xx (development version)
-----------------------
+- Prevented duplicate HTML IDs from appearing when two forms are displayed on
+ the same page and one of them was submitted with invalid data (minor markup
+ change).
- Fixed the theme settings form to properly clean up submitted values in
$form_state['values'] when the form is submitted (data structure change).
- Updated various admin tables to use the default "empty table" text UX
diff --git a/includes/form.inc b/includes/form.inc
index 826b6777b..fa49839e4 100644
--- a/includes/form.inc
+++ b/includes/form.inc
@@ -850,7 +850,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/modules/simpletest/tests/form.test b/modules/simpletest/tests/form.test
index 675e8d189..620621a69 100644
--- a/modules/simpletest/tests/form.test
+++ b/modules/simpletest/tests/form.test
@@ -1750,3 +1750,34 @@ class FormCheckboxTestCase extends DrupalWebTestCase {
}
}
}
+
+/**
+ * Tests uniqueness of generated HTML IDs.
+ */
+class HTMLIdTestCase extends DrupalWebTestCase {
+
+ public static function getInfo() {
+ return array(
+ 'name' => 'Unique HTML IDs',
+ 'description' => 'Tests functionality of drupal_html_id().',
+ 'group' => 'Form API',
+ );
+ }
+
+ function setUp() {
+ parent::setUp('form_test');
+ }
+
+ /**
+ * Tests that HTML IDs do not get duplicated when form validation fails.
+ */
+ function testHTMLId() {
+ $this->drupalGet('form-test/double-form');
+ $this->assertNoDuplicateIds('There are no duplicate IDs');
+
+ // Submit second 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/modules/simpletest/tests/form_test.module b/modules/simpletest/tests/form_test.module
index 5d6527680..6af18c6af 100644
--- a/modules/simpletest/tests/form_test.module
+++ b/modules/simpletest/tests/form_test.module
@@ -194,6 +194,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',
@@ -1787,3 +1793,29 @@ function form_test_checkboxes_zero($form, &$form_state, $json = TRUE) {
function _form_test_checkboxes_zero_no_redirect($form, &$form_state) {
$form_state['redirect'] = FALSE;
}
+
+/**
+ * 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;
+}