Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Steps to reproduce:
- Create a form with more then one autocomplete element.
- Create a custom autocomplete route.
- Have the labels of the returned results contain html tags.
Expected behavior:
- The html being rendered (correctly) on all autocomplete elements.
Result:
- Only the first element rendered the HTML.
- 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
Comment #2
Eyal ShalevComment #3
droplet CreditAttribution: droplet commented#2665738: jQuery Autocomplete applies "_renderItem" option only for first element on the page
Comment #4
Eyal ShalevSorry for the duplication.
For some reason I wasn't able to find the issue you linked.
Comment #5
droplet CreditAttribution: droplet commentedNevermind. I did spend some time to search it back. For some reason, it doesn't show in search result :s