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:
To this:
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
Comments
thanks
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!
Thanks heheh...The views API
Thanks heheh...The views API sometimes looks like black magic. But once you dive in it's easy to get the hang of.
Doesn't show up
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.
Hey Andrey, Just double
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.
Thanks!
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.
Awesome
Great article, I have added it to the post for reference.
How to theme such exposed custom filter
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?
First I would try and style
First I would try and style it with just CSS instead of overriding templates.
Exposed filters are getting added at the end
Also these filters are getting added at the end of already existing CCK exposed filters, even though we shuffle their order in views.
This can be tricky
Look at hook_form_alter function to change the order of the exposed filters.
Add new comment