Problem/Motivation

When using viewsreference field (https://www.drupal.org/project/viewsreference) with some facets I noticed some weird things while using the contextual filter option in this field when ajax was turned on.

In the SearchApiDisplay you can see that the following code is executed:

    $display_definition = $this->getDisplay()->getPluginDefinition();
    if ($results === NULL && isset($display_definition['view_id'])) {
      $view = Views::getView($display_definition['view_id']);
      $view->setDisplay($display_definition['view_display']);
      $view->execute();
      $results = $this->searchApiQueryHelper->getResults($search_id);
    }

What is missing here is the preExecute() which also calls on the views_pre_view hook. Which means that when facets rebuilds itself through ajax, not all the views hooks are called which could have an impact on the given results. Because this should be called before executing the view.

A second thing I noticed is that within the ajax controller the request is being rebuild to simulate an views ajax request. Trying to mimmic the situation for views ajax. But none of the ajax variables from drupal settings are posted to the endpoint.
In case of viewsreference field it expects additional data to setup stuff like contextual filters through this.

Snippet from viewsreference.module

/**
 * Implements hook_views_pre_view().
 */
function viewsreference_views_pre_view(ViewExecutable $view, $display_id, array &$args) {
  if (!empty($view->getRequest()->request->get('viewsreference'))) {
    $view->element['#viewsreference'] = $view->getRequest()->request->get('viewsreference');
    // For ajax views we reset all handlers and make the view initialize again
    // to allow changes from the settings plugins.
    $view->display_handler->handlers = [];
    $view->inited = FALSE;
  }

  // Let all settings plugins alter the view.
  $viewsreference_plugin_manager = \Drupal::service('plugin.manager.viewsreference.setting');
  $plugin_definitions = $viewsreference_plugin_manager->getDefinitions();
  if (isset($view->element['#viewsreference']['enabled_settings'])) {
    foreach ($view->element['#viewsreference']['enabled_settings'] as $enabled_setting) {
      if (!empty($plugin_definitions[$enabled_setting])) {
        $plugin_definition = $plugin_definitions[$enabled_setting];
        /** @var \Drupal\viewsreference\Plugin\ViewsReferenceSettingInterface $plugin_instance */
        $plugin_instance = $viewsreference_plugin_manager->createInstance($plugin_definition['id']);
        $value = isset($view->element['#viewsreference']['data'][$plugin_definition['id']]) ? $view->element['#viewsreference']['data'][$plugin_definition['id']] : $plugin_definition['default_value'];
        $plugin_instance->alterView($view, $value);
      }
    }
  }
}

Other modules might implement similar constructions as well, but that won't work because the javascript for views only sends this:

    // Update facet blocks.
    var facet_settings = {
      url: Drupal.url('facets-block-ajax'),
      submit: $.extend({}, args, {
        facet_link: href,
        facets_blocks: facets_blocks
      })
    };

    // Update facets summary block.
    if (updateFacetsSummaryBlock()) {
      facet_settings.submit.update_summary_block = true;
      facet_settings.submit.facet_summary_plugin_id = $('[data-drupal-facets-summary-id=' + settings.facets_views_ajax.facets_summary_ajax.facets_summary_id + ']').data('drupal-facets-summary-plugin-id');
      facet_settings.submit.facet_summary_wrapper_id = settings.facets_views_ajax.facets_summary_ajax.facets_summary_id;
    }

    Drupal.ajax(facet_settings).execute();

To fix this we need a smart solution that also send the views data with the request as well and use it in the ajax controller to mimmic the ajax views request even better.

Data model changes

Issue fork facets-3211155

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jefuri created an issue. See original summary.

jefuri’s picture

Status: Active » Needs review

Nitebreed made their first commit to this issue’s fork.

erlendsynetic’s picture

Updated for version 2.0

krilo_89’s picture

Version: 8.x-1.x-dev » 2.0.x-dev

Also applies on 2.0.x, changed the version to this, because 8.x is a stale branch.

krilo_89’s picture

Here's the plain patch file to use for version 2.x.

dimas11’s picture

Patch updated for v.2.0.9

rayand’s picture

StatusFileSize
new196.77 KB

Hi,
The patch facets-take-views-prerender-into-account-3211155-9.patch trigger an error:
error path 9 for 2.0.9

The patches that I use:
"drupal/facets": {
"Empty exposed filter param on ajax link based facets": "https://git.drupalcode.org/project/facets/-/merge_requests/155.diff",
"Facets and exposed filters don't work together with Ajax": "https://www.drupal.org/files/issues/2023-10-06/3168241-14.facets-plus-ex...",
"facet-views-ajax.js and ajax controller do not take views prerender and views drupal js settings into account": "https://www.drupal.org/files/issues/2024-10-10/facets-take-views-prerend...",
"Facets with AJAX not working in most of situations": "https://www.drupal.org/files/issues/2024-12-17/3052574-270-2.0.9_2.patch"
}

Drupal Version : 10.3.10
PHP Version : 8.1.13

rayand’s picture

Status: Needs review » Needs work
jabastin arul’s picture

#8 path was not working for me.

daniel kulbe’s picture

Error Message for E400 is Input value "views" contains a non-scalar value..

Caused by newer versions of Symfony like in latest 10.6.x