0

I made a simple live search function to filter results in a table.

See below:

$( "#searchinput" ).keyup(function() {

  if ($( "#searchinput" ).val() == ''){
    //LEEG
    $( "#tabledatadiv" ).html('Loading...');
    $( "#tabledatadiv" ).load('tabledata.php');
  }else{
    //NIET LEEG
    $( "#tabledatadiv" ).html('Loading...');
    $( "#tabledatadiv" ).load('tabledata.php?searchquery='+encodeURIComponent($( "#searchinput" ).val()));
  }

});

The problem is that when a user is typing fast, and the previous "string"my script is searching for has a lot of results, the result of the previous search overwrites the results of the final one.

So, when searching for "ax" which gives 2 results, it first tries (while typing) to search for "a" which has 5000 results.

Loading the result for ax takes less time than loading results for a, to so you the result you need for a short time, and then the content of the div is overwritten by the result for "a".

How to prevent this? When a user types in a searchbox, it should stop loading or displaying the result of the previous keystroke.

Mbrouwer88
  • 2,182
  • 4
  • 25
  • 38

2 Answers2

1

You should really use the autocomplete api of jquery-ui. It gives you a lot of options (like delay, minLength, etc).

If you need to abort the previous request you can use something like this.

Community
  • 1
  • 1
Dekel
  • 60,707
  • 10
  • 101
  • 129
0

If the problem really is a "user typing too fast" issue, you can delay the autocomplete load by a set time. As Dekel pointed out, since you're using JQuery already, using JQuery UI's autocomplete would definitely be the simplest approach, but here's an example of how you'd implement a delay without leaning on JQuery UI (in case you can't for some reason):

var rtime; // reference time
var inTimeoutLoop = false; // whether a subsequent keyup action is forcing the wait loop to continue
var delta = 200; // wait time between keyup actions

  $('#searchinput').keyup(function () {
    rtime = new Date();
    if (inTimeoutLoop === false) {
      inTimeoutLoop = true;
      setTimeout(keyupEnd, delta);
    }
  });

  function keyupEnd() {
    var timelapse = new Date() - rtime;
    if (timelapse < delta) {
      setTimeout(keyupEnd, delta);
    } else {
      inTimeoutLoop = false;
      doAutocomplete();
    }
  }

  function doAutocomplete() {
    if ($( "#searchinput" ).val() == ''){
      //LEEG
      $( "#tabledatadiv" ).html('Loading...');
      $( "#tabledatadiv" ).load('tabledata.php');
    }else{
      //NIET LEEG
      $( "#tabledatadiv" ).html('Loading...');
      $( "#tabledatadiv" ).load('tabledata.php?searchquery='+encodeURIComponent($( "#searchinput" ).val()));
    }
  }
Jonathan Michalik
  • 1,492
  • 14
  • 15