1

I need to be able to search for the first name OR possible middle name and last name of a user and have it pop up in the search results. If my user in a test case is "Alicia Henderson", currently with the following code, I can grab anything from the letter A onward (i.e. Alic, Alicia Hen). However, I would like to be able to type in "H" and get Alicia Henderson (and all other cases in any other word in that may be in the users name. Similar to how Facebook, Twitter, and many other fantastic search engines have. Thanks in advance!

    $("input[name='search_users']").keyup(function(){

        // Retrieve the input field text and reset the count to zero
        var filter = "^" + $(this).val(), itemsFound = 0;

        // Loop through each user
        $(".send_to .messages .message_username").each(function(){

            // If the list item does not contain the text phrase fade it out
            if ($(this).text().search(new RegExp(filter, "i")) < 0) {
                $(this).parent().css("display","none");

            // Show the list user if the phrase matches and increase the count by 1
            } else {                
                $(this).parent().show();
                itemsFound++;
            }

        });

    });
Dtrav
  • 355
  • 1
  • 2
  • 14
  • You could try taking away the `"^" + ` flag you've appended to the regex. The caret `^` character matches the start of the string. If you remove it, it will match values part-way through. – James Jul 05 '17 at 19:16
  • Try replacing `"^"` with `"(?:^|\\s)"`, or with just `"\\b"` (if you only work with ASCII letters). – Wiktor Stribiżew Jul 05 '17 at 20:35
  • Wiktor the first option works perfectly. Thanks a million! – Dtrav Jul 05 '17 at 21:10

2 Answers2

2

You need to replace the start of string anchor with another pattern that will allow matching any whitespace or start of string anchor, OR - if you only work with ASCII letters - a word boundary \b.

The regex you need may also be necessary to escape properly (if it contains (, ), or other special regex chars. So, this is how the regex should be declared:

 new RegExp( "(?:^|\\s)" + this.value.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), "i" )

Here, (?:^|\\s) is a non-capturing group (?:...) that matches either a string start position (^) or any whitespace (\\s) and the this.value special regex chars are escaped with escaping regex. The "i" modifier makes the pattern case insensitive.

Here is a snippet showing how this regex works:

function filterUsers() {
    var rgx = new RegExp( "(?:^|\\s)" + this.value.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), "i" );
    var $el = $(".message_username").hide().filter(function() {
      return  rgx.test( $(this).text() );
    }).show();
    $(this).next("span").text("Results:"+ $el.length);
}

$("input[name='search_users']").on("input", filterUsers);
<input type="text" name="search_users"> <span></span>
<ul>
  <li class="message_username">Alicia Barson</li>
  <li class="message_username">Brittney Halley</li>
  <li class="message_username">Alicia Henderson</li>
  <li class="message_username">Sten Tong</li>
  <li class="message_username">Bung Gang</li>
  <li class="message_username">Jin Jang</li>
  <li class="message_username">John Supreme</li>
  <li class="message_username">Super Man</li>
  <li class="message_username">Man Chester</li>
  <li class="message_username">Super Alicia</li>
</ul>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
0

First, try using this function to test the match:

const str = "Alicia Henderson";

console.log(testMatch(str, 'Alicia'));
console.log(testMatch(str, 'H'));
console.log(testMatch(str, 'NOPE!'));

function testMatch(str, inputToTest){
 return (new RegExp(inputToTest, 'gi')).test(str);
}
Diego ZoracKy
  • 2,227
  • 15
  • 14