Change views exposed filter value only on page reload Is there a clean way to alter a View exposed filter field, but only on page reload and not each time you submit the exposed filters form ?



Example

I have a View with exposed filters. When a user is loading this View, I want to change the value of an exposed filter field, depending on a cookie value.

I've managed to make it work with the hook_form_views_exposed_form_alter function.

function HOOK_form_views_exposed_form_alter(&amp;$form, FormStateInterface $form_state, $form_id) {
    if ($form['#id'] == 'views-exposed-form-MY-VIEW') {
        $cookies = \Drupal::request()-&gt;cookies-&gt;all();
        if (isset($cookies['MY_COOKIE'])) {
            $form['MY_FIELD']['#value'] = $cookies['MY_COOKIE'];
        }
    }
}


Problem is : if the user manually change the exposed filter and submit the form, the value is getting back to the first one because the hook_form_alter is getting called again.

Here is a video : https://imgur.com/EmVha6e



Poor solution

I've found a solution, but it doesn't looks like a good one. I've found out that when the hook_form_alter is getting called by a submit, there is a new entry ('a' =&gt; '') in the UserInput array that you can find by calling $form_state-&gt;getUserInput().

First load :

[
    'MY_FIELD' =&gt; 'All',
    '...' =&gt; '...'
]


After submit :

[
    'MY_FIELD' =&gt; 'New value',
    'a' =&gt; '',
    '...' =&gt; '...'
]


So now I can use the following to change the field value only on the page load :

if (isset($cookies['MY_COOKIE']) &amp;&amp; !array_key_exists('a', $form_state-&gt;getUserInput())) {
    $form['MY_FIELD']['#value'] = $cookies['MY_COOKIE'];
}


But I'm not even sure it is fully functional, is there a better way to do it ?



Clean solution

Thank's to @NoSssweat, here's a cleaner solution :

function MODULE_views_pre_build(ViewExecutable $view) {
    $request = \Drupal::request();
    $is_ajax = $request-&gt;isXmlHttpRequest();
    if (!$is_ajax) {
        $cookies = \Drupal::request()-&gt;cookies-&gt;all();
        if (isset($cookies['MY_COOKIE'])) {
            $view-&gt;setExposedInput(['MY_FIELD' =&gt; [$cookies['MY_COOKIE'] =&gt; $cookies['MY_COOKIE']]]);
        }
    }
}
Just added a video link to show you : imgur.com/EmVha6e


You just need to add a conditional to check if it's not ajax

   $request = \Drupal::request();
   $is_ajax = $request-&gt;isXmlHttpRequest();
   if (!$is_ajax) {
     // code that sets the filter initial value
   }


Credit: How can I detect AJAX request inside Drupal?