facet-views-ajax.js and ajax controller do not take views prerender and views drupal js settings into account

Created on 28 April 2021, over 3 years ago
Updated 10 October 2024, about 1 month ago

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

🐛 Bug report
Status

Needs review

Version

2.0

Component

Code

Created by

🇳🇱Netherlands jefuri

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024