views:

2215

answers:

8

I'm using jQuery UI Autocomplete plug-in. Is there a way to highlight search character sequence in drop-down results?

For example, if I have data: "foo bar" it and I search for "foo" I get "foo bar" in drop down.

A: 

If you instead use the 3rd party plugin, it has a highlight option: http://docs.jquery.com/Plugins/Autocomplete/autocomplete#url_or_dataoptions

(see the Options tab)

Brian Luft
yeah I'm aware of this plug in. however, we are using jQueryUI in our app so it would be nice to get this working with jQueryUI Autocomplete plug-in
dev.e.loper
As of 2010-06-23, the jQuery Autocomplete plugin has been deprecated in favor of the jQuery UI Autocomplete plugin. See http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/ for more information
shek
+12  A: 

Yes, you can if you monkey-patch autocomplete.

In the autocomplete widget included in v1.8rc3 of jQuery UI, the popup of suggestions is created in the _renderMenu function of the autocomplete widget. This function is defined like this:

_renderMenu: function( ul, items ) {
    var self = this;
    $.each( items, function( index, item ) {
        self._renderItem( ul, item );
    });
},

The _renderItem function is defined like this:

_renderItem: function( ul, item) {
    return $( "<li></li>" )
        .data( "item.autocomplete", item )
        .append( "<a>" + item.label + "</a>" )
        .appendTo( ul );
},

So what you need to do is replace that _renderItem fn with your own creation that produces the desired effect. This, I have come to learn, is called monkey-patching. Here's how I did it:

  function monkeyPatchAutocomplete() {

      // don't really need this, but in case I did, I could store it and chain
      var oldFn = $.ui.autocomplete.prototype._renderItem;

      $.ui.autocomplete.prototype._renderItem = function( ul, item) {
          var re = new RegExp("^" + this.term) ;
          var t = item.label.replace(re,"<span style='font-weight:bold;color:Blue;'>" + this.term + "</span>");
          return $( "<li></li>" )
              .data( "item.autocomplete", item )
              .append( "<a>" + t + "</a>" )
              .appendTo( ul );
      };
  }

Now, this is a hack, because

  • there's a regexp obj created for every item rendered in the list. That regexp obj ought to be re-used for all items.

  • there's no css class used for the formatting of the completed part. It's an inline style.
    This means if you had multiple autocompletes on the same page, they'd all get the same treatment. A css style would solve that.

...but it illustrates the main technique, and it works for your basic requirements.

alt text

working example: http://jsbin.com/ezifi/4

Cheeso
Thanks Cheeso. Do you have jsbin link for this?
dev.e.loper
yes, try this: http://jsbin.com/ezifi/4
Cheeso
Very helpful! Thanks.
womp
A: 

Wouldn't such monkey patching apply to all instances of any autocomplete used on the page? If you have several, you'd often want different result rendering on each.

iampivot
Ask a new question.
Cheeso
A: 

Take a look at the combobox demo, it includes result highlighting: http://jqueryui.com/demos/autocomplete/#combobox

The regex in use there also deals with html results.

Jörn Zaefferer
A: 

@Cheeso Thanks for your solution. Works like a charm :).

brechtvhb
A: 

this also works:

       $.ui.autocomplete.prototype._renderItem = function (ul, item) {
            item.label = item.label.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + $.ui.autocomplete.escapeRegex(this.term) + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
            return $("<li></li>")
                    .data("item.autocomplete", item)
                    .append("<a>" + item.label + "</a>")
                    .appendTo(ul);
        };

a combination of @Jörn Zaefferer and @Cheeso's responses.

Raj
A: 

for an even easier way, try this:

$('ul: li: a[class=ui-corner-all]').each (function (){      
 //grab each text value 
 var text1 = $(this).text();     
 //grab user input from the search box
 var val = $('#s').val()
     //convert 
 re = new RegExp(val, "ig") 
 //match with the converted value
 matchNew = text1.match(re);
 //Find the reg expression, replace it with blue coloring/
 text = text1.replace(matchNew, ("<span style='font-weight:bold;color:green;'>")  + matchNew +    ("</span>"));

    $(this).html(text)
});
  }
Aaron
A: 

Thanks Cheeso for the helpful monkey patch. Once little annoyance though - is there a way to make the replacement keep the case of the original text?

For example:- Typing 'c' will bring up '*c*alifornia'. Is there a way for it to show '*C*alifornia'? Similarly for letters appearing in the middle of phrases.

That would be really nice thanks!

ongkybeta