function theme_select_as_tree in Better Exposed Filters 7.3
Same name and namespace in other branches
- 8.3 better_exposed_filters.theme \theme_select_as_tree()
- 6.3 better_exposed_filters.theme \theme_select_as_tree()
- 6 better_exposed_filters.theme \theme_select_as_tree()
- 6.2 better_exposed_filters.theme \theme_select_as_tree()
- 7 better_exposed_filters.theme \theme_select_as_tree()
Themes a taxonomy-based exposed filter as a nested unordered list.
Note: this routine depends on the '-' char prefixed on the term names by Views to determine depth.
Parameters
array $vars: An array of arrays, the 'element' item holds the properties of the element.
Return value
string Nested, unordered list of filter options
1 string reference to 'theme_select_as_tree'
- better_exposed_filters_theme in ./
better_exposed_filters.module - Implements hook_theme().
2 theme calls to theme_select_as_tree()
- theme_select_as_checkboxes in ./
better_exposed_filters.theme - Themes a select element as a set of checkboxes.
- theme_select_as_radios in ./
better_exposed_filters.theme - Themes a select drop-down as a collection of radio buttons.
File
- ./
better_exposed_filters.theme, line 321 - Provides theming functions to display exposed forms using different interfaces.
Code
function theme_select_as_tree($vars) {
$element = $vars['element'];
// The selected keys from #options.
$selected_options = empty($element['#value']) ? $element['#default_value'] : $element['#value'];
// Build a bunch of nested unordered lists to represent the hierarchy based
// on the '-' prefix added by Views or optgroup structure.
$output = '<ul class="bef-tree">';
$curr_depth = 0;
foreach ($element['#options'] as $option_value => $option_label) {
// Check for Taxonomy-based filters.
if (is_object($option_label)) {
$slice = array_slice($option_label->option, 0, 1, TRUE);
$option_value = key($slice);
$option_label = current($slice);
}
// Check for optgroups -- which is basically a two-level deep tree.
if (is_array($option_label)) {
// TODO:
}
else {
// Build hierarchy based on prefixed '-' on the element label.
if (t('- Any -') == $option_label) {
$depth = 0;
}
else {
preg_match('/^(-*).*$/', $option_label, $matches);
$depth = strlen($matches[1]);
$option_label = ltrim($option_label, '-');
}
// Build either checkboxes or radio buttons, depending on Views' settings.
$html = '';
if (!empty($element['#multiple'])) {
if (isset($element['#bef_term_descriptions'][$option_value])) {
$element[$option_value]['#description'] = $element['#bef_term_descriptions'][$option_value];
}
$html = theme('bef_checkbox', array(
'element' => $element,
'value' => $option_value,
'label' => $option_label,
'selected' => array_search($option_value, $selected_options) !== FALSE,
));
}
else {
if (isset($element['#bef_term_descriptions'][$option_value])) {
$element[$option_value]['#description'] = $element['#bef_term_descriptions'][$option_value];
}
$element[$option_value]['#title'] = $option_label;
$element[$option_value]['#children'] = theme('radio', array(
'element' => $element[$option_value],
));
$html .= theme('form_element', array(
'element' => $element[$option_value],
));
}
if ($depth > $curr_depth) {
// We've moved down a level: create a new nested <ul>.
// TODO: Is there is a way to jump more than one level deeper at a time?
// I don't think so...
$output .= "<ul class='bef-tree-child bef-tree-depth-{$depth}'><li>{$html}";
$curr_depth = $depth;
}
elseif ($depth < $curr_depth) {
// We've moved up a level: finish previous <ul> and <li> tags, once for
// each level, since we can jump multiple levels up at a time.
while ($depth < $curr_depth) {
$output .= '</li></ul>';
$curr_depth--;
}
$output .= "</li><li>{$html}";
}
else {
if (-1 == $curr_depth) {
// No </li> needed -- this is the first element.
$output .= "<li>{$html}";
$curr_depth = 0;
}
else {
// Remain at same level as previous entry.
$output .= "</li><li>{$html}";
}
}
}
}
// foreach ($element['#options'] as $option_value => $option_label)
if (!$curr_depth) {
// Close last <li> tag.
$output .= '</li>';
}
else {
// Finish closing <ul> and <li> tags.
while ($curr_depth) {
$curr_depth--;
$output .= '</li></ul></li>';
}
}
// Close the opening <ul class="bef-tree"> tag.
$output .= '</ul>';
// Add exposed filter description.
$description = '';
if (!empty($element['#bef_description'])) {
$description = '<div class="description">' . $element['#bef_description'] . '</div>';
}
// Add the select all/none option, if needed.
if (!empty($element['#bef_select_all_none'])) {
if (empty($element['#attributes']['class'])) {
$element['#attributes']['class'] = array();
}
$element['#attributes']['class'][] = 'bef-select-all-none';
}
// Add the select all/none nested option, if needed.
if (!empty($element['#bef_select_all_none_nested'])) {
if (empty($element['#attributes']['class'])) {
$element['#attributes']['class'] = array();
}
$element['#attributes']['class'][] = 'bef-select-all-none-nested';
}
// Name and multiple attributes are not valid for <div>'s.
if (isset($element['#attributes']['name'])) {
unset($element['#attributes']['name']);
}
if (isset($element['#attributes']['multiple'])) {
unset($element['#attributes']['multiple']);
}
return '<div' . drupal_attributes($element['#attributes']) . ">{$description}{$output}</div>";
}