9

I've got several node types each of them referenced to different taxonomy term vocabulary. For category showing i use taxonomy_display module.

For example, we've got two categories: cues and billiard balls.

Cues has price from, price to and wood type filters. But balls has no wood type filter.

So i need to remove wood type filter if taxonomy_term tid referenced to billiard balls vocabulary.

Thus, I need to remove one of many exposed filters programmatically.

function modulename_views_pre_view(&$view, &$display_id, &$args) {
  // Some custom logic wich field_info_instances checking ...
  $filter_field = 'filter_id';
  // Removes from everywhere where i can find filter or filters properties
  unset($view->display[$view->current_display]->display_options['filters'][$filter_field]);
  unset($view->display[$view->current_display]->handler->options['filters'][$filter_field]);
  unset($view->display_handler->display->display_options['filters'][$filter_field]);
  unset($view->display_handler->options['filters'][$filter_field]);
}

Filter field removes successfully, but I've got php notice:

  Notice: Undefined index: field_wood_reference_tid in function views_handler_filter_term_node_tid->exposed_validate()

Also i try to remove field in hook_pre_execute(), but with the same result:

function modulename_views_pre_execute(&$view) {
  $filter_field = 'filter_id';
  unset($view->display_handler->handlers['filter'][$filter_field]);
  unset($view->filter[$filter_field]);
}

Also try with override_option() method like here - http://groups.drupal.org/node/82219, but no result at all.

Any suggestions? Pls help =)


Thanks to everybody for reply but I still has no answer. Maybe something is not clear? =(

4
  • Have you tried hook_views_pre_render()? You could also show/hide relevant filters depending on selection with jQuery.
    – dxc
    Commented Mar 27, 2013 at 5:54
  • Hi, I understand that your solution works okay, but there is not right way. So i can hide it using even CSS-conditions... Trying to explain. Each kind of code should place where it should be. For this issue if i hide exposed filter pre or after render, views still processes it. And if i try adding query string, smt like ?filter_id=val, views returns empty display or illegal choice error... Commented Mar 27, 2013 at 7:19
  • Have you tried my answer? Commented Apr 16, 2013 at 4:58
  • I don`t need to altering form (I know that your variant works), I wanna modify views object to has similar to yours result, but earlier than form builds. Commented Apr 16, 2013 at 9:25

9 Answers 9

5
+25

I would use hook_form_alter using unset on the form object as you are in your example for the element that you want to remove.

2

Here is the tested snippet which will allow you to remove the filters from the views exposed form using form alter as mentioned by Scott Thomas,

/**
 *Implements hook_form_FORM_ID_alter().
 */
function hook_form_views_exposed_form_alter(&$form, &$form_state) {
  $filter_field = 'filter_id';
  // Get the filters list for the current view. Here page_1 is the display ID.
  $filters = $form_state['view']->get_items('filter', 'page_1');
  if (isset($filters[$filter_field])) {
    $info_key = 'filter-' . $filter_field;
    unset($form[$filter_field], $form['#info'][$info_key]);
  }     
}

Apart from removing the form field you also need to remove the information for particular filter which is available in $form['#info'], So that it will remove the label also. If you remove the form element alone then the filter label will be displayed even though the field is removed, So always make sure that you're removing this information also.

Modify this according to your need. If you want to perform this one for particular view then add a condition for that too like ,

if ($form_state['view']->name == 'view_name') {
  // DO your operation.
}

Here $form_state['view'] will give you the current view object which is being processed.

Hope this helps.

1
  • This was the only solution that hid the labels as well as field widgets for me, and it worked in an exposed filter form in a block.
    – xenophyle
    Commented Nov 7, 2019 at 18:36
1

Follow the steps below

  1. Firstly write a hook_form_alter in a custom module
  2. Next try the following piece of code

    unset($form['#info']['your_field_name']); $form['your_field_name']['#access'] = 'FALSE';

Hope that helps.

1

You can remove exposed filter using template file as well.

Use this command:

cp sites/all/modules/contrib/views/theme/views-view.tpl.php sites/all/themes/costa/templates/views/views-view--<machine_name>.tpl.php

In the template file find this code:

  <?php if ($exposed): ?>
    <div class="view-filters">
      <?php print $exposed; ?>
    </div>
  <?php endif; ?>

And remove it. Your exposed filter will be removed from display, but will keep working of you pass proper arguments in URL.

1
  • Thx for reply, but I'm waiting D8 that uses core form api for building exposed filters :) Commented Jul 3, 2015 at 11:57
0

Correct me if I'm wrong because I'm not sure to fully understand your issue. So you would like to hide an exposed filter in a view depending on an other exposed filter's value? If so you can try Views Dependent Filters module. I used it several times and it does the job.

You can check our fiend Lullabot's review about this module.

If you really need to do it in code the exposed option should work: filter[$filter_id]->options['exposed'] = FALSE;

2
  • I would like to hide exposed filter if current content type has no this (filtered) field. Trying your snippet $view->display_handler->handlers['filter'][$filter_field]->options['exposed'] = FALSE; i have fatal error - PHP Fatal error: Call to undefined method stdClass::access() in .../view.inc on line 766. I think its correct behavior because if filter is not exposed, it also required default value. Any ideas? Commented Apr 11, 2013 at 21:54
  • pastebin.com/f1FKgUde here is my code, maybe it will be more clear than my english Commented Apr 11, 2013 at 22:07
0

The following did it for me inside hook_form_alter:

$info_key = 'filter-' . $fieldName;
unset($form[$fieldName], $form['#info'][$info_key], $form_state['view']->display_handler->options['filters'][$fieldName], $form_state['view']->display_handler->handlers['filter'][$fieldName], $form_state['view']->filter[$fieldName]);
0

Method 1

By using hook_views_query_alter(). See the following example:

<?php
/**
 * Implements hook_views_query_alter().
 */
function foo_views_query_alter(&$view, &$query) {

  if ($view->name == 'foo_view') {

    // Allow any distance when the postcode it is not specified.
    if (empty($_GET['postcode']['postal_code']) || $_GET['postcode']['postal_code'] === 'All') { 
      // Scan through the query.
      foreach ($query->where as $condition_group_key => &$condition_group) {
        foreach ($condition_group['conditions'] as $condition_key => &$condition) {
          $search_name = '(COALESCE(ACOS(';
          if (is_string($condition['field']) && strstr($condition['field'], $search_name) !== FALSE) {
            // Remove filter from the query.
            unset($query->where[$condition_group_key]['conditions'][$condition_key]);
          }
        } // end: foreach
      } // end: foreach
    } // end: if


    /*
     * Change the field conditions.
     * Possible field values: 1, 2, 3
     * Logic: When 3 is selected, then display 1, 2 and 3.
     */
    switch (@$view->display_handler->handlers['filter']['field_123_value']->value[0]) {

      case 3:
        foreach ($query->where as $condition_group_key => &$condition_group) {
          foreach ($condition_group['conditions'] as $condition_key => &$condition) {
            if($condition['field'] == 'field_data_field_123.field_123_value') {
              unset($query->where[$condition_group_key]['conditions'][$condition_key]);
              $query->where[] = array(
                  'conditions' => array(
                      array(
                          'field' => 'field_data_field_123.field_123_value',
                          'value' => 1,
                          'operator' => "=",
                      ),
                      array(
                          'field' => 'field_data_field_123.field_123_value',
                          'value' => 2,
                          'operator' => "=",
                      ),
                      array(
                          'field' => 'field_data_field_123.field_123_value',
                          'value' => 3,
                          'operator' => "=",
                      ),
                  ),
                  'args' => array(),
                  'type' => 'OR',
              );
            }
          }
        } // end: foreach
        break;

    } // end: switch

  } // end: if
}

Method 2

See the example by using hook_views_pre_execute and custom function which trying to find the right field condition and return the reference to it:

/**
 * Implements hook_views_pre_execute().
 */
function foo_views_pre_execute(&$view) {

  if ($view->name == 'foo_view') {


    foo_get_view_filter_recursively(
      $view,
      $view->build_info['query']->conditions(),
      'field_data_field_123.field_123_value',
      $filter
    );

    // We want our filter to work as a bit mask.
    $filter[0]['operator'] = '&';

    unset ($filter);

    // Example of finding Proximity filter condition
    $search_name = '(COALESCE(ACOS(';

    foo_get_view_filter_recursively(
      $view,
      $view->build_info['query']->conditions(),
      $search_name,
      $filter
    );

    if (empty($_GET['postcode']['postal_code']) || $_GET['postcode']['postal_code'] === 'All') {
      // Allowing any distance.
      $filter[0]['value'][':distance'] = 10000000;
    }
    else {
      $filter[0]['value'][':distance'] = 80000;
    }

    unset ($filter);


    // Fetching single record?

    foo_get_view_filter_recursively(
      $view,
      $view->build_info['query']->conditions(),
      'node.nid',
      $filter
    );

    if (!empty($_GET['nid'])) {
      $filter[0]['value'] = (int) $_GET['nid'];
    }
    else {
      $filter[0]['operator'] = '<>';
    }

    unset ($filter);                                                        

    // echo '<pre style="font-size:11px;font-family: Monaco">'; print_r($view->build_info['query']); exit;
  }
}

/**
 * Custom function to find the field condition within the view
 */
function foo_get_view_filter_recursively($view, &$conditions, $field_name, &$filter) {

  if (!empty($conditions)) {

    foreach ($conditions as &$condition) {
      if ($condition instanceof DatabaseCondition) {
        if (foo_get_view_filter_recursively($view, $condition->conditions(), $field_name, $filter)) {
          return TRUE;
        }
      } else if ($condition['field'] instanceof DatabaseCondition) {
        if (foo_get_view_filter_recursively($view, $condition['field']->conditions(), $field_name, $filter)) {
          return TRUE;
        }
      } elseif (is_string($condition['field']) && strstr($condition['field'], $field_name) !== FALSE) {
        @$filter = array(&$condition);
        return TRUE;
      }
    } // end: foreach

  } // end: if

  return FALSE;
}
0

I'm removing it from template files. Override the views-view.tpl.php and remove the following code from it:

  <?php if ($exposed): ?>
    <div class="view-filters">
      <?php print $exposed; ?>
    </div>
  <?php endif; ?>
0

I think the op was on the right track. I had a similar situation without exposed filters so I could not use the hook_form_alter method. Here is some example code for anyone else coming across this:

$view->set_item($view->current_display, 'filter', $filter_id, null);

The view object does not have a remove_item function but simply states in the code that you can set it to null in order to remove an item including filters: views/includes/view.inc on line 2526.

Here is a full example for anyone that targets a specific view and display:

/**
 * Implements HOOK_views_pre_view().
 */
function HOOK_views_pre_view(&$view) {
  if($view->name == 'VIEW_MACHINE_NAME') {
    switch($view->current_display) {
      case 'VIEW_DISPLAY_MACHINE_NAME':
        $view_filters = $view->display_handler->get_option('filters');
        foreach ($view_filters as $filter_id => $filter) {
          if ($filter_id == 'my_filter') {
            $view->set_item($view->current_display, 'filter', $filter_id, null);
          }
        }
      break;
    }
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.