5

Is there a way to create programmatically exposed filters in Drupal 7?

I searched a lot but I found only topics related remove or alter exposed filters already available in a view.

By instance my view doesn't provide any exposed filter. I must create it through the code in my module. I have a view but I can't change it via Views administration interface. I must achieve the result by implementing hook_views_pre_view() and add_item().

Unfortunately add_item is not very well documented or, at least, not the part concerning the $options array structure.

Given 'field_status' a "select list" with 3 items defined in the field configuration, and the following piece of code:

 function hook_views_pre_view(&$view, &$display_id, &$args) {
   $field = field_info_field('field_status');
   if (!empty($field)) {
    $filter = array(
     'identifier' => 'field_status',
     'exposed' => TRUE,
     'is_grouped' => FALSE,
     'table' => 'field_data_field_status',
     'type' => 'list_text',
     'expose' => array(
       'operator_id' => 'field_status_value',
       'label' => 'Status',
     )
   );
   $view->add_item($view->current_display, 'filter', 'field_data_field_status', 'field_status_value', $filter);
   $view->display_handler->set_option('css_class', 'view-status');
}

what should be the structure of the array $options (in my case $filter)?

As a result of this I can see the submit button 'Apply' and the label "Status" in an empty widget 'div'.

Here is the code edited following suggestions in comments:

function my_module_views_default_views_alter(&$views) {
  if (array_key_exists('my_view_name', $views)) {

    $options = array (
      0 => 'Blocked',
      1 => 'Active',
    );

    $display = $views['my_view_name']->display['my_view_page'];

    $display->display_options['filters']['field_status']['id'] = 'field_status';
    $display->display_options['filters']['field_status']['table'] = 'field_data_field_status';
    $display->display_options['filters']['field_status']['field'] = 'field_status';
    $display->display_options['filters']['field_status']['exposed'] = TRUE;
    $display->display_options['filters']['field_status']['expose']['operator_id'] = 'field_status_value';
    $display->display_options['filters']['field_status']['expose']['label'] = 'Status';
    $display->display_options['filters']['field_status']['expose']['operator'] = 'field_status_value';
    $display->display_options['filters']['field_status']['expose']['identifier'] = 'field_status';
    $display->display_options['filters']['field_status']['value'] = $options;

    $views['my_view_name']->display['my_view_page'] = $display;
  }
}

--- ALTERNATIVE SOLUTION ---

Since this problem seems to be hard to fix (@ least for my specific case) I have used a workaround to achieve the goal. The solution consists basically on a Views Block Clone with Exposed Filters which overrides the Views Block (without exposed filters) according to specific cases (Is User LoggedIn, Content Type, Contextual Filters ecc..).

1 Answer 1

3

Can you please try with hook_views_default_views_alter function. This function should be defined in MODULE_NAME/views/MODULE_NAME.views.inc file. And don't forget to include this file on .info file as files[] = views/MODULE_NAME.views.inc.

 function MODULE_NAME_views_default_views_alter(&$views) {
        if (array_key_exists('MY_VIEW_NAME', $views)) {
          $options = array(
          0 => 'Blocked',
          1 => 'Active',
          ); 
          $display = $views['MY_VIEW_NAME']->display['MY_VIEW_PAGE'];
          $display->display_options['filters']['field_status']['id'] = 'field_status';
          $display->display_options['filters']['field_status']['table'] = 'field_data_field_status';
          $display->display_options['filters']['field_status']['field'] = 'field_status';
          $display->display_options['filters']['field_status']['value'] = $options;
          $display->display_options['filters']['field_status']['exposed'] = TRUE;
          $display->display_options['filters']['field_status']['expose']['operator_id'] = 'field_status_value';
          $display->display_options['filters']['field_status']['expose']['label'] = 'Status';
          $display->display_options['filters']['field_status']['expose']['operator'] = 'field_status_value';
          $display->display_options['filters']['field_status']['expose']['identifier'] = 'field_status';
          $views['MY_VIEW_NAME']->display['MY_VIEW_PAGE'] = $display;
          }
    }
6
  • 1
    Great, thanks for precious information. I will make a test and will return to you with a feedback for this solution. Nov 7, 2016 at 9:25
  • 1
    Welcome. Please try and confirm if it got worked..
    – Aswini K
    Nov 7, 2016 at 10:08
  • 1
    Hi, the solution looks good in terms of cleanliness. Unfortuantely I got the same result with label and submit 'Apply' but no select list field. I also got the Notice: Undefined index: field_tags in views_handler_filter->accept_exposed_input(). Moreover, as far as I understood, this hook must be implemented streight in .module file otherwise it doesn't work. Any idea about that? Thank you anyway for your help!! I really appreciate Nov 7, 2016 at 17:54
  • 1
    Can u please include below code in to the above statement. I will edit my answer. $options = array( 0 => 'Blocked', 1 => 'Active', ); $display->display_options['filters']['field_status']['value'] = $options;
    – Aswini K
    Nov 8, 2016 at 8:56
  • 1
    Hi, I have added the snippet of code on my comment above. Nov 8, 2016 at 9:19

Your Answer

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

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