JQuery Autocomplete labels escape HTML tags

Published 17 November 2010

We just upgraded JQuery UI to version 1.8.6 (from 1.8.2) and found some previously working Autocomplete code is now broken.

Specifically we had some cleverness which shows the matching text in the results in bold.

The source function of the autocomplete looks like this:

source: function(request, response) {
  var matcher = new RegExp(request.term, "i");
  $.ajax({
    url: "/suggest_contact",
    dataType: "jsonp",
    data: { search: request.term },
    success: function(data) {
      var results = $.map(data, function(item) {
        var contact = item.contact;
        return {
          label: contact.name.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + $.ui.autocomplete.escapeRegex(request.term) + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>"),
          value: contact.name,
          id: contact.id
        }
      });
      results.push({id: 0, label: "New contact: " + request.term, value: request.term});
      response(results);
    }
  })
}

So the returned JSON data label gets set with the contact name. Where the text matches the search for term we wrap in a <strong> tag.

Now it seems the <strong> tag gets escaped and appears in the search results:

JQuery Autocomplete showing the escaped HTML strong tag
JQuery UI now escapes the Autocomplete results

Sure enough the code which used to render the item has been updated to use the JQuery text() method, which escapes the HTML.

So to prevent that, I replace the /_renderItem/ method on autocomplete and use the JQuery html() method instead.

Just add this code to your Javascript somewhere and your HTML tags won’t be escaped anymore in Autocomplete:

/* this allows us to pass in HTML tags to autocomplete. Without this they get escaped */
$[ "ui" ][ "autocomplete" ].prototype["_renderItem"] = function( ul, item) {
return $( "<li></li>" ) 
  .data( "item.autocomplete", item )
  .append( $( "<a></a>" ).html( item.label ) )
  .appendTo( ul );
};