Recent comments

Quick and dirty views exposed filter form select replacement in a block

firebus's picture

I have a client who wants an exposed filter but, instead of having a select drop down, would like to replace it with a set of links.

This is not an uncommon use case, and there are some existing examples on how to do this. It's pretty easy, since views will read a value for the exposed filter from a query string.

But what if your exposed filter form is in a block? Exposed filter forms in blocks only work if you enable AJAX for the exposed filter, and the ajax dynamically replaces the contents of the block with the results of your selection.

In this case, in addition to replacing the select with links, you need to add a javascript event handler to the links that will duplicate (or invoke) the ajax.

Step 1. my_theme_preprocess_views_exposed_form

You could also use hook_form_alter, for some reason this seemed more straightforward to me.

We're going to go through the select key/value pairs, and create a set of links that we add to the $variables array. We're also going to include a javascript file that will be created in step 2.


function my_theme_preprocess_views_exposed_form(&$variables) {
// return an array of links that we can display in the form
$filter_links = array();
foreach ($variables['form']['tid']['#options'] as $key => $value) {
$filter_links[] = l($value, '', array(
'attributes' => array(
'class' => 'filter-link',
'data-value' => $key,
),
'fragment' => 'filter',
));
}
$variables['filter_links'] = $filter_links;


drupal_add_js(drupal_get_path('theme', 'my_theme') . '/js/exposed_filter.js', 'theme');
}

Step 2. exposed-filter.js

Add js/exposed-filter.js to your theme.

We're going to add a click event handler to each of the links we created in step 1 that will set the value of the existing submit input, and will submit the form. Once the form is submitted, the jQuery behavior supplied by Views takes over.


Drupal.behaviors.my_theme_exposed_filter = function(context) {
$('a.filter-link', context).bind('click', function() {
$('select#edit-tid').val($(this).attr('data-value'));
$('div.view-filters form').submit();
});
}

Step 3. views-exposed-form--VIEW-NAME--block-DELTA.tpl.php

Copy views/themes/views-exposed.form.tpl.php to your theme so that you can print the links you added in the preprocess function.


<div class="links">
<?php
foreach ($filter_links as $link) {
print "$link\n";
}
?>
</div>

Optionally, you can remove the submit button here if you want.

Step 4. Hide the select input in CSS

There's more than one way to do this. However, it's required that you hide the select instead of omitting it, since Views will read from the select when the form is submitted.


form#views-exposed-form-VIEW-NAME-block-DELTA div.views-widget {
display: none;
}

This is, admittedly, an ugly way to do it, but it works. An extension to the better exposed filters project would be much nicer.

Also, *why* is it that exposed filters only work in blocks via ajax? Shouldn't it be possible to reload the page that a block is on with a query string that the block view can recognize? You could use the block ID to disambiguate in the case that multiple blocks with exposed filter forms were on the same page...


Comments

Addition to BEF

This kinda, sorta exists in Better Exposed Filters (see http://drupal.org/node/894312 and http://drupal.org/node/1111712), though in admittedly very early, and thus buggy, form. (Though only for Views 3.x since this originally came from links as a display option for exposed sorts).

The current implementation relies on tweaking the URL of each link so that clicking on a new filter option results in a page load -- not very Web 2.0 -- so I haven't given much effort to make it work with AJAX. I'll take a look at your example and see if that is doable in BEF. And, if you're so inclined, patches are always welcome in the BEF queue!

Thanks for posting.


firebus's picture

BEF

thanks for your response!

i looked at BEF before i wrote this hack, but saw that it only supports views 3, so i moved on.

i haven't really had a chance to play with views 3 at all yet, but would be interested in finding a more generic solution to this problem, and learning more about views ajax forms. i'll put it on my patch todo list!


Powered by Drupal - Design by Artinet - Amazon Affiliate