0

I'm using Views Selective Filters, trying to expose taxonomy terms filters with its depth/hierarchy.

Whenever I configure a filter with criterion Content, for instance Country (field_country) where field_country is a term, I have this extra setting window to choose the widget :

Views exposed form extra setting window for selection mode

Instead, with the same field, but selective filter option, that extra settings window doesn't appear.

The Exposed form style is provided by Better Exposed Filters, but I let the default style for that filter.

Is there a configuration step I'm missing ? A necessary module combination to achieve that ? Meanwhile, I updated to Views selective filters dev version, plus a patch providing taxonomy weight ordering for the filters. This is the relevant part, from views_handler_filter_selective.inc :

/**
 * Get list of options for current view, only at runtime.
 */
protected function get_oids() {
//...
// Sort values.
  $sort_option = $this->options['selective_display_sort'];
  switch($sort_option) {
    case 'WEIGHT':
      $terms = taxonomy_term_load_multiple(array_keys($oids));
      usort($terms, function($a, $b) {
        return $a->weight - $b->weight;
      });
      $oids_ordered_by_weight = array();
      foreach ($terms as $term) {
        $oids_ordered_by_weight["$term->tid"] = $oids[$term->tid];
      }
      $oids = $oids_ordered_by_weight;
      break;
  }

And I'm trying now to figure out how to overwrite that to show hierarchy instead.

1 Answer 1

1

I realised the BEF desired option "Nested checkboxes" was missing for all selective filters. Since into better_exposed_filters_exposed_form_plugin.inc, the missing option depends on :

if ($bef_nested) {
  $display_options['bef_ul'] = t('Nested Checkboxes/Radio Buttons');
}

So I added the following :

/* line 314 */
if ($filter instanceof views_handler_filter_selective) {
  $bef_nested = TRUE;
}
/* line 493 */
if ($bef_nested) {
  //...
  $bef_options[$label]['more_options']['bef_select_all_none_nested'] = array(
    '#disabled' => !$filter instanceof views_handler_filter_selective &&(!$filter->options['expose']['multiple'] || !$filter->options['hierarchy']),

I know this is a very quick hack and should be improved for general use. Alternate proposals are warmly welcome.

Last, I had to patch also Views selective filters handler, resulting in :

case 'HCHY':
  $options = array();
  //get remaining terms tids
  $remaining_terms = taxonomy_term_load_multiple(array_keys($oids));
  $tids = array();
  foreach ($remaining_terms as $term) {
    $tids[$term->tid] = $term->tid; 
  }
  //get vocabulary tree
  $anyterm = array_shift($remaining_terms); 
  $tree = taxonomy_get_tree($anyterm->vid);
  if ($tree) {
    //we flag the terms to avoid displaying them more than once
    $flagged = array();
    //we keep tree items if they match with current selection
    foreach ($tree as $trm) {
      if(in_array($trm->tid, $tids ) && !in_array($trm->tid, $flagged) ){
        //so we always keep its parents displayed
        $parents_all = taxonomy_get_parents_all($trm->tid);

        if($anyterm->vid == '3'){//country vocab, Three levels taxonomy
          switch (count($parents_all)) {
            case 3: 
              $parent = $parents_all[1];
              $gd_parent = $parents_all[2];
              break;
            case 2: 
              $gd_parent = $parents_all[1];
              break;
            default:
              break;
          }
          //Add the gd_parent to options
          if(!in_array($gd_parent->tid, $flagged) && !is_null($gd_parent->tid)){

            $gd_parent_depth = get_term_depth($gd_parent->tid)-1;
            $choice = new stdClass();
            $choice->option = array($gd_parent->tid => str_repeat('-', $gd_parent_depth) . $gd_parent->name);
            $options[] = $choice;
            $flagged[] = $gd_parent->tid;
          }   
          //Add the parent to options
          if(!in_array($parent->tid, $flagged) && !is_null($parent->tid)){

            $parent_depth = get_term_depth($parent->tid)-1;
            $choice2 = new stdClass();
            $choice2->option = array($parent->tid => str_repeat('-', $parent_depth) . $parent->name);
            $options[] = $choice2;
            $flagged[] = $parent->tid;
          }
        }

        //last, add the term itself to options
        $choice3 = new stdClass();
        $choice3->option = array($trm->tid => str_repeat('-', $trm->depth) . $trm->name);
        $options[] = $choice3;   
        $flagged[] = $trm->tid;
      }
    }
  }
  $oids = $options;

/*
 * Returns a term depth (https://www.drupal.org/node/886526#comment-7708315)
 */
function get_term_depth($tid) {
  $limit = 5;
  $depth = 0;
  while ($parent = db_select('taxonomy_term_hierarchy', 't') ->condition('tid', $tid, '=') ->fields('t') ->execute() ->fetchAssoc()) {
    $depth ++;
    $tid = $parent['parent'];
    if ($depth > $limit) {
      break;
    }
  }
  return $depth;
}

Both are necessary, usual nested checkboxes from BEF do not work as is. This might be useful for some of you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.