25

Could you please help me in highlighting the typed words in the auto complete text box. i am already populating the autocomplete words and i need to just highlight the typed words alone.i am new to Jquery autocomplete

i am getting the output as text like <Strong>Br</Strong>ijesh // seen as text
and not as highlighting the Br alone.

Below is the snippet

$(document).ready(function () {
$("#studentName").autocomplete({
    source: function (request, response) {
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: "Webservice.asmx/GetStudentNames",
            data: "{'prefixText':'" + request.term + "'}",
            dataType: "json", 
            success: function (data) {
           var regex = new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + request.term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi");
                response($.map(data.d, function (item) {
                    return {
                    label: item.split('|')[0].replace(regex, "<Strong>$1</Strong>"),
                    val: item.split('|')[1]
                    }
                }))
            },

            failure: function (response) {
                ServiceFailed(result);
            }
        });
    },
    select: function (event, ui) {
     txtStudent(ui.item.val, ui.item.label); //Student name and id used in this method
    },
    minLength: 2
});
});              // End of ready method

Please help me.

pal
  • 1,202
  • 6
  • 17
  • 27
  • One more remark. You use `val` and `label` property of `item`, but the documentation (see [here](http://wiki.jqueryui.com/w/page/12137709/Autocomplete) in the "Datamodel" part) describes that it should be `value` (not `val`) and `label`. – Oleg Mar 27 '12 at 16:23

6 Answers6

42

It seems to me you should overwrite the _renderItem method to have custom rendering of the items. The code could be about the following:

$("#studentName").autocomplete({/* all your parameters*/})
    .data("autocomplete")._renderItem = function (ul, item) {
        var newText = String(item.value).replace(
                new RegExp(this.term, "gi"),
                "<span class='ui-state-highlight'>$&</span>");

        return $("<li></li>")
            .data("item.autocomplete", item)
            .append("<div>" + newText + "</div>")
            .appendTo(ul);
    };

In the code I use jQuery UI CSS "ui-state-highlight" for highlighting. You can use <strong> instead. Moreover I don't include the code which would escape any RegEx characters which could be inside of this.term. I wanted to explain you the main idea only. Look at the answer for example for additional information.

UPDATED: More recent versions of jQuery UI uses .data("ui-autocomplete") instead of .data("autocomplete"). To make your code working in both (old and new) versions of jQuery you can do something like the following:

var $elem = $("#studentName").autocomplete({/* all your parameters*/}),
    elemAutocomplete = $elem.data("ui-autocomplete") || $elem.data("autocomplete");
if (elemAutocomplete) {
    elemAutocomplete._renderItem = function (ul, item) {
        var newText = String(item.value).replace(
                new RegExp(this.term, "gi"),
                "<span class='ui-state-highlight'>$&</span>");

        return $("<li></li>")
            .data("item.autocomplete", item)
            .append("<div>" + newText + "</div>")
            .appendTo(ul);
    };
}

UPDATED 2: In the same way the name "item.autocomplete" should be changed to "ui-autocomplete-item". See here.

Praveen Lobo
  • 6,956
  • 2
  • 28
  • 40
Oleg
  • 220,925
  • 34
  • 403
  • 798
  • @pal: By the way I see that you still never used your [voting](http://stackoverflow.com/privileges/vote-up) right. Voting is main criteria for the searching engine. You can vote up about 30 questions or answers **per day** (see [here](http://meta.stackexchange.com/a/5213/147495)). So by voting of helpful information which you find on the stackoverflow you help other visitors to find the information. So I recommend you to start to use your voting right. – Oleg Mar 28 '12 at 10:49
  • `RegExp(this.term, "gi")` will cause drama (may throw a JavaScript error) if the search term is anything that could be parsed as regex, particularly things like brackets or the dollar sign. – Lachlan McDonald Sep 03 '13 at 07:34
  • @nness: If you need highlight just text you can use `.toUpperCase().indexOf()` to locate the substring `this.term` in the string `item.value`. You can use simple JavaScript string sunctions to insert the ``. Alternatively you can escape all special characters *before* call of `RegEx` (see [the answer](http://stackoverflow.com/a/9168127/315935) for example). The main idea of my old answer was not providing perfect solution, but just showing that one can use custom implementation of `_renderItem` to render menu items in the custom way. – Oleg Sep 03 '13 at 10:24
  • @oleg, Absolutely understand; I just wanted to highlight the potential for issues for anyone copying and pasting the code without regexp experience. – Lachlan McDonald Sep 04 '13 at 02:05
  • the above code not working in my condition I have to use $.ui.autocomplete.prototype._renderItem = function (ul, item) {/*Rest of your code*/} – Avinash Ranjan Aug 21 '15 at 10:03
  • @AvinashRanjan: It's very important to know **which version of jQuery UI you use**. The usage of `$.ui.autocomplete.prototype._renderItem` is not the same as getting `elemAutocomplete = $elem.data("ui-autocomplete") || $elem.data("autocomplete");` and changing `_renderItem`. The interface is changed in different versions of jQuery UI. The above code is tested with jQuery UI 1.10.4 and older. There are many options to implement the requirement. – Oleg Aug 21 '15 at 10:13
  • I'm using jQuery Autocomplete 1.11.4, and there the parameter is not `autocomplete` or `ui-autocomplete`, but `uiAutocomplete`. – Mikko Saari May 14 '20 at 07:12
7

For a correct render in jQuery UI - v1.12.1 use "div", not "a"

$.ui.autocomplete.prototype._renderItem = function (ul, item) {        
    var t = String(item.value).replace(
            new RegExp(this.term, "gi"),
            "<strong>$&</strong>");
    return $("<li></li>")
        .data("item.autocomplete", item)
        .append("<div>" + t + "</div>")
        .appendTo(ul);
};
wildnove
  • 2,185
  • 2
  • 24
  • 32
4

we can also implement it like this.

 $("#studentName").autocomplete({/* all your parameters*/});
    $.ui.autocomplete.prototype._renderItem = function (ul, item) {        
        var t = String(item.value).replace(
                new RegExp(this.term, "gi"),
                "<span class='ui-state-highlight'>$&</span>");
        return $("<li></li>")
            .data("item.autocomplete", item)
            .append("<a>" + t + "</a>")
            .appendTo(ul);
    };
Avinash Ranjan
  • 180
  • 2
  • 11
2

If you are using new JQueryUI, You should replace this:

.data("autocomplete")._renderItem

to this:

.data("uiAutocomplete")._renderItem
Adam
  • 1,371
  • 2
  • 11
  • 12
2
$.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);
};

Use this

Raviteja
  • 3,399
  • 23
  • 42
  • 69
1

Here is the code I used to make it work (case insensitive):

open: function (e, ui) {
      var acData = $(this).data('ui-autocomplete');
      acData.menu.element.find('li').each(function () {
         var me = $(this);
         var keywords = acData.term.split(' ').join('|');
         me.html(me.text().replace(new RegExp("(" + keywords + ")", "gi"), '<strong>$1</strong>'));
      });
   }
Prateek
  • 1,229
  • 17
  • 31