2

Is there a way (a hook perhaps) that would allow me to modify the autocomplete fields returned by an exposed views_autocomplete_filter field? I'd like to style the text typed into the field differently from the rest of the suggestion text.

Something like this:

------------------
| term_          |
------------------------------
| terminal emulators |
------------------------------
| determination         |
------------------------------
| midterm exams      |
------------------------------

  • Could be done via javascript/jquery. – No Sssweat Feb 27 '20 at 23:44
0

So it seems it is necessary to extend the ViewsAutocompleteFiltersController class to do this. In order to override the routing so that a custom controller can be used instead, an entry must be added to /mymodule/mymodule.services.yml:

services:
  mymodule.route_subscriber:
    class: Drupal\mymodule\Routing\RouteSubscriber
    tags:
      - { name: event_subscriber }

Then provide your /mymodule/src/Routing/RouteSubscriber.php file, which redirects to our local ViewsAutocompleteFiltersController

<?php

namespace Drupal\mymodule\Routing;

use Drupal\Core\Routing\RouteSubscriberBase;
use Symfony\Component\Routing\RouteCollection;

/**
 * Listens to the dynamic route events.
 */
class RouteSubscriber extends RouteSubscriberBase {

  /**
   * {@inheritdoc}
   */
  public function alterRoutes(RouteCollection $collection) {
    // Replace "some.route.name" below with the actual route you want to override.
    if ($route = $collection->get('viewsfilters.autocomplete')) {
      $route->setDefaults(array(
        '_controller' => '\Drupal\mymodule\Controller\ViewsAutocompleteFiltersController::autocomplete',
      ));
    }
  }
}

Finally provide your local /mymodule/src/Controller/ViewsAutocompleteFiltersController.php which filters for the view of interest, then modifies the output of the base ViewsAutocompleteFiltersController. The tricky part of that process is that the data member of the JsonResponse output is protected, so we use a customized JsonResponse wrapper to perform the highlighting:

<?php

namespace Drupal\mymodule\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;

/**
 * Overrides default ViewsAutocompleteFiltersController to provide highlighting of autocomplete suggestions
 */
class ViewsAutocompleteFiltersController extends \Drupal\views_autocomplete_filters\Controller\ViewsAutocompleteFiltersController {

  /**
   * {@inheritdoc]
   */
  public function autocomplete(Request $request, $view_name, $view_display, $filter_name, $view_args) {

    $response = parent::autocomplete($request, $view_name, $view_display, $filter_name, $view_args);
    if($response instanceof JsonResponse && $view_name === 'my_view' && $view_display === 'my_view_display') {
      $response = new HighlightedJsonResponse($response, $request->query->get('q'));
    }
    return $response;
  }

}


/**
 * Overrides default JsonResponse to provide highlighting of autocomplete suggestions
 */
class HighlightedJsonResponse extends JsonResponse {

  function __construct($jsonResponse, $q) {

    $data = \json_decode($jsonResponse->data);
    if(isset($q)) {
      $qPattern = '/(' . preg_quote($q, '/') . ')/i';
      foreach($data as &$datum) {
        if(isset($datum->label)) {
          $datum->label = '<b>' . \preg_replace($qPattern, '</b>$0<b>', $datum->label) . '</b>';
          $datum->label = \str_replace("<b></b>","",$datum->label);
        }
      }
    }

    parent::__construct($data, $jsonResponse->statusCode, $jsonResponse->headers->all());

  }
}

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.