Posted by aristeides on November 10, 2011 at 8:36pm
3 followers
Jump to:
| Project: | Better Exposed Filters |
| Version: | 7.x-3.x-dev |
| Component: | Code |
| Category: | feature request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | active |
Issue Summary
The title might be a little confusing but couldn't think of anything else atm.
I've got a use case that needs views exposed filters (hierarchical taxonomy terms) structured like the "Nested Checkboxes/Radio Buttons" but with a twist:
Instead of checkboxes or radio buttons I need links.
Sort of like a "Nested Links" display. (hence the title of this issue)
We've got "Nested Checkboxes/Radio Buttons", we've got "Links", why not combine them into "Nested Links" ? From what I understand it wouldn't be too hard to implement and theming-wise it would make some things a lot easier!
over-simplified, having an output like
<ul>
<li><a href=#>term 1</a></li>
<li><a href=#>term 2</a>
<ul>
<li><a href=#>sub-term</a></li>
</li>
</li>
<li><a href=#>term 3</a></li>
</ul>would mean easier to theme hierarchical exposed filters, plus the ability to use a few js tricks to make this prettier and more functional.
Comments
#1
I was in the same situation. To save a bit of time, I copied the theme function code in better_exposed_filters.theme function theme_select_as_tree for counting depth
<?phppreg_match('/^(-*).*$/', $option_label, $matches);
$depth = strlen($matches[1]);
?>
And then wrapped a div tag around the link with a depth class
<?php$link = '<div class="depth-'.$depth.'">'.l($value, bef_replace_query_string_arg($name, $key, $multiple));.'</div>';
?>
and then I can style the different depth levels that I need. Not a great solution, but it works.
Here's the whole thing to go into your template.php file:
<?php
function YOURTHEME_select_as_links($vars) {
$element = $vars['element'];
$output = '';
$name = $element['#name'];
// Collect selected values so we can properly style the links later
$selected_options = array();
if (empty($element['#value'])) {
if (!empty($element['#default_values'])) {
$selected_options[] = $element['#default_values'];
}
}
else {
$selected_options[] = $element['#value'];
}
// Add to the selected options specified by Views whatever options are in the
// URL query string, but only for this filter
$urllist = parse_url(request_uri());
if (isset($urllist['query'])) {
$query = array();
parse_str(urldecode($urllist['query']), $query);
foreach ($query as $key => $value) {
if ($key != $name) {
continue;
}
if (is_array($value)) {
// This filter allows multiple selections, so put each one on the selected_options array
foreach ($value as $option) {
$selected_options[] = $option;
}
}
else {
$selected_options[] = $value;
}
}
}
$curr_depth = 0;
$element['#options']['All'] = t('View All');
// Go through each filter option and build the appropriate link or plain text
foreach ($element['#options'] as $option => $elem) {
// Check for Taxonomy-based filters
if (is_object($elem)) {
list($option, $elem) = each(array_slice($elem->option, 0, 1, TRUE));
}
/*
* Check for optgroups. Put subelements in the $element_set array and add a group heading.
* Otherwise, just add the element to the set
*/
$element_set = array();
if (is_array($elem)) {
$element_set = $elem;
}
else {
$element_set[$option] = $elem;
}
$links = array();
$multiple = !empty($element['#multiple']);
$html = '';
foreach ($element_set as $key => $value) {
//dpm($value);
preg_match('/^(-*).*$/', $value, $matches);
$depth = strlen($matches[1]);
//dpm($depth);
// Custom ID for each link based on the <select>'s original ID
$id = drupal_html_id($element['#id'] . '-' . $key);
if (array_search($key, $selected_options) === FALSE) {
$link = l(ltrim($value, '-'), bef_replace_query_string_arg($name, $key, $multiple));
$html = '<div class="depth-'.$depth.'">'.$link.'</div>';
$output .= theme('form_element', array('element' => array( '#id' => $id, '#children' => $html, '#markup' => '',
'#name' => 'depth-'.$depth,)));
} else {
// Selected value is output without a link
// TODO: add link to remove this option from the filter?
$elem = array(
'#id' => $id,
'#children' => $value,
'#markup' => '',
'#name' => 'depth-'.$depth,
);
_form_set_class($elem, array('bef-select-as-links-selected'));
$output .= theme('form_element', array('element' => $elem));
}
} // end foreach
} // end foreach
$properties = array(
'#description' => isset($element['#description']) ? $element['#description'] : '',
'#children' => $output,
'#name' => 'test-list',
);
return '<div class="bef-select-as-links">'
. theme('form_element', array('element' => $properties))
. '</div>';
}
?>
Daniel
#2
Wow, thank a lot! that actually works!!