Download & Extend

Exposed filter gets error class without submitting it

Project:Views
Version:7.x-3.x-dev
Component:exposed filters
Category:bug report
Priority:major
Assigned:Unassigned
Status:needs work
Issue tags:exposed filter

Issue Summary

I have some fields exposed in filter criteria, and my exposed form style is input required.
So as expected, when i visit the view path i see only the exposed form and no results from the view, until i submit (or apply the filters). What i don't want is to be able to submit an empty form and see all the results from my view, so i check the fields i need to have a value as required but they automatically receive an .error class (so they get a red margin) before i apply the filters (or submit). I would like to have this validation after the form is submitted not before, since, in my understanding, the whole meaning of having input required is to wait for the filters to be applied (and maybe do some validation if something is marked as required) then show results.

This also happens when the form is exposed in a block.
What i wanted is to have my filters exposed in a block and loaded in a region on my home page, then submit the form and see the results in my view. It works as expected with this one little drawback, the required fields in the exposed form receive the .error class before the form is submitted even though the validation should be done after submission

Comments

#1

facing the same problem and not sure if to simply override it using js or dive deeper into the module (which might end up consuming hell lot of time)

#2

facing the same problem and not sure if to simply override it using js or dive deeper into the module (which might end up consuming hell lot of time)

#3

Well the only hint i have is in
sites/all/modules/views/plugins/views_plugin_exposed_form.inc line 151 in function render_exposed_form
its using this function to build the form, $form = drupal_build_form('views_exposed_form', $form_state);
and drupal_build_form does the processing, validation and submission all in one go (from here
http://api.drupal.org/api/drupal/includes!form.inc/function/drupal_build_form/7 )

On the other hand, when you build forms in a module you can just use drupal_get_form, and provide the function that builds the render array to it. Then have a _validate function and it runs as expected, you get the form, and on submission it's validated (also shows validation error messages if it doesn't pass). Example here
http://codekarate.com/daily-dose-of-drupal/drupal-7-module-development-p...

#4

Hi, have the same issue, don't know how to fix this, but this definitely needs some work, because this behavior is incorrect.

#5

Version:7.x-3.5» 7.x-3.x-dev

Bug confirmed in views-7.x-3.5+37-dev on two separate websites using required exposed textfields and the "exposed form style" set to either "input required" or "basic".

Here's a simple view to test it:

<?php
$view
= new view();
$view->name = 'exposed_test';
$view->description = '';
$view->tag = 'default';
$view->base_table = 'node';
$view->human_name = 'Exposed test';
$view->core = 7;
$view->api_version = '3.0';
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */

/* Display: Master */
$handler = $view->new_display('default', 'Master', 'default');
$handler->display->display_options['title'] = 'Exposed test';
$handler->display->display_options['use_more_always'] = FALSE;
$handler->display->display_options['access']['type'] = 'perm';
$handler->display->display_options['cache']['type'] = 'none';
$handler->display->display_options['query']['type'] = 'views_query';
$handler->display->display_options['exposed_form']['type'] = 'basic';
$handler->display->display_options['pager']['type'] = 'full';
$handler->display->display_options['pager']['options']['items_per_page'] = '10';
$handler->display->display_options['style_plugin'] = 'default';
$handler->display->display_options['row_plugin'] = 'node';
/* Field: Content: Title */
$handler->display->display_options['fields']['title']['id'] = 'title';
$handler->display->display_options['fields']['title']['table'] = 'node';
$handler->display->display_options['fields']['title']['field'] = 'title';
$handler->display->display_options['fields']['title']['label'] = '';
$handler->display->display_options['fields']['title']['alter']['word_boundary'] = FALSE;
$handler->display->display_options['fields']['title']['alter']['ellipsis'] = FALSE;
/* Filter criterion: Content: Title */
$handler->display->display_options['filters']['title']['id'] = 'title';
$handler->display->display_options['filters']['title']['table'] = 'node';
$handler->display->display_options['filters']['title']['field'] = 'title';
$handler->display->display_options['filters']['title']['operator'] = 'contains';
$handler->display->display_options['filters']['title']['exposed'] = TRUE;
$handler->display->display_options['filters']['title']['expose']['operator_id'] = 'title_op';
$handler->display->display_options['filters']['title']['expose']['label'] = 'Title';
$handler->display->display_options['filters']['title']['expose']['operator'] = 'title_op';
$handler->display->display_options['filters']['title']['expose']['identifier'] = 'title';
$handler->display->display_options['filters']['title']['expose']['required'] = TRUE;
$handler->display->display_options['filters']['title']['expose']['remember_roles'] = array(
 
2 => '2',
 
1 => 0,
 
3 => 0,
);

/* Display: Page */
$handler = $view->new_display('page', 'Page', 'page');
$handler->display->display_options['defaults']['hide_admin_links'] = FALSE;
$handler->display->display_options['path'] = 'exposed-test';
$handler->display->display_options['menu']['type'] = 'normal';
$handler->display->display_options['menu']['title'] = 'Exposed';
$handler->display->display_options['menu']['weight'] = '0';
$handler->display->display_options['menu']['context'] = 0;
$handler->display->display_options['tab_options']['weight'] = '0';
?>

#6

The error class was introduced in Drupal 7.17. I managed to trace it to this patch in form.inc.

Here's the (reopened) issue: #1785436: Submission of #required elements without #title and empty value does not display any error

#7

Priority:normal» major

(semi-crosspost with #1785436: Submission of #required elements without #title and empty value does not display any error #22)

Hmmm... Further investigation points to this piece of code in views/plugins/views_plugin_exposed_form.inc->render_exposed_form()

<?php
    $form_state
= array(
     
'view' => &$this->view,
     
'display' => &$this->display,
     
'method' => 'get',
     
'rerender' => TRUE,
     
'no_redirect' => TRUE,
     
'always_process' => TRUE,
    );

...

   
$form_state['exposed_form_plugin'] = $this;
   
$form = drupal_build_form('views_exposed_form', $form_state);
   
$output = drupal_render($form);
?>

In this case 'always_process' => TRUE triggers form validation, which < Drupal 7.17 did throw an error(!), but without the error class. I now believe the patch from this issue reveiled the error in the views exposed filter plugin instead of causing it ...

The attached patch only processes the form if there actually is input. This seems to be a really straight-forward fix for a long time error which became visible with the fix in Drupal 7.17, but it also changes the way you have to set default values for exposed filters.

Before the patch:

<?php
if (!isset($form_state['view']->exposed_input['my_field'])) {
 
$form_state['input']['my_field'] = 'my value';
}
?>

after the patch:
<?php
$form
['my_field']['#default_value'] = 'my value';
?>

You now can omit the if () because 'always_process' is triggered when there's input available from $_GET (or session, etc) and will override whatever you set as default value with the input.

Bumping it to 'major' since a lot of websites will encounter this bug/misbehaviour when updating to Drupal 7.17+.

AttachmentSizeStatusTest resultOperations
1877678_views_plugin_exposed_form_check_input.patch815 bytesIdleFAILED: [[SimpleTest]]: [MySQL] 1,580 pass(es), 23 fail(s), and 0 exception(s).View details | Re-test

#8

Status:active» needs review

Note to self: do not only check if you've actually attached the patch, also check if you set the status to 'needs review' ;)

#9

Status:needs review» needs work

The last submitted patch, 1877678_views_plugin_exposed_form_check_input.patch, failed testing.

#10

Not only did my patch fail testing, it's also not good enough.

I only check if there's input, not if the input matches the exposed filters in this view. This means that all forms are processed when there's input and the error class returns for all exposed filters on that page.

This also explains this function in views_plugin_exposed_form_input_required.inc

<?php
 
function exposed_filter_applied() {
    static
$cache = NULL;
    if (!isset(
$cache)) {
     
$view = $this->view;
      if (
is_array($view->filter) && count($view->filter)) {
        foreach (
$view->filter as $filter_id => $filter) {
          if (
$filter->is_exposed()) {
           
$identifier = $filter->options['expose']['identifier'];
            if (isset(
$view->exposed_input[$identifier])) {
             
$cache = TRUE;
              return
$cache;
            }
          }
        }
      }
     
$cache = FALSE;
    }

    return
$cache;
  }
?>

A revisited patch will probably move that function into views_plugin_exposed_form.inc and use it instead of $exposed_input = $this->view->get_exposed_input();

#11

Status:needs work» needs review

Here's the revised patch which moves get_exposed_input() into the views_plugin_exposed_form class. I had to get rid of the static cache because it had to be cached for each identifier.

Really hoping someone looks into this ...

AttachmentSizeStatusTest resultOperations
1877678_views_plugin_exposed_form_check_input_2.patch2.37 KBIdleFAILED: [[SimpleTest]]: [MySQL] 1,604 pass(es), 23 fail(s), and 0 exception(s).View details | Re-test

#12

Status:needs review» needs work

The last submitted patch, 1877678_views_plugin_exposed_form_check_input_2.patch, failed testing.

#13

Title:Exposed form with style input required» Exposed filter gets error class without submitting it

Changing the title to reflect the problem. Still hoping someone looks into this.

#14

Status:needs work» needs review

#11: 1877678_views_plugin_exposed_form_check_input_2.patch queued for re-testing.

#15

Status:needs review» needs work

The last submitted patch, 1877678_views_plugin_exposed_form_check_input_2.patch, failed testing.