2

I have a views with 2 exposed filters - both taxonomy reference, select. I want to limit options in second filter based on user selection from the first. Tested with enabled/disabled ajax in views - no difference. Tested with exposed form in block - no difference.

Error message replace target filter: "An unrecoverable error occurred. The uploaded file likely exceeded the maximum file size (60 MB) that this server supports."

Using standard form alteration and ajax in form exposed filters, the filtering produce error. This work fine in custom form, but not in views exposed filter.

<?php

use Drupal\Core\Form\FormStateInterface;

function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {  
  if ($form_id == 'views_exposed_form') {
    if ($form['#id'] == 'views-exposed-form-articles-page-1') {
      //kint($form);
      //kint($form_state);
      //
      $form['field_tags2_target_id']['#prefix'] = '<div id="tags2-replace">';
      $form['field_tags2_target_id']['#suffix'] = '</div>';

      $form['field_tags_target_id']['#ajax'] = [
        'callback' => 'tags_ajax_callback',
        'wrapper' => 'tags2-replace'
      ];
    }
  }
}

function tags_ajax_callback($form, FormStateInterface $form_state) {
  // remove test2 1 (tid 3) from Tags2 options
  unset($form['field_tags2_target_id']['#options'][3]);

  $response = new AjaxResponse();
  $response->addCommand(new ReplaceCommand(
    '#tags2-replace',
    $form['field_tags2_target_id']
  ));
  return $response;

  //return $form['field_tags2_target_id'];
}

How to make this work?

1

This patch is related to this issue https://www.drupal.org/files/issues/2019-08-01/2842525-56.patch. See the section core/modules/views/src/ViewExecutable.php especially, the FormBuilder part is already committed but the rest is waiting.

| improve this answer | |
  • Hello This patch worked for apache server but issue still occur for nginx server drupal version- 8.6.13 php version - 7.1.25 – Gaurav Jadaun Oct 24 '19 at 14:36
0

If you don't want to patch the core you can create an EventSubscriber that attaches the view filter to the ajax command. After adding this your can use hook_form_alter to alter the filter. The subscriber looks like this.

file: yourmodule.services.yml

services:
  yourmodule.ajax_respose_subscriber:
    class: Drupal\yourmodule\EventSubscriber\AjaxResponseSubscriber
    tags:
      - {name: event_subscriber}

file: src/EventSubscriber/AjaxResponseSubscriber.php

<?php

namespace Drupal\yourmodule\EventSubscriber;

use Drupal\views\Ajax\ViewAjaxResponse;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Drupal\Core\Ajax\ReplaceCommand;

/**
 * Response subscriber to handle AJAX responses.
 */
class AjaxResponseSubscriber implements EventSubscriberInterface {

  /**
   * Renders the ajax commands right before preparing the result.
   *
   * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
   *   The response event, which contains the possible AjaxResponse object.
   */
  public function onResponse(FilterResponseEvent $event) {
    $response = $event->getResponse();

    // Only alter views ajax responses.
    if (!($response instanceof ViewAjaxResponse)) {
      return;
    }
    $view = $response->getView();

    // Only alter commands if view is ours.
    if ($view->storage->id() != 'yourviewname') {
      return;
    }

    // Alter commands.
    $display_handler = $view->display_handler;
    if ($display_handler->ajaxEnabled() && $display_handler->usesExposedFormInBlock()) {
      $form = $display_handler->viewExposedFormBlocks();
      $rendered_form = \Drupal::service('renderer')->renderRoot($form);
      $response->addCommand(new ReplaceCommand("#{$form['#id']}", $rendered_form));
    }

  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    return [KernelEvents::RESPONSE => [['onResponse']]];
  }

}

Sources: 1 & 2

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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