Ivan Zugec

Drupal Consultant

Creating custom filters in views 2

A project that I’m currently working on requires a classifieds system which is fairly straight forward to setup. I’m using the location module for users to specify a location of the classified. To make the search easy I created a simple views page with exposed filters, but I wanted to have a select field with only Australian states.

Out of the box the location module only gives you an exposed autocomplete field for the state/province.

This is what I was trying to achieve.

From this:
filters_fig1_0.jpg

To this:
filters_fig2.jpg

The only way I could do this is with a custom filter.

Creating a custom filter

First we have to let views know about your module.

// in locationstate.module
function locationstate_views_api()
{
  return array(
    'api' => 2,
    'path' => drupal_get_path('module', 'locationstate') . '/inc',
  );
}

To keep the locationstate module directory tidy we’ll place all views file in the /inc folder.

Create a file called locationstate.views.inc in the /inc directory and add the hook_views_data function.


//In locationstate.views.inc
function locationstate_views_data() {

  $data = array();

  if(module_exists('location')) {

    $data['location']['state_au'] = array(
      'title' => t('States AU'),
      'help' => t('Filter by AU states.'),
      'real field' => 'province',
      'group' => t('Location state'),
      'filter' => array(
        'handler' => 'locationstate_handler_filter_state',
      ),
    );
  }

  return $data;
}

Next we’ll have to register the locationstate_handler_filter_state filter so views is aware of it.

You can do this by using the hook_views_handlers function.

//In locationstate.views.inc
function locationstate_views_handlers() {
  return array(
    'info' => array(
      'path' => drupal_get_path('module', 'locationstate') . '/inc',
    ),
    'handlers' => array(
      // The name of my handler
      'locationstate_handler_filter_state' => array(
        // The name of the handler we are extending.
        'parent' => 'views_handler_filter_string',
      ),
    ),
  );
}

Finally we’ll have to create the actual filter file. Because the filter is called locationstate_handler_filter_state, views will search for locationstate_handler_filter_state.inc with in the /inc directory.

Create a file called locationstate_handler_filter_state.inc and paste the following.

class locationstate_handler_filter_state extends views_handler_filter_string {
  /**
   * Shortcut to display the exposed options form.
   */
  function value_form(&$form, &$form_state) {

    $form['value'] = array(
    '#type' => 'select',
    '#title' => t('State'),
    '#options' => array(
      'ACT' => t('ACT'),
      'NSW' => t('NSW'),
      'NT' => t('NT'),
      'QLD' => t('QLD'),
      'SA' => t('SA'),
      'TAS' => t('TAS'),
      'VIC' => t('VIC'),
      'WA' => t('WA'),
      ),
    );

    return $form;
  }
}
}

There you have it, now you should have a custom views filter. Also check out http://thereisamoduleforthat.com/content/fun-views-and-location for more info. I have also attached the module to this post so you guys can download it.

UPDATE: Check this tutorial on creating a filter with SQL joins.
Drupal: How to create Views 2 filters for your new module

Version: 

Comments

manuee's picture

Submitted by manuee on

Hey, I think you just motivated me to finaly drop my guard when it comes to messing around with handlers, I had to do one the other day, and working out new filters seems like a great tool to have in your toolbox.

If I may say something, I guess you could've gotten the list of Australian states dynamicaly perhaps? I guess thats for another day =))

Thanks for the article!

ivan's picture

Submitted by ivan on

Thanks heheh...The views API sometimes looks like black magic. But once you dive in it's easy to get the hang of.

mr.andrey's picture

Submitted by mr.andrey on

Hello,

Thanks for the tutorial. I'm using it to build a different filter. Do you have to do anything special, like reinstall the module for the filter to show up? I cleared all caches, and it still doesn't want to show up.

Thanks,
Andrey.

ivan's picture

Submitted by ivan on

Hey Andrey,

Just double check the array in hook_views_data(). Sometimes that can cause the problem.
Also make sure your handler name in hook_views_data() matches the one in hook_views_handlers().

Hope this helps.

mr.andrey's picture

Submitted by mr.andrey on

Thanks, finally got it figured out. I was the way I did the joins that didn't work. I wrote a tutorial on how to do views filters with joins, for reference.

Here's the tutorial:

examiner.com/x-8158-Open-Source-Examiner~y2010m5d5-Drupal-How-to-create-Views-2-filters-for-your-new-module

Thanks again,
Andrey.

ivan's picture

Submitted by ivan on

Great article, I have added it to the post for reference.

Asif's picture

Submitted by Asif on

Great tutorial.
How to theme such exposed custom filter? I have added custom filters using above technique. Now I am trying to theme this exposed filter. So I have copied views-exposed-form.tpl.php, but some how in foreach($widgets as $id => $widget) --- $widget doesn't hold this exposed filter instead it gets printed in <?php print $button ?>. Could you please help me to theme filter?

Add new comment