Insensitive search when typing in INPUT

2

I have the JavaScript search engine below. The problem is that when I type the word " tomato " it looks for the word " tomatoes ". It's probably a sensitivity problem or you're just picking up part of the typed word. Would it be possible to fix this using just javascript or jQuery?

$("#box").on('keyup', function() {
   var matcher = new RegExp($(this).val(), 'gi');
	$('.connect-cat').show().not(function() {
	   return matcher.test($(this).find('.name, .category').text())
    }).hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input placeholder='Search' id='box' type='text' />
<div style='clear:both;'></div>
			
<div class='connect-cat'>
	<span class='name'>tomatoes</span>
</div>
			
<div class='connect-cat'>
	<span class='name'>tomato</span>
</div>
   
<div class='connect-cat'>
	<span class='name'>apple</span>
</div>
    
asked by anonymous 09.05.2018 / 19:44

2 answers

1

The return you expect from the function within .not() must be a element , a selector , or an array ( .not() documentation). As it stands, the return is either a true or false , which has no effect on the method.

Change the return to a ternary that will return the element itself (if the condition is true ) or null (if it is false ). That is, by returning the element itself, it will not suffer .hide() later.

return matcher.test($(this).find('.name, category').text()) ? $(this) : null;

Regarding search, there are two ways to resolve this:

1. Using .test() :

Uncheck the g ( global ) flag because the behavior of this flag with .test and .exec is different from .match (#).

$("#box").on('keyup', function(){
   var matcher = new RegExp($(this).val(), 'i');
   $('.connect-cat').show().not(function(){
       return matcher.test($(this).find('.name, category').text()) ? $(this) : null;
   }).hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><inputplaceholder='Search'id='box'type='text'/><divstyle='clear:both;'></div><divclass='connect-cat'><spanclass='name'>tomatoes</span></div><divclass='connect-cat'><spanclass='name'>tomato</span></div><divclass='connect-cat'><spanclass='name'>tomatos</span></div><divclass='connect-cat'><spanclass='name'>apple</span></div>

2.Using.match():

$("#box").on('keyup', function(){
   var matcher = new RegExp($(this).val(), 'gi');
   $('.connect-cat').show().not(function(){
      return $(this).find('.name, category').text().match(matcher) ? $(this) : null;
   }).hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><inputplaceholder='Search'id='box'type='text'/><divstyle='clear:both;'></div><divclass='connect-cat'><spanclass='name'>tomatoes</span></div><divclass='connect-cat'><spanclass='name'>tomato</span></div><divclass='connect-cat'><spanclass='name'>tomatos</span></div><divclass='connect-cat'><spanclass='name'>apple</span></div>

Edit

  

Justtoreinforceandcontrarytowhattheotheranswersays,theflag  %with%HAVEYESTOVIEWwiththewaygworks,as  youcansee in this documentation , which I am reporting again. It seems to me that the   our friend of the other response did not read, or read and did not understand.

Also as this answer in SOen:

  

When you use the global flag on a JS RegExp the "test" and "exec"   methods each halt at the first match but keep a pointer to where they   stopped searching in the string. That pointer can be inspected on the   lastIndex property. When you call "test" or "exec" again it begins   searching for a match starting at the lastIndex.

     

So, when you test RegExp on a string that matches the entire string   the lastIndex is set to the end of the string. The next time you test   it starts at the end of the string, returns false, and sets lastIndex   back to zero.

Free translation:

  

When you use the global flag ( .test() ) in a JavaScript regex, both   the "test" and "exec" methods stop at the first match and maintain   position in the string search. This position can be   lastIndex property. When you call the "test" or "exec"   again, the search will start from the last verified position ( cito:   this explains the malfunction that was occurring ).

     

So when you test a RegExp in a string that will match the entire   string, the lastIndex will be at the end of the string. The next time you   test, it will start at the end of the string, returning false , and   resetting the lastIndex back to zero.

    
09.05.2018 / 21:40
0

The way you used regex

new RegExp($(this).val(), 'gi');

Of course the use of regex will always be a problem since you have no control over the value of val()

Even the problem with "tomatoes" is that there are no "delimiters" ^ and $ at the beginning and end of the regex, and just to note, the problem has nothing to do with with the g modifier.

If there is a lot of complexity that is not necessary, you would have to use .toLowerCase on both of these values, for example:

$("#box").on('keyup', function() {
    var matcher = $(this).val().toLowerCase();

	$('.connect-cat').show().not(function() {
	   return matcher == $(this).find('.name, .category').text().toLowerCase()
    }).hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input placeholder='Search' id='box' type='text' />
<div style='clear:both;'></div>
			
<div class='connect-cat'>
	<span class='name'>tomatoes</span>
</div>
			
<div class='connect-cat'>
	<span class='name'>tomato</span>
</div>
   
<div class='connect-cat'>
	<span class='name'>apple</span>
</div>

If you intend to search for words beginning with what you typed in, you can use .indexOf() == 0

var matcher = $(this).val().toLowerCase();

$('.connect-cat').show().not(function() {
   return matcher.indexOf( $(this).find('.name, .category').text().toLowerCase() ) == 0
}).hide();

If the intention is to search for words that contain part of what was typed, you can use .indexOf() != -1

var matcher = $(this).val().toLowerCase();

$('.connect-cat').show().not(function() {
   return matcher.indexOf( $(this).find('.name, .category').text().toLowerCase() ) != -1
}).hide();
    
09.05.2018 / 21:56