1

I have an autocomplete (jQuery) in which I want to highlight any words in the dropdown that occur in the user input. User enters: "holy water" then both holy and water should be highlighted even if they're not next to each other. So entering multiple words should highlight multiple words if present

Entering multiple words should highlight multiple words if present

I'm trying to do this with just making text bold using a regular expression

_renderItem: function( ul, item ) {
    var termWords = this.term.trim().split(" ").join("|"); //if multiple words, split into parts, join back with ors to use in regexp
    var regex = new RegExp("({"+termWords+"[s]?}*)([\s\.,])","gi"); // convert to regex, make global and case insensitive
    var currentLabel = item.label;
    var currentLabel = currentLabel.replace(regex, "<b>$1</b>$2");
    var itemHtml = '<a>'+ currentLabel + '</a>';
    return $( "<li></li>" )
        .data( "item.autocomplete", item )
        .html(itemHtml)
        .appendTo( ul );
}

Trying this out if I enter "is language", the output expression becomes

/({is|language[s]?}*)([s.,])/gi

But the problem is, none of the text I enter matches and hence isn't highlighted.

Here is a jsfiddle of what I'm trying: http://jsfiddle.net/8tD49/5/ , just note that it's not exactly the same as my own ajax function returns results as seen in the image.

Edit:

Final answer to highlight multiple strings:

_renderItem: function( ul, item ) {
    var termWords = this.term.trim().split(" ").join("|"); //if multiple words, split into parts, join back with ors
    "(?:"+termWords+"[s]?)*"
    var regex = new RegExp("((?:"+termWords+")s?)([\s.,])?","gi");
    var currentLabel = item.label;
    var currentLabel = currentLabel.replace(regex, "<b>$1</b>$2");
    var itemHtml = '<a>'+ currentLabel + '</a>';
    return $( "<li></li>" )
        .data( "item.autocomplete", item )
        .html(itemHtml)
        .appendTo( ul );
}

http://jsfiddle.net/8tD49/7/

2 Answers 2

1

I believe you mixed up {} and simple parenthesis. For matching either something OR another, the syntax is something|other. If you need to enclose in non-selective parenthesis, the syntax is

(?:is|language[s]?)*

But here, I don't think the * is necessary. You want to match all occurrences of a few words: all you have to do is do a regex that would match any of these words. The g flag will take care of repeating the task.

Your complete regex should then become:

"/((?:"+termWords+")s?)([\s.,])?/gi"
...
/((?:is|language)s?))([s.,])?/gi

The ([.,]?) part (why did you put an s there, btw?) seems a little restrictive too. You could use (\W?) instead for english language (\W is short for non alphanumerical character, ie [^a-zA-Z0-9], which means it would catch any punctuation but mess up words like journée).

And you may wanna be careful when you try to catch plural, in this example iss would also be catched... This part probably needs a bit more thinking !

Sign up to request clarification or add additional context in comments.

1 Comment

Edited answer for a few more precautions you might wanna take.
1

You'll need to use word boundaries (\b)

(\bis\b|\blanguage\b)

is this the correct language. The above regex matches is and language.

3 Comments

well, i do want to bold a substring, not entire words
for example I still want to highlight brook even though I didn't type brookstone
Ahh, yes. I was mainly basing it off of your 1st paragraph description. It'll be interesting. Say the first character typed is an "a", you could get a lot of highlighed a's.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.