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

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.

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

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 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

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:

<?php
function 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.

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.

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

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.

Has anybody got a workaround for Drupal 5 yet?

I thought my upgrade to 5 was going too well!

Mark

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 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

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

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);
?>

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...

When I enabled this module, the form in my events_select view won't display in the event/select page.

Anybody know how to do this with a fused view (built using the views fusion module)?

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 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 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?

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 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 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...

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.

forgot to change the "your_view_name"

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)

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)

old news (views? ha ha?) , but i just figured it out for myself and thought i'd respond.

otherwise, the filter form appears for each filter you have set up once you set some values to filter on.

Add new comment