August 9, 2016

I recently needed to add custom functionality to a Views filter on a Drupal 7 site, but ran into problems when I tried to hook into the views rendering process to update the options for an exposed filter.  The new options needed to be updated whenever a new item was added, but this filter happened to use a select list with manually specified options.  At first I thought I could use a simple form alter to update the filter options, and while the options were updated they did not properly map back into the View results.  The new options were useless!

To correctly update the filter options I hooked into View's render process.  This allowed me to get the needed data and rewrite the filter options with the correct data structure, then Views became aware of the updated items.

function mymodule_views_pre_view(&$view) {


  // Check that we are altering the correct view

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

    // In my case the required filter options were as simple as getting the available entity form types

    // You could use a custom query, or any number of Drupal functions to get data options

    $option_entities = entityform_get_types();


    // Get existing filter options so you can duplicate the structure

    $prev_filters =  $view->display_handler->get_option('filters');


    // Unset the existing filter values with empty array to store new values

    $prev_filters['label']['group_info']['group_items'] = array();


    // Use a counter to track the array keys

    $counter = 1;


    // Loop through entity form types and update filter options

    foreach($option_entities as $key => $form_option) {

      $prev_filters['label']['group_info']['group_items'][$counter]['title'] = $form_option->label;

      $prev_filters['label']['group_info']['group_items'][$counter]['operator'] = 'contains';

      $prev_filters['label']['group_info']['group_items'][$counter]['value'] = $form_option->label;



    // Save the new filter options to the view

    $view->display_handler->override_option('filters', $prev_filters);



That's it!  A quick way to programmatically update a simple Views filter.