Drupal 6: Filtering a view’s exposed filter options to show relevant nodes
Recently I was working on a project that had a view with an exposed filter for country (via location module) and the dropdown list by default showed the entire country list, which was very large. I decided to write a code snippet that would reduce the select options to show only the countries that have been assigned to the nodes.
In my sandbox I create a simple node type for “person” that used the location module to capture the user’s country. I then created a view to show the people’s names and countries, and added an exposed filter for country.
Clicking on the exposed filter showed all of the available countries, which was a very large list.
I added the following code to my module to alter the exposed filter form and reduce the country list. (Please note, an alternative approach would be to modify the views object, I wanted to show how this could be accomplished in hook_form_alter())
<?php
/**
* Implements hook_form_alter()
*/
function MYMODULE_form_alter(&$form, $form_state, $form_id) {
// define variables
$view_name = 'people_places';
$filer_name = 'country';
// modify country drop down
if ($form_id == 'views_exposed_form' && is_object($form_state['view']) && $form_state['view']->name==$view_name && is_array($form[$filer_name])) {
// define SQL to fetch nodes that have countries
$sql = "
select distinct
l.country
from
{node} n
join
{location_instance} li on li.nid = n.nid and li.vid = n.vid
join
{location} l on l.lid = li.lid
where
n.status = 1 and n.type = 'person'
";
// fetch results
$resource = db_query($sql, $tid);
$countries = array();
while($row = db_fetch_object($resource)) {
$countries[] = $row->country;
}
// filter country list
foreach($form[$filer_name]['#options'] as $key => $value) {
// allow "All"
if ($key == 'All') {
continue;
}
elseif (!in_array($key, $countries)) {
unset($form[$filer_name]['#options'][$key]);
}
}
}
}
?>
Now the view only shows countries that match the resulting nodes.