0

I am trying to implement jQuery autocomplete box and successfully integrated into my project. Here I am giving the source for the jquery Autocomplete box as list elements.

    var _array = ['<li height="45px" class="ui-menu-item ui_dropdown_item" role="presentation"><a id="ui-id-302" class="ui-corner-all ui_dropdown_focus" tabindex="-1"><img class="apps-share-chips-profile-icon" src="build/assets/apple.png" onerror="helper.onImageError(this);"><span search="text">01arun23@gmail.com</span></a></li>',
'<li height="45px" class="ui-menu-item ui_dropdown_item" role="presentation"><a id="ui-id-302" class="ui-corner-all ui_dropdown_focus" tabindex="-1"><img class="apps-share-chips-profile-icon" src="build/assets/ms.png" onerror="helper.onImageError(this);"><span search="text">aaron.lee@rescue.org</span></a></li>'];

As you see, I am giving li elements as source and binding it in jQuery as below.

$(this).data('ui-autocomplete')._renderItem = function(ul, item) {
    return $(item.label).appendTo(ul);
};

So I get the functionality completed. Now what am trying to achieve is highlighting the query that the user enter, like given in this SO link.

My try as of is given below, I am trying to replace the span tag text with the query that user enters. How could I achieve this in my scenario.

$(this).data('ui-autocomplete')._renderItem = function(ul, item) {
    $(item.label).find('span').replace(new RegExp('(?![^&;]+;)(?!<[^<>]*)(' + $.ui.autocomplete.escapeRegex(this.term) + ')(?![^<>]*>)(?![^&;]+;)', 'gi'), '<span style="font-weight:bold;color:Blue;">$1</span>');

    return $(item.label).appendTo(ul);
};

But I couldn't able to achieve and I dont know what's going wrong in my solution. Answers are highly appreciated.

EDIT: I have added the jsfiddle link. Just want to add the highlight query functionality in that.

Community
  • 1
  • 1
Balasubramani M
  • 7,742
  • 2
  • 45
  • 47
  • Do you mean something like [this](https://jsfiddle.net/julmot/bs69vcqL/) – using [mark.js](https://markjs.io/)? – dude Jul 05 '16 at 08:57

1 Answers1

1

Since I'm using JQuery UI Autocomplete myself and I found this interesting, I experimented a bit with it.

First of: I have like zero idea how regex works, but I believe the regex is the problem here.

Second: I found this: Case insensitive string replacement in JavaScript?

And with this regex it works for me:

.data("ui-autocomplete")._renderItem = function (ul, item) {
                var t = highlightWords(item.label, this.term);
                return $("<li></li>")
                    .data("item.autocomplete", item)
                    .append(t)
                    .appendTo(ul);
            };
        });



    function highlightWords( line, word )
    {
        var regex = new RegExp( '(' + preg_quote(word) + ')', 'gi' );
        return line.replace( regex, "<b>$1</b>" );
    }

    function preg_quote( str ) {
        return (str+'').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1");
    }

Hope that helps you. :)

EDIT: Added the preg_quote function from the accepted answer in the stackoverflow question I linked, it is needed so you can search for something like 'name.' to make it work properly.

Community
  • 1
  • 1
Danmoreng
  • 2,367
  • 1
  • 19
  • 32
  • No this isn't working. See my question, and the source given. The source is collection of list elements. You are again creating li elements while returning and so it creates li inside li. Thats what my problem is. How to replace text inside that li element which is in source? – Balasubramani M Jul 05 '16 at 09:32
  • Check js fiddle link which I have attached in question, try the above functionality in that. – Balasubramani M Jul 05 '16 at 09:47
  • So what exactly is the problem? Looks like its working to me: https://jsfiddle.net/0nzrzumj/1/ – Danmoreng Jul 05 '16 at 09:58
  • Yes the functionality works but not as expected. Instead of searching and replacing text inside span, it matches the text with the whole li element instead of text in span. See the following pics for more info. https://postimg.org/image/trgun4x81/ https://postimg.org/image/vkocp77sh/ – Balasubramani M Jul 06 '16 at 05:20
  • Soved this issue by sending the item.label twice to the highlightWords function and could able to get it, but still waiting for the proper solution. – Balasubramani M Jul 06 '16 at 09:07
  • Well if you have no influence on the item.label, you would have to parse for the , string split it, then highlight words in only that part, then put it back together. – Danmoreng Jul 08 '16 at 08:29
  • It's actually pretty straightforward, here you go: https://jsfiddle.net/0nzrzumj/2/ – Danmoreng Jul 08 '16 at 08:42