Steps to reproduce:

  1. Create a form with more then one autocomplete element.
  2. Create a custom autocomplete route.
  3. Have the labels of the returned results contain html tags.

Expected behavior:

  1. The html being rendered (correctly) on all autocomplete elements.

Result:

  1. Only the first element rendered the HTML.
  2. The other element(s) displayed the escaped html.

The error originates from the Drupal.behaviors.autocomplete behavior in core/misc/autocomplete.js file.

  Drupal.behaviors.autocomplete = {
    attach: function (context) {
      // Act on textfields with the "form-autocomplete" class.
      var $autocomplete = $(context).find('input.form-autocomplete').once('autocomplete');
      if ($autocomplete.length) {
        // Allow options to be overriden per instance.
        var blacklist = $autocomplete.attr('data-autocomplete-first-character-blacklist');
        $.extend(autocomplete.options, {
          firstCharacterBlacklist: (blacklist) ? blacklist : ''
        });
        // Use jQuery UI Autocomplete on the textfield.
        $autocomplete.autocomplete(autocomplete.options)
          .data('ui-autocomplete')
          ._renderItem = autocomplete.options.renderItem;
      }
    },
    detach: function (context, settings, trigger) {
      if (trigger === 'unload') {
        $(context).find('input.form-autocomplete')
          .removeOnce('autocomplete')
          .autocomplete('destroy');
      }
    }
  };

The issue is caused by the following line of code:
$autocomplete.autocomplete(autocomplete.options).data('ui-autocomplete')._renderItem = autocomplete.options.renderItem;

Which changes the _renderItem method of only the first autocomplete element.
The other elements use the default _renderItem method that escapes html.

Proposed Solution:

Update the above implementation to use foreach method and apply the custom render method to all items.

        $autocomplete.each(function() {
          // Use jQuery UI Autocomplete on the textfield.
          $(this).autocomplete(autocomplete.options)
            .data('ui-autocomplete')
            ._renderItem = autocomplete.options.renderItem;
        });

Comments

Eyal Shalev created an issue. See original summary.

Eyal Shalev’s picture

droplet’s picture

Version: 8.0.5 » 8.0.x-dev
Status: Active » Closed (duplicate)
Eyal Shalev’s picture

Sorry for the duplication.

For some reason I wasn't able to find the issue you linked.

droplet’s picture

Nevermind. I did spend some time to search it back. For some reason, it doesn't show in search result :s