[SOLVED] "Live Search Heading" being displayed twice

At least the search does not take very long to perform the query :slight_smile:

Is it possible to measure the time taken from entering a character to displaying the results on your UK laptop?

I’m sure there’s something that could be added to the JavaScript to note the time when the request is sent, and the time when the data comes back. I’m not sure what it is, but I’d expect something similar to how you did it in the PHP code, but in the JS that runs here. You might then be able to subtract the time taken to actually perform the search, which would give you the time taken to send the request and get the data back.

Just remembered that a query can be passed from the browser’s search:

https://johns-jokes.com/downloads/sp-i/dasabooks/index.php?q=this%20l%20b%20e%20g%20

Pingdom results:

1.97 secs - Melbourne, Australia
1.42 secs - Stockholm, Sweden
107 mSecs - San Jose, California

Repeating the queries gave very different results which I suppose is due to the amount of global traffic.

Are you buffering the calls appropriately so that you do not get a multitude of calls if someone is typing really fast? I normally set a timeout of 500ms from the start of typing until the search happens. That way you’re not indiscriminately firing calls at the server, which could potentially become a problem with performance both client and server side. Also for security and performance reasons any AJAX call triggered from a user input should be prevented from running if there is one currently busy

I do not think I am using buffering - here is the AJAX script:


<script type="text/javascript">
  function showResult(str)
  {
    if (str.length==0)
    {
      document.getElementById("livesearch").innerHTML="";
      // document.getElementById("livesearch").style.border="0px";
      return;
    }
    if (window.XMLHttpRequest)
    {
      // code for IE7+, Firefox, Chrome, Opera, Safari
      xmlhttp=new XMLHttpRequest();
    }else{  // code for IE6, IE5
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange=function() {
      if (xmlhttp.readyState==4 && xmlhttp.status==200)
      {
        document.getElementById("livesearch").innerHTML=xmlhttp.responseText;
        // document.getElementById("livesearch").style.border="1px solid #A5ACB2";
      }
    }
    xmlhttp.open("GET","_dbResults.php?q="+str,true);
    xmlhttp.send();
  }// endfunc ShowResults
</script>

I am curious to know if all the script is necessary or used because of old browsers.

I tested on your page and you aren’t indeed. Let me get home and refer to my code and post an example of how to go about it

1 Like

Hi @John_Betong I have come up with this snippet. That’s how I would buffer a user key input so that it doesn’t become too much of a resource overkill. If there is anything not clear please let me know and I’ll explain.
As for the AJAX request… I think just IE8 and below need ActiveXObject(“Microsoft.XMLHTTP”); but not entirely sure right now.
Hope that helps.

var liveSearch = function(inputID) {
	this.input = document.getElementById(inputID);	
	if (this.input) {
		this.initialise();
	}
}
liveSearch.prototype = {
	initialise: function() 
	{
		this.previousSearch = null;
		this.canSearch = 1;
		this.input.addEventListener("keyup", this.onKeyUp.bind(this));
	},
	onKeyUp : function() 
	{
		if (this.canSearch) {
			this.canSearch = 0;
			setTimeout(function(){
				var value = this.input.value.toLowerCase();
				if (value != this.previousSearch) {
					this.doSearch(value);
				}		
				this.previousSearch = value;
				this.canSearch = 1;
			}.bind(this), 500);			
		}
	},
	doSearch : function(value)
	{
		// do your ajax call here
	}
}

new liveSearch("myInput");

Unfortunately I could not get the script to work :slight_smile:

I tried inserting // do your ajax call here (without the script tags) and errors were shown. I also tried numerous other scripts all without success. I think the problem is how the function showResult(str) was inserted. Looks like a syntax error and I am not familiar with JavaScript syntax when chaining functions.

JavaScript without buffer

JavaScript with buffer NOW WORKING OK

The difference between the two links is the second has a ?andres URL parameter and uses PHP to include the selected JavaScript file.

Hi John, let’s try this:
First off remove the onkeyup = "showResult(this.value)" from the input as I’m already adding an event listener in the initialise method. Then add any id you want to the input and make sure you pass it in in this call var myLiveSearch = new liveSearch("yourInputId");
Then, as it shows below, remove the wrapping “showResult” function from “doSearch” method. Hope this gets you there, if not please ask.

var liveSearch = function(inputID) {
	this.input = document.getElementById(inputID);
	if (this.input) {
		this.initialise();
	}
}
liveSearch.prototype = {
	initialise: function()
	{
		this.previousSearch = null;
		this.canSearch = 1;
		this.input.addEventListener("keyup", this.onKeyUp.bind(this));
	},
	onKeyUp : function()
	{
		if (this.canSearch) {
			this.canSearch = 0;
			setTimeout(function(){
				var value = this.input.value.toLowerCase();
				if (value != this.previousSearch) {
					this.doSearch(value);
				}
				this.previousSearch = value;
				this.canSearch = 1;
			}.bind(this), 500);
		}
	},
	doSearch : function(str)
	{
		// do your ajax call here ============================================
	    if (str.length==0)
	    {
	      document.getElementById("livesearch").innerHTML="";
	      // document.getElementById("livesearch").style.border="0px";
	      return;
	    }
	    if (window.XMLHttpRequest)
	    {
	      // code for IE7+, Firefox, Chrome, Opera, Safari
	      xmlhttp=new XMLHttpRequest();
	    }else{  // code for IE6, IE5
	      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
	    }
	    xmlhttp.onreadystatechange=function() {
	      if (xmlhttp.readyState==4 && xmlhttp.status==200)
	      {
	        document.getElementById("livesearch").innerHTML=xmlhttp.responseText;
	        // document.getElementById("livesearch").style.border="1px solid #A5ACB2";
	      }
	    }
	    xmlhttp.open("GET","_dbResults.php?q="+str,true);
	    xmlhttp.send();
		// do your ajax call here ============================================
	}
}

var myLiveSearch = new liveSearch("yourInputId");
1 Like

SUCCESS

Edit:
Many thanks for the modified script:

  1. JavaScript set matching id ** new liveSearch(“bufferedInput”);**
  2. added id = “bufferedInput” to input text
  3. used following PHP to select the correct parameters to <input ... />
        <input
          id    = "bufferedInput"
          type  = "text"
          size  = "30"
          name  = "search"
          class = "fs2"
          value = ""
          <?php
            # IF AND ONLY IF ISSET($_GET['andres'])
              $onKeyUp = 'onkeyup = "showResult(this.value)"';
              $andres  = $_GET['andres'] ?? $onKll I need now is a vast amount of traffic eyUp;
              echo  $andres;
          ?>
        />

Both versions now work a treat, and now ready for when I get a vast amount of traffic :slight_smile:

1 Like

I’m glad it worked.
It doesn’t hurt to have it anyway. It prevents from queueing up too many requests for a fast typer for example. It will also prevent running redundant searches… Anyways there you have it, enjoy :slight_smile:

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.