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..).

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;
          }
    }
  • 1
    Great, thanks for precious information. I will make a test and will return to you with a feedback for this solution. – Fabrizio Fab01 Sabato Nov 7 '16 at 9:25
  • 1
    Welcome. Please try and confirm if it got worked.. – Aswini K Nov 7 '16 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 – Fabrizio Fab01 Sabato Nov 7 '16 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 '16 at 8:56
  • 1
    Hi, I have added the snippet of code on my comment above. – Fabrizio Fab01 Sabato Nov 8 '16 at 9:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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