Search code examples
drupaldrupal-viewsdrupal-exposed-filter

Decouple all the exposed filters in Drupal with each other and make each exposed filter as a separate block


I have created a custom content type and using views2 for creating various page-views. I have used a taxonomy (having 4 terms, say "A", "B", "C" and "D") for broader categorization of this content type. There are 4 other taxonomies corresponding to each of the above terms "A", "B", "C" and "D" called "Taxonomy-A", "Taxonomy-B", "Taxonomy-C" and "Taxonomy-D" which are used to further sub-categorize this content type in a particular category (say "A" or "B" etc.). The sub-category "Taxonomy-A" is visible on the node edit form only if broader category "A" is selected. Similar is the case with "B", "C" and "D" categories. Now in my page-views, i have used Taxonomy terms "A", "B", "C" and "D" as my first arguments of the url. Thus the following url

www.example.com/A

provides all the published custom content types of "category A". Similar will be the cases for "category B", "category C" etc. Now to filter my content types of a particular category (say "A") into its sub-categories, i have created FOUR exposed filters corresponding to each Taxonomy "Taxonomy-A", "Taxonomy-B", "Taxonomy-C" and "Taxonomy-D". Now i would like to show only one filter on each type of "page-view";i.e.
Filter corresponding to "Taxonomy-A" on www.example.com/A page-view
Filter corresponding to "Taxonomy-B" on www.example.com/B page-view
Filter corresponding to "Taxonomy-C" on www.example.com/C page-view etc.

If i configure basic setting of view to show filter in a separate block, then the filter block contains all the Four Filter plus apply button. But I want to show only one filter (based on page url's first argument) with apply button.

Actually i would like to decouple all the exposed filters with each other and make each exposed filter as a separate block which can be assigned to a template region. Is it possible to achieve this by theming (each select element on views exposed filter form has different "id")? Otherwise the only option left with me is to create separate content types for each category "A", "B", "C" and "D", which is not a practical solution if the number of categories are large.

How i can achieve this?

Thanks in advance for your response!!


Solution

  • 1. Super Slick

    Well, the slick way would be to look at how you might modify Views to spit out the different exposed filters into different blocks, possibly determined by a block delta setting in the configuration for each filter. That would be neat.

    2. Overkill/Redundant/FAPI-hook_block() Drill

    Get your exposed block, then use hook_form_alter() to hide the filters you want to put on a different block. Then create new blocks programmatically in a new module (or if you absolutely must, the PHP Filter module and a custom block through the GUI). In that module, replicate the form elements you need in that block, including the unique exposed filter. It's useful to remember that exposed filters don't care about the form. They care about the querystring. You could type in your filter arguments in the URL if need be.

    3. Conditional Modification

    Implement hook_form_alter() for the form displayed in the exposed filter. To identify this form, you will first need to get the id for the views_exposed_form (not sure it's that) then get a more specific identify out of the forms array to target only this exposed form. (You'd need this for approach #2 anyway).

    Now that you have that, you can do a couple things. First, keep in mind that if you are aggressive about caching this block in a gobal way, this will break. Cache per page, or at whatever granularity you intent to change the block. For each filter you want to hide, you are going to put some logic into $form['#access'] so Drupal can look at the form element, look at the page it's on, and hide that form element because it's not in use.

    If you happened to be relying on the current page path, you might do something like this:

    $form['taxonomy_b_filter']['#access'] = arg(0) == 'section';
    

    This tells Drupal to hide the imaginary 'taxonomy_b_filter' element if the current page path looks like http://example.com/section.