0

I have 2 exposed filters in my Drupal 8 view - both are select dropdowns. I want the value of the 2nd filter to change based on selection of first filter Here are the filters $filters = $view->display_handler->getOption('filters');

$filters['country'] and $filters['states'].

Problem is that I always get an empty value when I try to access country filter in my views_pre_view hook.

dpm($filters['country']['value']) always prints empty.

How do I solve this please?

2 Answers 2

0

You don't have access to your filter options inside hook_views_pre_view.

$filters = $view->display_handler->getOption('filters');

give only informations about the filter something like:

 "field_country_target_id" => array:20 [▼
    "id" => "field_country_target_id"
    "table" => "node__field_country"
    "field" => "field_country_target_id"
    "relationship" => "none"
    "group_type" => "group"
    "admin_label" => ""
    "operator" => "or"
    "value" => []
    "group" => 1
    "exposed" => true
    "expose" => array:13 [▶]
    "is_grouped" => false
    "group_info" => array:10 [▶]
    "reduce_duplicates" => false
    "type" => "select"
    "limit" => true
    "vid" => "countries"
    "hierarchy" => false
    "error_message" => true
    "plugin_id" => "taxonomy_index_tid"
  ]

To get the selected filter values with:

$filters_selected = $view->getExposedInput(); 

Even you get the filter options you can't alter it because exposed filters are form inputs.
So i thing the best way to achieve this is by using hook_form_FORM_ID_alter like the following.

/**
 * Implements hook_form_FORM_ID_alter().
 */
function MY_MODUOLE_form_views_exposed_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  // Here is options of your country filter
  // Note that they key is FIELD_NAME_target_id
  // Change the FIELD_NAME with you field name
  $countries = $form['field_country_target_id']['#options'];
  // Get the city options the same way .
  /**
   * TODO: To alter options array change $form['field_country_target_id']['#options'] not the $countries
   */
}
9
  • Thanks berramou, but how does this help me get the currently value of the countries drop-down filter? I need the value of that filter not just all the options. It's the value of countries filter that will determine values I populate states filter with..
    – ilechcod
    Apr 1, 2020 at 13:39
  • Also $form['field_country_target_id']['#options'] doesn't work. What works for me is $form['country'] ['#options'] and that returns the list of all countries rather than the selected option.
    – ilechcod
    Apr 1, 2020 at 13:41
  • check my edit to get selected values try with $view->getExposedInput()
    – berramou
    Apr 1, 2020 at 13:43
  • i just gave you an example with my field and i add the comment Change the FIELD_NAME with you field name to change it with your field name
    – berramou
    Apr 1, 2020 at 13:45
  • Thanks again berramou for quick reply. I tried the $view->getExposedInput() but got the following output from dpm
    – ilechcod
    Apr 1, 2020 at 14:00
0

To programatically change an exposed filter value in Drupal 9 based on another exposed filter, you can use the following steps:

Implement the hook_form_alter() function in a custom module. This function allows you to alter the form elements of a Drupal form.

In the hook_form_alter() function, find the two exposed filters in the form using their element IDs. You can use the dpm() or kint() functions from the Devel module to inspect the form elements and find their IDs.

Add an AJAX callback to the first exposed filter using the #ajax property. This callback will be triggered when the first filter's value is changed.

In the AJAX callback function, use the Drupal.ajax() function to send a request to the server and retrieve the filtered results. You can use the Drupal Views module's built-in AJAX callbacks to retrieve the filtered results.

Once you have retrieved the filtered results, use the Drupal.views.instances[] object to find the view's exposed form and update the value of the second exposed filter using jQuery.

Here is some example code to get you started:

use Drupal\Core\Form\FormStateInterface;

function MYMODULE_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'views_exposed_form' && $form['#id'] == 'MY_VIEW_ID') {
    // Find the two exposed filters in the form.
    $first_filter = &$form['MY_FIRST_FILTER'];
    $second_filter = &$form['MY_SECOND_FILTER'];

    // Add an AJAX callback to the first exposed filter.
    $first_filter['#ajax'] = [
      'callback' => 'MY_AJAX_CALLBACK',
      'wrapper' => 'MY_VIEW_WRAPPER',
      'event' => 'change',
    ];
  }
}

function MY_AJAX_CALLBACK($form, FormStateInterface $form_state) {
  // Retrieve the filtered results using Views AJAX callbacks.
  $view = views_get_view('MY_VIEW_ID');
  $view->setExposedInput($form_state->getValues());
  $view->preExecute();
  $view->execute();
  $result = $view->render();

  // Update the value of the second exposed filter using jQuery.
  $settings = [
    'MY_SECOND_FILTER' => $result['MY_SECOND_FILTER']['#options'],
  ];
  $commands[] = [
    'command' => 'MY_UPDATE_SECOND_FILTER',
    'settings' => $settings,
  ];
  return [
    '#type' => 'ajax',
    '#commands' => $commands,
  ];
}

In the above code, replace MY_VIEW_ID, MY_FIRST_FILTER, and MY_SECOND_FILTER with the appropriate IDs for your view and exposed filters. You will also need to define the MY_UPDATE_SECOND_FILTER JavaScript function to update the value of the second exposed filter using jQuery.

With this code, when the user changes the value of the first exposed filter, an AJAX request will be sent to the server to retrieve the filtered results. The value of the second exposed filter will then be updated based on the filtered results.

0

Your Answer

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

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