diff --git a/core/modules/views/src/Tests/Plugin/ExposedFormTest.php b/core/modules/views/src/Tests/Plugin/ExposedFormTest.php index 61c1568..0aa565d 100644 --- a/core/modules/views/src/Tests/Plugin/ExposedFormTest.php +++ b/core/modules/views/src/Tests/Plugin/ExposedFormTest.php @@ -21,7 +21,7 @@ class ExposedFormTest extends ViewTestBase { * * @var array */ - public static $testViews = array('test_exposed_form_buttons', 'test_exposed_block'); + public static $testViews = array('test_exposed_form_buttons', 'test_exposed_block', 'test_exposed_form'); /** * Modules to enable. @@ -198,4 +198,20 @@ protected function getExpectedExposedFormId(ViewExecutable $view) { return drupal_clean_css_identifier('views-exposed-form-' . $view->storage->id() . '-' . $view->current_display); } + /** + * Tests a view which is rendered after a form with a validation error. + */ + public function testFormErrorWithExposedForm() { + $nodes = array(); + $nodes[] = $this->drupalCreateNode(); + $nodes[] = $this->drupalCreateNode(); + + $this->drupalGet('test-form'); + $this->assertRaw(t('Apply'), 'Ensure the exposed form is rendered before submitting the normal form.'); + + $this->drupalPost(NULL, array(), t('Submit')); + $this->assertRaw(t('Apply'), 'Ensure the exposed form is rendered after submitting the normal form.'); + + } + } diff --git a/core/modules/views/src/ViewExecutable.php b/core/modules/views/src/ViewExecutable.php index d6b4775..f967e93 100644 --- a/core/modules/views/src/ViewExecutable.php +++ b/core/modules/views/src/ViewExecutable.php @@ -1076,8 +1076,16 @@ public function build($display_id = NULL) { if ($this->display_handler->usesExposed()) { $exposed_form = $this->display_handler->getPlugin('exposed_form'); + // (1) Record the errors before rendering the exposed form widgets + $errors_before = \Drupal::formBuilder()->getAnyErrors(); $this->exposed_widgets = $exposed_form->renderExposedForm(); - if (\Drupal::formBuilder()->getAnyErrors() || !empty($this->build_info['abort'])) { + // (2) Record the errors after rendering the exposed form widgets. + $errors_after = \Drupal::formBuilder()->getAnyErrors(); + // Find out if the validation of any of the elements in the exposed form + // has failed by comparing (1) and (2) above. Don't mess with the view + // otherwise. + $exposed_errors = count($errors_after) > count($errors_before); + if ($exposed_errors || !empty($this->build_info['abort'])) { $this->built = TRUE; // Don't execute the query, $form_state, but rendering will still be executed to display the empty text. $this->executed = TRUE; diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form.yml index cde0aee..f9646db 100644 --- a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form.yml +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_exposed_form.yml @@ -1,4 +1,5 @@ base_table: node +base_field: nid core: '8' description: '' status: '1' @@ -10,17 +11,63 @@ display: cache: type: none exposed_form: - type: test_exposed_form + type: basic pager: type: full style: type: default row: type: fields + filters: + status: + id: status + table: node + field: status + relationship: none + group_type: group + admin_label: '' + operator: '=' + value: '1' + group: '1' + exposed: '1' + plugin_id: boolean + expose: + operator_id: '' + label: Published + description: '' + use_operator: '0' + operator: status_op + identifier: status + required: '1' + remember: '0' + multiple: '0' + remember_roles: + authenticated: authenticated + anonymous: '0' + administrator: '0' + is_grouped: '0' + group_info: + label: '' + description: '' + identifier: '' + optional: '1' + widget: select + multiple: '0' + remember: '0' + default_group: All + default_group_multiple: { } + group_items: { } display_plugin: default display_title: Master id: default - position: 0 + position: '0' + embed_1: + display_plugin: embed + id: embed_1 + display_title: Embed + position: '' + display_options: { } +human_name: '' label: '' id: test_exposed_form tag: '' diff --git a/core/modules/views/tests/views_test_form/views_test_form.info b/core/modules/views/tests/views_test_form/views_test_form.info new file mode 100644 index 0000000..0baaa59 --- /dev/null +++ b/core/modules/views/tests/views_test_form/views_test_form.info @@ -0,0 +1,7 @@ +name = Views test form +description = Test module for a page with a normal form and a exposed form. +package = Testing +version = VERSION +core = 8.x +dependencies[] = views +hidden = TRUE diff --git a/core/modules/views/tests/views_test_form/views_test_form.module b/core/modules/views/tests/views_test_form/views_test_form.module new file mode 100644 index 0000000..1732da5 --- /dev/null +++ b/core/modules/views/tests/views_test_form/views_test_form.module @@ -0,0 +1,59 @@ + 'views_test_form_page', + 'access callback' => TRUE, + ); + + return $items; +} + +/** + * Page callback to render a form and a + * + * @see \Drupal\views\Tests\Plugin\ExposedFormTest::testFormErrorWithExposedForm() + */ +function views_test_form_page() { + $build = array(); + $build['normal_form'] = drupal_get_form('views_test_form_test_form'); + $build['embedded_view'] = array( + '#markup' => views_embed_view('test_exposed_form') + ); + + return $build; +} + +/** + * Form constructor for the test form. + * + * @see views_test_form_test_form_validate + */ +function views_test_form_test_form() { + $form['text'] = array( + '#type' => 'textfield', + ); + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Submit'), + ); + + return $form; +} + +/** + * Form validation handler for the test form. + * + * @see views_test_form_test_form + */ +function views_test_form_test_form_validate(&$form, &$form_state) { + form_set_error('text', t('Form validation error')); +}