So you have Views, and you've figured out exposed filters. Which, in short, gives nice handy little widgets to search. Often by keyword or by some taxonomy term.
Now what you want to do is put that functionality in a block. Say you're doing a catalog search or you have something you just want to always be up.
No Problem!
You need 2 snippets. In Drupal 4.7, the first goes in a custom block, and looks thus:
I'm going to call the view 'catalog'. Anywhere you see that word below, you'll need to replace it with your view name. This is especially true in the theme function.
<?php
$view = views_get_view('trackerx');
$form = views_filters_form($view);
$form['#action'] = url($view->url);
return drupal_get_form("views_filters_$view->name", $form, 'views_filters');
?>That block will display the filter form; the #action bit is to make sure the form goes to the right place. [Note: Views 1.1 will correct this so that part won't be quite as necessary.)
Now, you need to do one other thing: Make the exposed filter *not display* on the view itself, otherwise you'll get it twice. This is bad CSS at the very least, and very confusing to the user. But it's easy to get rid of.
In your template.php:
<?php
function phptemplate_views_display_filters_catalog() {
// Do absolutely nothing.
}
?>Because you're not using this theme function above, but instead displaying the filter directly...the filter will no longer display except in your block.

Comments
Simplicity proves design principles
The fact that you can do this so easily proves just how well designed Views is. Of course you're benefitting from FAPI and the block system, too, but wow - 6 lines of code including an empty function, and you're done! Great snippet.
You rock
merlin, you kick almost as much ass as Views itself does. :-)
I would be trackbacking this, but you don't have trackbacks enabled, so: http://www.garfieldtech.com/blog/merlin-the-amazing
I've been trying to figure this out.
This type of post is a very valuable to those of us without coding experience. This helps expose some of the possiblities that I don't always grok. Three cheers for Merlin!
Hi, when I try it, it gives
Hi, when I try it, it gives me a long horizontal filter. How do I work it so the filters go on top top of each other?
ie.
Filter 1
Filter 2
Filter 3
--- Submit
instead of
Filter 1 Filter 2 Filter 3 ---Submit
Cheers, Sean
Theming!
In 4.7 you can theme the filter form. In Drupal 5 I'm still working on how to replicate this, as form api has actually lost the functionality:
<?phpfunction phptemplate_views_filters_VIEWNAME($form) {
return form_render($form);
}
?>
This might not give you your labels though, because they're done in the theme, so you might need to put them back in.
Where do I put this script?
Sorry, I'm a complete caveman when it comes to scripting. Where do I place this code? Is it in the template or is it in the theme. And what do I do with it once I've got it set up?
Thanks for you help. I really appreciate the coolness of your work.
A Bit Late But...
You can really place this code absolutely anywhere. Create a new page and change your input format to php and place it there or drop it straight into your theme template, or you could even place this in a block. Like I said you really can put this anywhere.
Hope this helps.
Peace!
Matthew Pare
www.paretech.com
Typo
Merlin, looks like there is a typo in that code. It says 'trackerx' in the code, but you call the view 'catalog' in the description.
Update for 5?
Has anybody got a workaround for Drupal 5 yet?
I thought my upgrade to 5 was going too well!
Mark
Update for 5 using View Block
I've enabled the Views Filter Block (this is just for Drupal 5?) and can now apply:
function phptemplate_views_filterblock($form) {$view = $form['view']['#value'];
foreach ($view->exposed_filter as $count => $expose) {
$label = '<div class="form-element-label">'.$expose['label'].'</div>';
$formelement = drupal_render($form["op$count"]) . drupal_render($form["filter$count"]);
$o .= '<div class="form-element-'.$count.' form-element-'.$expose['label'].'">'.$label.$formelement.'</div>';
}
$o .= '<div class="form-submit-button">' . drupal_render($form['submit']) . '</div>';
return $o . drupal_render($form);
}
This gives me what I want.
Is it possible to theme the exposed filters, by view name?
did you ever figure out how
did you ever figure out how to theme specific filterblocks? I'm most interested in figuring out a way to modify the contents of the filter's selectbox in order to take out options that shouldn't be available to the exposed filter.
-campsoupster
Update 2 for 5 using View Block
You can use this. Works at me with 5.2.
template.php
function phptemplate_views_filterblock($form) {return _phptemplate_callback('views_filterblock', array('form' => $form));
}
views_filterblock.tpl.php
<?php
/* $Id: views_filterblock.tpl.php, v 1.0 2007/09/17 quiptime Exp $ */
drupal_add_js('misc/collapse.js');
$view = $form['view']['#value'];
// make the 'q' come first
$output = drupal_render($form['q']);
foreach ($view->exposed_filter as $count => $filter) {
$newform["fieldset$count"] = array(
'#type' => 'fieldset',
'#title' => $filter['label'],
'#collapsible' => true,
'#weight' => $count - 1000, // we'll never have this many filters
);
$newform["fieldset$count"]['#collapsed'] = TRUE;
}
foreach ($form as $field => $value) {
if (preg_match('/(op|filter)([0-9]+)/', $field, $match)) {
$curcount = $match[2];
$newform["fieldset$curcount"][$field] = $value;
if (!isset($newform["fieldset$curcount"]['#weight'])) {
$newform["fieldset$curcount"]['#weight'] = $value['#weight'];
}
}
else {
if ($field == 'submit' || drupal_substr($field, 0, 1) == '#') {
unset($curcount);
}
if (isset($curcount)) {
$newform["fieldset$curcount"][$field] = $value;
}
else {
$newform[$field] = $value;
}
}
}
foreach ($view->exposed_filter as $count => $filter) {
if ($filter['is_default']) {
$newform["fieldset$count"]['#collapsed'] = FALSE;
$open = TRUE;
}
else {
$value = $newform["fieldset$count"]["filter$count"]['#default_value'];
if (isset($value)) {
if (is_array($value)) {
foreach ($value as $key => $item) {
if ($item != '') {
$newform["fieldset$count"]['#collapsed'] = FALSE;
$open = TRUE;
}
}
}
elseif ($value != '') {
$newform["fieldset$count"]['#collapsed'] = FALSE;
$open = TRUE;
}
}
}
}
if (!$open) {
$newform["fieldset0"]['#collapsed'] = TRUE; // first fieldset, make this TRUE or FALSE
}
// make any fieldset TRUE or FALSE
//$newform["fieldset2"]['#collapsed'] = FALSE;
print theme('views_filterblock_output', $newform);
?>
--------------
quiptime
Code for the block - drupal 5.2
The following code from merlin did not work by me:
<?php$view = views_get_view('trackerx');
$form = views_filters_form($view);
$form['#action'] = url($view->url);
return drupal_get_form("views_filters_$view->name", $form, 'views_filters');
?>
Therefore I replaced it by this code:
<?php$view = views_get_view('trackerx');
$form = drupal_retrieve_form('views_filters', $view);
$form['#action'] = url($view->url);
drupal_process_form('views_filters', $form);
return drupal_render_form('views_filters', $form);
?>
Theming the filter...
The "Views Filter Block" module is great - it packages up this nifty little behavior into an easy-to-administer module. But....
if you are going to all the trouble of custom theming your filter anyhow (which, IMO, was one of the big reasons to get the module) OR if you want to do this yourself without the overhead of a module, you can simply override:
function theme_views_filters($form)in your template.php file to layout the form... in addition to creating the custom block and hiding the filter on the view itself, of course.
You can custom theme the filter per-view with
function phptemplate_views_filters_YOUR_VIEW($form)BUT this does not work for filters displayed in a block, I suspect because the request for theming the filter originates from the block, not the view, so the above never gets called. There is probably a way though...
Filter form
When I enabled this module, the form in my events_select view won't display in the event/select page.
Fusion
Anybody know how to do this with a fused view (built using the views fusion module)?
I've been trying to figure this out.
This type of post is a very valuable to those of us without coding experience. This helps expose some of the possiblities that I don't always grok. Three cheers for Merlin
did you ever figure out how
did you ever figure out how to theme specific filterblocks? I'm most interested in figuring out a way to modify the contents of the filter's selectbox in order to take out options that shouldn't be available to the exposed filter.
-campsoupster
I'm trying to get this
I'm trying to get this working in Drupal 6 w/Views 2 and can't determine how to get the $form object to pass to drupal_get_form. Anyone else figure this out already?
Show me your's, I'll show you mine :-)
Hi Greg,
Could you show me how you tried to accomplish it in your described setup. I'm trying to do the same, but it doesn't work either (see http://drupal.org/node/290691). Maybe we could learn from each other's code.
Bart
I think I've got this
I think I've got this working in Drupal 6 (views2) - see reply I've posted to the above node on drupal.org or http://www.computerminds.co.uk/displaying-exposed-filter-form-views-drup...
Yes, this seems to work for
Yes, this seems to work for drupal6/views2:
$view = views_get_view('your_view_name');$view->set_display('default');
$view->init_handlers();
$form_state = array(
'view' => $view,
'display' => $view->display_handler->display,
'method' => 'get',
'rerender' => TRUE,
'no_redirect' => TRUE,
);
$output = drupal_build_form('views_exposed_form', $form_state);
return $output;
Taken from http://www.computerminds.co.uk/displaying-exposed-filter-form-views-drup...
set_display()
I get this PHP error when I use the code above:
Fatal error: Call to a member function set_display() on a non-object in drupal\includes\common.inc(1547) : eval()'d code on line 4
What am I doing wrong? Using D6.6.
how careless of me
forgot to change the "your_view_name"
the whole form?
I've tried the code from http://www.computerminds.co.uk/displaying-exposed-filter-form-views-drup...
but the filter only shows the submit button, what am I missing here? (Drupal 6)
same here
sane issue:
I've tried the code from http://www.computerminds.co.uk/displaying-exposed-filter-form-views-drup...
but the filter only shows the submit button, what am I missing here? (Drupal 6)
put that code inside your view header with php formatting
old news (views? ha ha?) , but i just figured it out for myself and thought i'd respond.
and set "Exposed form in block" to "yes"
otherwise, the filter form appears for each filter you have set up once you set some values to filter on.
Add new comment