You are here

function theme_select_as_tree in Better Exposed Filters 6.3

Same name and namespace in other branches
  1. 8.3 better_exposed_filters.theme \theme_select_as_tree()
  2. 6 better_exposed_filters.theme \theme_select_as_tree()
  3. 6.2 better_exposed_filters.theme \theme_select_as_tree()
  4. 7.3 better_exposed_filters.theme \theme_select_as_tree()
  5. 7 better_exposed_filters.theme \theme_select_as_tree()

Themes a taxonomy-based exposed filter select element as a nested unordered list. Note: this routine depends on the '-' char prefixed on the term names by Views to determine depth.

Parameters

$element:

Return value

HTML

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 225

Code

function theme_select_as_tree($element) {

  // The selected keys from #options
  $selected_options = (array) $element['#post'][$element['#name']];

  /*
   *  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)) {
      list($option_value, $option_label) = each(array_slice($option_label->option, 0, 1, TRUE));
    }

    // 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
      preg_match('/^(-*).*$/', $option_label, $matches);
      $depth = strlen($matches[1]);

      // Build either checkboxes or radio buttons, depending on Views' Force single option
      $html = '';
      if ($element['#multiple']) {
        $html = bef_checkbox($element, $option_value, ltrim($option_label, '-'), array_search($option_value, $selected_options) !== FALSE);
      }
      else {

        // Remove prefixed '-' characters
        $element[$option_value]['#title'] = ltrim($element[$option_value]['#title'], '-');
        $html = theme('radio', $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 {

        // Remain at same level as previous entry. No </li> needed if we're at the top level
        if (0 == $curr_depth) {
          $output .= "<li>{$html}";
        }
        else {
          $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
  $class = isset($element['#attributes']['class']) ? 'class="' . $element['#attributes']['class'] . '"' : '';
  $description = '';
  if (!empty($element['#description'])) {
    $description = '<div class="description">' . $element['#description'] . '</div>';
  }
  return "<div {$class}>{$description}{$output}</div>";
}