2

Hey all I am trying to stop the animation from "blinking" as many times as the user types in a word into the text box.

Here is the jQuery search code:

$('#searchTxtBox1, #searchTxtBox2').keyup(function() {
   var input = $(this).val();
   var _this = $('#' + $(this).attr('data-id') + ' .select3-multiple-selected-item');
   var theLeanth = $(this).val().length;

   switch(true){
    case input === '':
        _this.animate({"opacity": 1.0}, 250);
        break;
    default:
        _this.animate({"opacity": 0.2}, 250);
        _this.filter('[data-searchBox*="' + input.toLowerCase() + '"]').animate({"opacity": 1.0}, 250);             
    break;
   }
});

And the HTML:

<div>
    <input style="margin-bottom:1em ;" data-id="Inventory1" id="searchTxtBox1" placeholder="Search..." class="form-control">
</div>
<h1>jQuery jSearch Plugin Demo</h1>
<ul class="list-group">
    <div class="select3-multiple-input-container" id="Inventory1">
        <li class="select3-multiple-selected-item item list-group-item list-group-item-success" data-searchBox="vegan pizza">vegan pizza</li>
        <li class="select3-multiple-selected-item item list-group-item list-group-item-info" data-searchBox="coke soda">coke soda</li>
        <li class="select3-multiple-selected-item item list-group-item list-group-item-warning" data-searchBox="cheese pizza">cheese pizza</li>
        <li class="select3-multiple-selected-item item list-group-item list-group-item-danger" data-searchBox="pepsi soda">pepsi soda</li>
        <li class="select3-multiple-selected-item item list-group-item list-group-item-success" data-searchBox="chocolate cake">chocolate cake</li>
        <li class="select3-multiple-selected-item item list-group-item list-group-item-info" data-searchBox="glaze donut">glaze donut</li>
        <li class="select3-multiple-selected-item item list-group-item list-group-item-warning" data-searchBox="cheese cake">cheese cake</li>
        <li class="select3-multiple-selected-item item list-group-item list-group-item-danger" data-searchBox="cream donut">cream donut</li>
    </div>
</ul>

This code above does work and filters the needed typed word out of the list but it continues to blink (animation opacity in and out) for every letter typed into the textbox.

enter image description here

What would I need to modify in order to only allow the .filter part of the code to only fire once it finishes with the typing (or while typing since this is a live search filter)?

StealthRT
  • 10,108
  • 40
  • 183
  • 342
  • perhaps, throttle/delay opacity animations for keyup event? [underscore delay](http://underscorejs.org/#delay) – Varinder Feb 21 '18 at 21:49
  • Possible duplicate [Run javascript function when user finishes typing instead of on key up?](https://stackoverflow.com/questions/4220126/run-javascript-function-when-user-finishes-typing-instead-of-on-key-up) – Ele Feb 21 '18 at 21:57
  • @Ele not a dup as this is a **live** search. – StealthRT Feb 21 '18 at 22:00
  • A possible duplicate means that you can leverage a very close solution. Therefore, go ahead and read the possible solution from that question, just take the idea to solve your problem. – Ele Feb 21 '18 at 22:09
  • @Ele looking at the "dup" and using some code examples on there yielded the same results. – StealthRT Feb 21 '18 at 22:22

2 Answers2

0

The problem was that you were changing the opacity of the entire list, and then changing it again for items that were searched on. By filtering on what is NOT searched on or selected, you can avoid that blinking animation:

$('#searchTxtBox1, #searchTxtBox2').keyup(function() {
   var input = $(this).val();
   var _this = $('#' + $(this).attr('data-id') + ' .select3-multiple-selected-item');
   var theLeanth = $(this).val().length;

   switch(true){
    case input === '':
        _this.animate({"opacity": 1.0}, 250);
        break;
    default:
        _this.filter('li:not([data-searchBox*="' + input.toLowerCase() + '"])').animate({"opacity": 0.2}, 250);
    break;
   }
});

EDIT: Oops jumped the gun there. The fix above doesn't account for when the user backspaces; when the user does, the searched values should be rehighlighted. The fix below works perfectly.

$('#searchTxtBox1, #searchTxtBox2').keyup(function() {
   var input = $(this).val();
   var _this = $('#' + $(this).attr('data-id') + ' .select3-multiple-selected-item');
   var theLeanth = $(this).val().length;

   switch(true){
    case input === '':
        _this.animate({"opacity": 1.0}, 250);
        break;
    default:
            _this.each(function(e){
            if (_this.eq(e).attr('data-searchBox').indexOf(input.toLowerCase()) < 0){
            _this.eq(e).animate({"opacity": 0.2}, 250);
          } else {
            _this.eq(e).animate({"opacity": 1.0}, 250);
          }
        });
    break;
   }
});
Eric Nam
  • 21
  • 4
0

Here is a working sample. Adding a setTimeout on keyup will do.

var to;
$('#searchTxtBox1, #searchTxtBox2').keyup(function() {
   var input = $(this).val();
   var _this = $('#' + $(this).attr('data-id') + ' .select3-multiple-selected-item');
  if(to) { // If a timeout object is set and you are still typing, cancel it
    clearTimeout(to);
    to = null;
  }
  to = setTimeout(function() {
    if(!_this) {
      return;
    }
    switch(true){
      case input === '':
        _this.animate({"opacity": 1.0}, 250);
        break;
      default:
        _this.animate({"opacity": 0.2}, 250);
        _this.filter('[data-searchBox*="' + input.toLowerCase() + '"]').animate({"opacity": 1.0}, 250);
   }
  }, 500);
});
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<div>
    <input style="margin-bottom:1em ;" data-id="Inventory1" id="searchTxtBox1" placeholder="Search..." class="form-control">
</div>
<h1>jQuery jSearch Plugin Demo</h1>
<ul class="list-group">
    <div class="select3-multiple-input-container" id="Inventory1">
        <li class="select3-multiple-selected-item item list-group-item list-group-item-success" data-searchBox="vegan pizza">vegan pizza</li>
        <li class="select3-multiple-selected-item item list-group-item list-group-item-info" data-searchBox="coke soda">coke soda</li>
        <li class="select3-multiple-selected-item item list-group-item list-group-item-warning" data-searchBox="cheese pizza">cheese pizza</li>
        <li class="select3-multiple-selected-item item list-group-item list-group-item-danger" data-searchBox="pepsi soda">pepsi soda</li>
        <li class="select3-multiple-selected-item item list-group-item list-group-item-success" data-searchBox="chocolate cake">chocolate cake</li>
        <li class="select3-multiple-selected-item item list-group-item list-group-item-info" data-searchBox="glaze donut">glaze donut</li>
        <li class="select3-multiple-selected-item item list-group-item list-group-item-warning" data-searchBox="cheese cake">cheese cake</li>
        <li class="select3-multiple-selected-item item list-group-item list-group-item-danger" data-searchBox="cream donut">cream donut</li>
    </div>
</ul>
CodeLover
  • 571
  • 2
  • 11