When I have an exposed views filter that contains just an HS selector, things work fine, but if I add another exposed filter (like keyword for search), the display of the rendered filters gets hosed due to the way views.js alters the HTML. (See attached images)

If you'd like me to take some time to look into this, let me know, but I'm wondering if you may know off the top of your head a quick solution.

Comments

jrbeeman’s picture

Title: views.js alters exposed filters HTML in a way that breaks multiple item filters » views.js alters exposed filters HTML in a way that breaks display of multiple item filters
wim leers’s picture

Yes, that JS needs work.

It moves HS exposed filters to separate rows, because a HS needs a row of its own. If it doesn't have a row of its own, it'll start moving around the exposed filters "after" it (i.e. to the right of it). Which is *very* annoying.

The only solution is to make the JS better. No other solution is possible, because Views' exposed filters form has a hardcoded rendering to a table, so I can't just add a custom #theme callback for rendering that form.

It'd be great if you could improve that JS! :)

jrbeeman’s picture

StatusFileSize
new1.54 KB
new220.34 KB
new256.22 KB

I wonder if the issues you were attempting to solve with the bulk of views.js were fixed by other stuff you've done in the meantime...? I just removed the code that alters the DOM, and things seems to still work correctly. The altered code works in both Garland and a custom, zen-based theme that has implemented theme_views_filters() to alter the filter HTML.

wim leers’s picture

Your "Picture 2.png" file is still problematic. Try using HS to go to a next level and everything will jump around!

jrbeeman’s picture

StatusFileSize
new225.14 KB
new221.04 KB

So is the issue that the select boxes end up tiling down beneath each other? If so, it's not really that the HS widget breaks the HTML, it's that the default Views filters theme tiles the filters across table cells, simply not leaving enough room for the HS widget on each exposed filter. Am I understanding it correctly? The attached screens show a custom theme and Garland successfully rendering the widget with selections. In Garland, the select boxes are just all scrunched together.

The code below is what I used to alter the Views filters theme output in my custom theme. It renders the filters as a table still, but by making the header (label) for each exposed filter be in the left-hand column as opposed to the top row. This leaves much more room for the HS widget (and is a better default, in my opinion). It sounds like you can't override this in the HS module, though, right?

function zen_views_filters($form) {
  $view = $form['view']['#value'];
  $rows = array();
  $form['submit']['#value'] = t('Search');
  if (isset($view->exposed_filter)) {
    foreach ($view->exposed_filter as $count => $expose) {
      $rows[] = array(
        array('data' => $expose['label'], 'header' => TRUE),
        drupal_render($form["op$count"]) . drupal_render($form["filter$count"]),
      );
    }
  }
  $rows[] = array(
    array('data' => '', 'header' => TRUE),
    drupal_render($form['submit'])
  );
  // make the 'q' come first
  if (count($rows) > 1) {
    $output = drupal_render($form['q']) . theme('table', array(), $rows) . drupal_render($form);
  }
  else {
    $output = drupal_render($form);
  }
  return $output;
}
wim leers’s picture

Status: Active » Postponed (maintainer needs more info)

So is the issue that the select boxes end up tiling down beneath each other? If so, it's not really that the HS widget breaks the HTML, it's that the default Views filters theme tiles the filters across table cells, simply not leaving enough room for the HS widget on each exposed filter. Am I understanding it correctly? The attached screens show a custom theme and Garland successfully rendering the widget with selections. In Garland, the select boxes are just all scrunched together.

That's right. But sometimes, when there's enough room, say you ONLY have a HS exposed filter and the submit button, things jump around to the HS.
I don't have to fix this, but it's nice to support it for my users. I'm very inclined to stop doing that right now though.

The code below is what I used to alter the Views filters theme output in my custom theme. It renders the filters as a table still, but by making the header (label) for each exposed filter be in the left-hand column as opposed to the top row. This leaves much more room for the HS widget (and is a better default, in my opinion). It sounds like you can't override this in the HS module, though, right?

I think that's right, yes. I believe you can do this in Drupal 6 thanks to hook_theme().

I think the only conclusion can be that this CANNOT be solved automagically through some JS hackery. It generates as much problems as it resolves… So unless you oppose, I'm going to throw this out completely. I'll refer to this issue instead.

wim leers’s picture

Jeff, any feedback? :)

jrbeeman’s picture

Sorry for the delay - been buried in a project. When you say, "I'm going to throw this out completely" do you mean you're just going to take out that JS that alters the table? If so, I'm all for it. I'd be happy to provide a patch for the docs that show how to alter your views filters theme output to play more nicely with HS.

wim leers’s picture

Status: Postponed (maintainer needs more info) » Needs work

The delay's not a problem ;) :)

I just committed your patch with some documentation improvements of my own thrown in. Setting to CNW because I'm welcoming your offered patch with wide open arms ;) :)

Thanks Jeff!

wim leers’s picture

There are several people waiting for that documentation, Jeff :) I don't mean to add extra pressure, but do know that your work won't be in vain!

jrbeeman’s picture

StatusFileSize
new1.96 KB

I've attached a patch to the README with some instructions on overriding theme_views_filters().

jrbeeman’s picture

Status: Needs work » Needs review
wim leers’s picture

Title: views.js alters exposed filters HTML in a way that breaks display of multiple item filters » Document how to theme views exposed filters to play nicely with HS

Excellent, thanks! Committed :)

wim leers’s picture

Status: Needs review » Fixed

Oops, forgot status.

Anonymous’s picture

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for two weeks with no activity.

codenamerhubarb’s picture

Category: support » bug

Thanks Wim Leers and jrbeeman... but I'm having trouble implementing jrbeeman's code. I already have the following code in my template.php file (this is pretty much the standard code from the Views Theme Wizard)...

// Theme the filters area on '/ebooks' pages ( see http://drupal.org/node/79302 )
function phptemplate_views_filters($form) { //this call overrides all views filters so I need a condition
  $view = $form['view']['#value'];

  if ($view->name == 'ebookslistrating' or $view->name == 'ebookslistprice' or $view->name == 'ebookslisttitle' or $view->name == 'ebookslistdate' or $view->name == 'ebookslisthits' or $view->name == 'ebookslistcomments'){ //so I used the view's name/s.
    foreach ($view->exposed_filter as $count => $expose) {
      $row[] = drupal_render($form["op$count"]) ;
      $box[] = drupal_render($form["filter$count"]);
      $label[] = $expose['label'];
	  //$fivestarform = array('#type' => 'fivestar', '#stars' => 5,);
    }
    $row[] = drupal_render($form['submit']);
    $label[] = ''; // so the column count is the same.
    $title = $view->page_title;
 
    return _phptemplate_callback('views-filters-ebooks', array('title' => $title, 'row' => $row, 'box' => $box, 'label'=>$label));
    // I use a callback to a tpl called views-filters-ebooks.tpl.php
  }
  else{ // in the case it isn't 'ebookslistrating', 'ebookslistprice' etc. it goes through the normal flow as defined in views.module
    foreach ($view->exposed_filter as $count => $expose) {
      $row[] = drupal_render($form["op$count"]) . drupal_render($form["filter$count"]);
      $label[] = $expose['label'];
    }
    $row[] = drupal_render($form['submit']);
    $label[] = ''; // so the column count is the same.

    // make the 'q' come first
    return drupal_render($form['q']) . theme('table', $label, array($row)) . drupal_render($form);
  }
}

...This code works very nicely in that I can chose exactly how I'd like the exposed filters to look by adjusting views-filters-ebooks.tpl.php

However, I still get the following errors on the page with my exposed filters and the HS form doesn't work properly:

    * warning: Missing argument 1 for drupal_retrieve_form() in /home/myusername/public_html/includes/form.inc on line 179.
    * warning: call_user_func_array() [function.call-user-func-array]: First argument is expected to be a valid callback, '' was given in /home/myusername/public_html/includes/form.inc on line 218.
    * warning: uasort() [function.uasort]: The argument should be an array in /home/myusername/public_html/includes/common.inc on line 2146.

Is there a way to implement jrbeeman's fix but still be able to customize the appearance of the exposed filters via a *.tpl.php?

wim leers’s picture

Status: Closed (fixed) » Needs review

jrbeeman, could you maybe answer this one? Thanks!

wim leers’s picture

Category: bug » support
wim leers’s picture

Category: bug » support
Status: Needs review » Postponed (maintainer needs more info)

I think the cause might be that you're not rendering the root level of the form. Try changing your code to:

// Theme the filters area on '/ebooks' pages ( see <a href="http://drupal.org/node/79302" title="http://drupal.org/node/79302" rel="nofollow">http://drupal.org/node/79302</a> )
function phptemplate_views_filters($form) { //this call overrides all views filters so I need a condition
  $view = $form['view']['#value'];

  if ($view->name == 'ebookslistrating' or $view->name == 'ebookslistprice' or $view->name == 'ebookslisttitle' or $view->name == 'ebookslistdate' or $view->name == 'ebookslisthits' or $view->name == 'ebookslistcomments'){ //so I used the view's name/s.
    foreach ($view->exposed_filter as $count => $expose) {
      $row[] = drupal_render($form["op$count"]) ;
      $box[] = drupal_render($form["filter$count"]);
      $label[] = $expose['label'];
      //$fivestarform = array('#type' => 'fivestar', '#stars' => 5,);
    }
    $row[] = drupal_render($form['submit']);
    $label[] = ''; // so the column count is the same.
    $title = $view->page_title;

    return _phptemplate_callback('views-filters-ebooks', array('title' => $title, 'row' => $row, 'box' => $box, 'label'=>$label));
    // I use a callback to a tpl called views-filters-ebooks.tpl.php
  }
  else{ // in the case it isn't 'ebookslistrating', 'ebookslistprice' etc. it goes through the normal flow as defined in views.module
    foreach ($view->exposed_filter as $count => $expose) {
      $row[] = drupal_render($form["op$count"]) . drupal_render($form["filter$count"]);
      $label[] = $expose['label'];
    }
    $row[] = drupal_render($form['submit']);
    $label[] = ''; // so the column count is the same.

    // make the 'q' come first
    $output = drupal_render($form['q']) . theme('table', $label, array($row)) . drupal_render($form);

    // Make sure the entire form is rendered, including the root level.
    drupal_render($form)

    return $form
  }
}
codenamerhubarb’s picture

Thanks Wim, I appreciate your effort in responding. I've made the change and I'll let you know if I experience the error again.

P.S. You were missing a couple of semi-colons on the last two lines.

wim leers’s picture

Status: Postponed (maintainer needs more info) » Closed (fixed)

Looks like this is fixed then. :)