By default an exposed optional multi-select filter on taxonomy vocabulary implies "any" when no options have been selected, the result being that all relevant nodes are returned regardless of what, if any, taxonomy vocabulary they have been associated with.

When the exact same view is used with the exposed filter form altered with hook_form_alter, so that checkboxes are used instead of a multi-select form element, the expected behaviour breaks down. When no checkboxes are checked the view returns nothing instead of the expected full listing of all relevant nodes regardless of any associated taxonomy vocabulary. Checking all of the checkboxes returns all of the nodes with an associated taxonomy vocabulary. There is no way to have the view output the nodes that do not have an associated vocabulary.

Switching the exposed filter form back to its default multi-select form element corrects the problem.

While exploring this issue I read through http://drupal.org/node/507556, which is somewhat related, but different.

Comments

merlinofchaos’s picture

Status: Active » Postponed (maintainer needs more info)

Please specify exactly how you have the filter configured. In particular, the setting of the 'operator' is crucially important. Exporting a view that exhibits the behavior you think is wrong will be the best way to demonstrate to us that it is wrong.

Beanjammin’s picture

Here is the exported view along with some additional information.

I notice that when the exposed filter form is unaltered the resulting SQL is:

SELECT node.nid AS nid,
   node.title AS node_title
 FROM node node 
 LEFT JOIN location_instance location_instance ON node.vid = location_instance.vid
 LEFT JOIN location location ON location_instance.lid = location.lid
 WHERE (node.status <> 0) AND (node.type in ('some_store'))

When the exposed filter form is altered the resulting SQL is:

SELECT node.nid AS nid,
   node.title AS node_title
 FROM node node 
 LEFT JOIN term_node term_node ON node.vid = term_node.vid
 LEFT JOIN term_data term_data ON term_node.tid = term_data.tid
 LEFT JOIN location_instance location_instance ON node.vid = location_instance.vid
 LEFT JOIN location location ON location_instance.lid = location.lid
 WHERE (node.status <> 0) AND (node.type in ('some_store')) AND (term_data.vid in ('0', '0', '0'))

This is how I am altering the form:

function custommod_form_alter(&$form, $form_state, $form_id) {
  switch ($form_id) {
    case 'views_exposed_form':
      // Make changes to exposed views filters
      if($form_state['view']->name == 'store_search') {
        // Change taxonomy vocab search from select to checkbox
        $form['vocabulary5']['#type'] = 'checkboxes';
      }
      break;
  }
}

Here is the exported view:

$view = new view;
$view->name = 'store_search';
$view->description = 'storesearch';
$view->tag = '';
$view->view_php = '';
$view->base_table = 'node';
$view->is_cacheable = FALSE;
$view->api_version = 2;
$view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */
$handler = $view->new_display('default', 'Defaults', 'default');
$handler->override_option('fields', array(
  'title' => array(
    'label' => 'Title',
    'alter' => array(
      'alter_text' => 0,
      'text' => '',
      'make_link' => 0,
      'path' => '',
      'link_class' => '',
      'alt' => '',
      'prefix' => '',
      'suffix' => '',
      'help' => '',
      'trim' => 0,
      'max_length' => '',
      'word_boundary' => 1,
      'ellipsis' => 1,
      'strip_tags' => 0,
      'html' => 0,
    ),
    'link_to_node' => 0,
    'exclude' => 0,
    'id' => 'title',
    'table' => 'node',
    'field' => 'title',
    'relationship' => 'none',
  ),
));
$handler->override_option('sorts', array(
  'distance' => array(
    'order' => 'ASC',
    'origin' => 'tied',
    'units' => 'km',
    'latitude' => '',
    'longitude' => '',
    'id' => 'distance',
    'table' => 'location',
    'field' => 'distance',
    'relationship' => 'none',
  ),
));
$handler->override_option('filters', array(
  'status' => array(
    'operator' => '=',
    'value' => '1',
    'group' => '0',
    'exposed' => FALSE,
    'expose' => array(
      'operator' => FALSE,
      'label' => '',
    ),
    'id' => 'status',
    'table' => 'node',
    'field' => 'status',
    'relationship' => 'none',
  ),
  'type' => array(
    'operator' => 'in',
    'value' => array(
      'some_store' => 'some_store',
    ),
    'group' => '0',
    'exposed' => FALSE,
    'expose' => array(
      'operator' => FALSE,
      'label' => '',
    ),
    'id' => 'type',
    'table' => 'node',
    'field' => 'type',
    'relationship' => 'none',
  ),
  'vid' => array(
    'operator' => 'in',
    'value' => array(),
    'group' => '0',
    'exposed' => TRUE,
    'expose' => array(
      'use_operator' => 0,
      'operator' => 'vid_op',
      'identifier' => 'vocabulary5',
      'label' => 'Taxonomy: Vocabulary',
      'optional' => 1,
      'single' => 0,
      'remember' => 0,
      'reduce' => 0,
    ),
    'id' => 'vid',
    'table' => 'term_data',
    'field' => 'vid',
    'relationship' => 'none',
  ),
));
$handler->override_option('access', array(
  'type' => 'none',
));
$handler->override_option('cache', array(
  'type' => 'none',
));
$handler = $view->new_display('page', 'Page', 'page_1');
$handler->override_option('path', 'storelocator');
$handler->override_option('menu', array(
  'type' => 'none',
  'title' => '',
  'description' => '',
  'weight' => 0,
  'name' => 'navigation',
));
$handler->override_option('tab_options', array(
  'type' => 'none',
  'title' => '',
  'description' => '',
  'weight' => 0,
));
dagmar’s picture

Status: Postponed (maintainer needs more info) » Active

@Beanjammin please remember change the status when you "provide more information"

merlinofchaos’s picture

Status: Active » Closed (won't fix)

Why is it that form altering something that works in Views to something else that doesn't work is a bug in Views? Sounds like a bug in your form alter, to me; or more likely, you're trying to do something that doesn't work. Note: checkboxes in exposed filters generally don't work. That's not Views' fault, it's just the way checkboxes work in GET forms.

bkosborne’s picture

This module may help others looking for a checkbox solution

http://drupal.org/project/better_exposed_filters