I have just done this as well and based my solution on @vrwired's solution
(Drupal 8 Dynamic Dependent Dropdown Views Exposed Filters)
My view is a view of content teaser with 3 referenced vocabs on the content type.
Firstly I duplicated the entire view and called it the same as the first on with "Count" on the end and changed it to have no limit to the number of results returned and also to just return fields and only the title field.
This was because without it I wasn't getting the full list of terms I could filter by
All the things in CAPS are as descriptive as I could make them in 5 mins, you'll need to change them as required for your solution
<?php
/**
* Implements hook_views_exposed_form_alter().
*
* Alters exposed filter for equipment selector to limit filtered results in a
* new view
*/
function MYMODULE_form_views_exposed_form_alter(&$form, &$form_state) {
if ($form['#id'] == 'views-exposed-form-VIEWID-page-1') {
// Get whatever values selected by user in all menus
$input = &$form_state->getUserInput();
$args = [];
foreach ($input as $arg) {
if (!empty($arg)) {
$args[] = $arg;
}
}
$filters = ['FILTER_1', 'FILTER_2', 'FILTER_2'];
foreach ($filters as $filter) {
$form[$filter]['#options'] = MYMODULE_get_associative_array_from_view(
'VIEWID_count', // viewi id
'page_1', // view dsplay id
$args, $filter
);
}
}
}
/**
* Filters out the unavailable options from the drop downs
*/
function MYMODULE_get_associative_array_from_view($view_id, $display_id, $args, $menu_chosen) {
$options_array = array();
$options_array['All'] = t('- Any -');
$result = MYMODULE_get_view_result($view_id, $display_id, $args);
foreach ($result as $row) {
switch ($menu_chosen) {
// views_get_view_result returns rows with original field name so don't
// use filter identifier name to acceess, use field name
case 'FILTER_1':
$field = $row->_entity->get('FIELD_1')->getValue();
break;
case 'FILTER_2':
$field = $row->_entity->get('FIELD_2')->getValue();
break;
case 'FILTER_2':
$field = $row->_entity->get('FIELD_3')->getValue();
break;
default:
break;
}
$target_id = $field[0]['target_id'];
$term = MYMODULE_get_referenced_term($target_id);
if (!empty($term)) {
$term_name = $term->getName();
$term_id = $term->id();
if (!in_array($term_name, $options_array)) {
$options_array[$term_id] = $term_name;
}
}
}
asort($options_array);
return $options_array;
}
/**
* Returns a term if in scope
*
* @param int $tid
*
* @return object
*/
function MYMODULE_get_referenced_term($tid = 0) {
if (empty($tid)) {
return;
}
$term = taxonomy_term_load($tid);
if (empty($term)) {
return;
}
return $term;
}
/**
* Get the view result filtered by the arguments passed
*
* @param string $viewname
* @param string $display
* @param array $args
*
* @return boolean|array
*/
function MYMODULE_get_view_result($viewname, $display, $args) {
// Get the view
$view = \Drupal\views\Views::getView($viewname);
if (!$view) {
// The view could not be loaded. Add a watchdog message and leave the function
\Drupal::logger('MYMODULE')->error('View @view not found', array('@view' => $viewname));
return false;
}
// set the display machine name
$view->setDisplay($display);
// Set arguments for exposed filters
// Note that you always need to use an array.
// The arguments are passed in the order as they appear on the view
$view->setArguments($args);
// Execute the view
// This function does not do any access checks on the view. It is the
// responsibility of the caller to check $view->access()
$view->preview();
if (!empty($view->result)) {
return $view->result;
}
}