How to theme the views exposed form?

I’ve created a view with a number of exposed filters, but it is pretty ugly looking.

enter image description here

I’d like to improve the theming, including wrapping the whole thing in a fieldset as well as grouping some of the other elements (like pairing the published and updated inputs), but not sure how to go about this.

I tried to var_dump the form, but it seems to go on forever and my browser locks up, so I can’t easily learn anything about the form that way.

I also tried putting the form as a fieldset child in another form, but getting all the form ID information and so on proved problematic (although, I did get the fieldset styling).

Anyone got any pointers?

Update:

I copied over the template from the module to my site’s theme directory, and made a start.

<fieldset>
    <legend>Filters</legend>

    <div class="views-exposed-form">
        <div class="views-exposed-widgets clear-block">
            <?php foreach($widgets as $id => $widget): ?>
                <div class="views-exposed-widget">
                    <?php if (!empty($widget->label)): ?>
                        <label for="<?php print $widget->id; ?>">
                            <?php print $widget->label; ?>
                        </label>
                    <?php endif; ?>
                    <?php if (!empty($widget->operator)): ?>
                        <div class="views-operator">
                            <?php print $widget->operator; ?>
                        </div>
                    <?php endif; ?>
                    <div class="views-widget">
                        <?php print $widget->widget; ?>
                    </div>
                </div>
            <?php endforeach; ?>
            <div class="views-exposed-widget">
                <?php print $button ?>
            </div>
        </div>
    </div>
</fieldset>

I can’t seem to figure out how to pair up the date fields – I need to somehow modify the widget properties so I can wrap them in HTML (using hook_form_alter doesn’t work because the #prefix and #suffix are added to $widget->widget so they break the output)

– Answer –

  • 19 April 2012: Answer by Игорь Марусик for How to theme the views exposed form? -

    You should look into what's in the form['#theme'] item. Better way to do this (better than var_dump()) would be using dsm($form) or even kpr($form), these functions will be availible after you install the devel module (http://drupal.org/project/devel). form['#theme'] should be an array of about 7 elements. These elements are names of theme hooks that are called when this form is being rendered. you can use them to implement you own way of themeing a form.

    One of the items will be called views_exposed_form__VIEW_NAME__DISPLAY_ID.

    In your module (if you have one) there should be an implementation of hook_theme()

    function MYMODULE_theme($existing, $type, $theme, $path) {
      return array(
        'views_exposed_form__VIEW_NAME__DISPLAY_ID' => array(
          'function' => 'my_exposed_form_theme_function',
          'render element' => 'form',
        )
      );
    }
    
    // somwhere later in code
    
    function my_exposed_form_theme_function($vaiables) {
      //$vaiables['form'] contains a form array
      //to display a form element call drupal_render($vaiables['form']['some element'])
      //don't forget to call drupal_render($form) 
      //after you are done with rendering individual elements
      //
      //you can use template_preprocess_views_exposed_form() from 
      // views/theme/theme.inc as an example
    
      return "concatenated results of multiple drupal_render() calls";
    }
    
  • 12 May 2011: Answer by mikeker for How to theme the views exposed form? -

    Also take a look at the Better Exposed Filters module. You'll need the -dev release to get the collapsible filters option, though I'm hoping to get a proper 1.1 release out soon...

  • 29 April 2011: Answer by Pierre Buyle for How to theme the views exposed form? -

    Theming Views' exposed form is (unecessary, IMHO) hard because it doesn't behave like most forms and use its own label mechanism. So, you can't simply use a form_alter hook to add #prefix and #suffix to elements. But using THEME_preprocess_views_exposed_form, you can craft your own suffix/prefix mechanism:

    function THEME_preprocess_views_exposed_form(&$variables) {
      if ($vars['form']['#id'] == 'views-exposed-form-VIEWNAME-DISPLAYID') {
        foreach ($variables['widgets'] as $id => &$widget) {
          switch ($id) {
            case 'first_date_id'
              $widget->prefix = '<div class="date-widgets-wrapper">';
              break;
            case 'last_date_id':
              $widget->suffix = '</div>';
              break;
          }
        }
      }
    }
    

    and in the themplate

    <fieldset>
        <legend>Filters</legend>
    
        <div class="views-exposed-form">
            <div class="views-exposed-widgets clear-block">
                <?php foreach($widgets as $id => $widget): ?>
                    <?php if (!empty($widget->prefix) print $widget->prefix; ?>
                    <div class="views-exposed-widget">
                        <?php if (!empty($widget->label)): ?>
                            <label for="<?php print $widget->id; ?>">
                                <?php print $widget->label; ?>
                            </label>
                        <?php endif; ?>
                        <?php if (!empty($widget->operator)): ?>
                            <div class="views-operator">
                                <?php print $widget->operator; ?>
                            </div>
                        <?php endif; ?>
                        <div class="views-widget">
                            <?php print $widget->widget; ?>
                        </div>
                    </div>
                    <?php if (!empty($widget->suffix) print $widget->suffix; ?>
                <?php endforeach; ?>
                <div class="views-exposed-widget">
                    <?php print $button ?>
                </div>
            </div>
        </div>
    </fieldset>
    
  • 29 April 2011: Answer by Teegan for How to theme the views exposed form? -

    In previous situations I have used Hook_form_alter() to add prefix and suffix to form elements to wrap them up in div which can then be styled. Not sure about wrapping in fieldsets though.

    eg.

    $form['submitted']['full_name']['#prefix'] = '<div class="background">';        
    $form['submitted']['message']['#suffix'] = '</div>';
    
  • 29 April 2011: Answer by Adam S for How to theme the views exposed form? -

    You can copy views-exposed-form.tpl.php from sites/all/modules/views/theme to your theme path to override the template.

  • 29 April 2011: How to theme the views exposed form? -

    I've created a view with a number of exposed filters, but it is pretty ugly looking.

    enter image description here

    I'd like to improve the theming, including wrapping the whole thing in a fieldset as well as grouping some of the other elements (like pairing the published and updated inputs), but not sure how to go about this.

    I tried to var_dump the form, but it seems to go on forever and my browser locks up, so I can't easily learn anything about the form that way.

    I also tried putting the form as a fieldset child in another form, but getting all the form ID information and so on proved problematic (although, I did get the fieldset styling).

    Anyone got any pointers?

    Update:

    I copied over the template from the module to my site's theme directory, and made a start.

    <fieldset>
        <legend>Filters</legend>
    
        <div class="views-exposed-form">
            <div class="views-exposed-widgets clear-block">
                <?php foreach($widgets as $id => $widget): ?>
                    <div class="views-exposed-widget">
                        <?php if (!empty($widget->label)): ?>
                            <label for="<?php print $widget->id; ?>">
                                <?php print $widget->label; ?>
                            </label>
                        <?php endif; ?>
                        <?php if (!empty($widget->operator)): ?>
                            <div class="views-operator">
                                <?php print $widget->operator; ?>
                            </div>
                        <?php endif; ?>
                        <div class="views-widget">
                            <?php print $widget->widget; ?>
                        </div>
                    </div>
                <?php endforeach; ?>
                <div class="views-exposed-widget">
                    <?php print $button ?>
                </div>
            </div>
        </div>
    </fieldset>
    

    I can't seem to figure out how to pair up the date fields - I need to somehow modify the widget properties so I can wrap them in HTML (using hook_form_alter doesn't work because the #prefix and #suffix are added to $widget->widget so they break the output)

Leave a Reply