3

I have an exposed filter for tags on my view. I want this filter to only show show used tags. I found some drupal 7 options like this one and the Views Selective Filter but can't seem to find a good drupal 8 option.

Can anyone help me out with a solution for this?

  • in the same way that is made in the article you can alter the form and just show the terms that you need. – Adrian Cid Almaguer Nov 9 '17 at 13:26
2

In Drupal 8, I was able to display only tags with results with the following code. Note that I'm using Better Exposed Filters contrib module, and display my filter as a Select.

function mymodule_form_views_exposed_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form['#id'] == 'views-exposed-form-your-view-name-page') {

    if (array_key_exists('field_activities_target_id', $form)) {
      // Rewrite the default 'All' option
      if (!empty($form['field_activities_target_id']['#options']['All'])) {
        $option_default = ['All' => t('Choose a category')];
      }

      $options = $form['field_activities_target_id']['#options'];

      $connection = Database::getConnection();
      $query = $connection->select('node__field_activities', 'activities');
      $query->join('node_field_data', 'n', 'n.nid = activities.entity_id');
      $query->fields('activities', ['field_activities_target_id']);
      $query->fields('n', ['status']);
      $query->condition('activities.bundle', 'your_node_type_name');
      $query->condition('n.status', 1);
      $data = $query->distinct()->execute();

      $results = array_flip($data->fetchAll(\PDO::FETCH_COLUMN, 'field_activities_target_id'));
      $options = array_intersect_key($options, $results);

      // Rebuild the option select
      $form['field_activities_target_id']['#options'] = $option_default + $options;
    }
  }
}

This article was a great help : https://johndevman.com/only-show-options-in-a-views-exposed-filter-that-belong-to-result-set/

| improve this answer | |
1

As Adrian said it was possible to change the code in the article a bit to make it suitable for Drupal 8. Here is my solution:

function MODULENAME_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  //id of the form you want to alter
  $formId = 'views-exposed-form-agenda-page-1';
  //field tags
  $select_field = 'field_tags_target_id';

  /**
   * Apply the form_alter to a specific form #id
   * the form #id can be found through inspecting the markup
   */
  if ($form['#id'] == $formId) {
    $available_terms = _get_available_terms();
    if (isset($available_terms)) { // Unset the existing list and add new one with available terms.
      unset($form[$select_field]['#options']);

      if ($form[$select_field]['#options']['All']) {
        $form[$select_field]['#options']['All'] = '- Any Term -';
      }

      foreach ($available_terms as $available_term) {
        $tid = $available_term[0];
        $name = $available_term[1];
        $form[$select_field]['#options'][$tid] = $name;
      }
    }
    else { // Unset all options except '- Any -'
      unset($form[$select_field]['#options']);
      $form[$select_field]['#options']['All'] = '- Any Term -';
    }
  }
}

function _get_available_terms() {
  //table name of tags field
  $node_tags_table = 'node__field_tags';

  $db = \Drupal::database();
  $query = $db->select($node_tags_table, 'nft');
  $query->distinct();
  $query->join('taxonomy_term_field_data', 'tname', 'tname.tid = nft.field_tags_target_id');
  $query->fields('nft', ['field_tags_target_id']);
  $query->fields('tname', ['name']);
  $result = $query->execute();

  $term_list = [];
  while ($row = $result->fetchAssoc()) {
    array_push($term_list, [$row['field_tags_target_id'], $row['name']]);
  }

  return $term_list;
}
| improve this answer | |
1

Here is the D8 module I am using to accomplish this function: https://www.drupal.org/project/selective_better_exposed_filters

It depends on better_exposed_filters. https://www.drupal.org/project/better_exposed_filters

It's still in beta, so test locally in your environment first, but it worked well in my testing. It won't create the (selective) filter options when you add filter criteria like you are used to in the old D7 module, but it accomplishes the same function:

Once you have an exposed filter in filter criteria, go to "exposed form style" under advanced then switch to better exposed filters (selective). Click apply

enter image description here

And then to enable it, check the box "show only used terms" down towards the bottom. Click apply.

enter image description here

Edit: If you have multiple exposed filters, you can set them each individually under each "more options for..." or you can set all of them globally at the very bottom of the settings options.

Pretty simple for those of us who aren't comfortable writing our own modules.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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