SitePoint Sponsor

User Tag List

Results 1 to 9 of 9
  1. #1
    SitePoint Addict JamieJelly's Avatar
    Join Date
    Jan 2004
    Location
    London
    Posts
    226
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    check input field as you type

    hi guys,
    I am trying to come up with a script that takes the input of a user and checks a database as they type, so on keyup, a xmlhttprequest is fired to the server and the input is checked on the fly for duplicates. This bit is fine, but as people type it creates unnecessary requests to the server.

    I want to fire the request off only if there is a delay of 1 second after the keyup event, this would indicate the user has stopped typing.

    Can anyone tell me how I can achieve the firing of the xmlhttprequest ONLY if one second has expired since the keyup event and there have been no further keyup events?

    I hope that makes sense

    thanks
    International calls from the UK
    Cheap International Calls

  2. #2
    Web-coding NINJA! silver trophy beetle's Avatar
    Join Date
    Jul 2002
    Location
    Dallas, TX
    Posts
    2,900
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    something like this?
    HTML Code:
     <html>
     <head>
     	<script type="text/javascript">
     		var AjaxAutoCompleter = function( elem )
     		{
     			var self = this;
     			this.element = elem;
     			this.element.onkeyup = function() { self.triggerLookup() };
     			this.timer = null;
     		}
     
     		AjaxAutoCompleter.prototype.triggerLookup = function()
     		{
     			var self = this;
     			this.abortLookup();
     			this.timer = setTimeout( function() { self.doLookup(); }, 1000 );
     		}
     
     		AjaxAutoCompleter.prototype.abortLookup = function()
     		{
     			clearTimeout( this.timer );
     		}
     
     		AjaxAutoCompleter.prototype.doLookup = function()
     		{
     			// XmlHTTPRequest here
     			window.status += 'Lookup ran! ';
     		}
     
     		onload = function()
     		{
     			new AjaxAutoCompleter( document.getElementById( 'testField' ) );
     		}
     	</script>
     </head>
     <body>
     	<input type="text" name="test" id="testField">
     </body>
     </html>
    Of course, I'd recommend using more abstracted event assignment and maybe node retrieval, but this should do it.
    beetle a.k.a. Peter Bailey
    blogs: php | prophp | security | design | zen | software
    refs: dhtml | gecko | prototype | phpdocs | unicode | charsets
    tools: ide | ftp | regex | ffdev




  3. #3
    SitePoint Addict JamieJelly's Avatar
    Join Date
    Jan 2004
    Location
    London
    Posts
    226
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    thanks Peter, it seems the trouble I am having is that as a user types, if a previous request takes longer to complete than the current one, the results of the previous request overwrite the current.

    In this case I have realised adding the delay doesnt resolve this issue in all cases.

    The AJAX class I'm using is from Sitepoint's new book, and contains an abort method.

    I thought if I call the abort method from my xmlhttprequest function it would abort previous requests but this doesn't seem to be the case. This is the xmlhttprequest function:
    Code:
    function sendQuery() {
    	var search = document.getElementById('search');
    	var qs = '?search=' + search.value;
    	if(xmlhttp)
    	{
    	xmlhttp.abort;
    	}
    	var xmlhttp = new Ajax();
    	xmlhttp.doGet('process.php' + qs, hand)
    }
    Is there anything obvious I am doing wrong?

    thanks
    International calls from the UK
    Cheap International Calls

  4. #4
    Web-coding NINJA! silver trophy beetle's Avatar
    Join Date
    Jul 2002
    Location
    Dallas, TX
    Posts
    2,900
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, to invoke a method you need the parens
    Code:
    xmlhttp.abort();
    maybe that's it?
    beetle a.k.a. Peter Bailey
    blogs: php | prophp | security | design | zen | software
    refs: dhtml | gecko | prototype | phpdocs | unicode | charsets
    tools: ide | ftp | regex | ffdev




  5. #5
    SitePoint Addict JamieJelly's Avatar
    Join Date
    Jan 2004
    Location
    London
    Posts
    226
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    thought as much, and infact tried that first, but it didn't work.

    This is my first real attempt at any sort of javascript app so bear with me please!
    International calls from the UK
    Cheap International Calls

  6. #6
    Web-coding NINJA! silver trophy beetle's Avatar
    Join Date
    Jul 2002
    Location
    Dallas, TX
    Posts
    2,900
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What runs sendQuery()? Is that the function that you call from the doLookup() method I wrote?

    Also, what methods are available on the Ajax object besides abort() and doGet()?
    beetle a.k.a. Peter Bailey
    blogs: php | prophp | security | design | zen | software
    refs: dhtml | gecko | prototype | phpdocs | unicode | charsets
    tools: ide | ftp | regex | ffdev




  7. #7
    SitePoint Addict JamieJelly's Avatar
    Join Date
    Jan 2004
    Location
    London
    Posts
    226
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    thanks for taking the time to look at this Peter, I don't know if I am allowed to post sitepoint's AJAX class here but it can be seen here: http://www.sitepoint.com/article/bui...jax-web-apps/2

    this is my code
    Code:
    function addEvent(elm, evType, fn, useCapture) {
    	 // cross-browser event handling for IE5+, NS6+ and Mozilla/Gecko
    	// By Scott Andrew
    	if (elm.addEventListener) {
    		elm.addEventListener(evType, fn, useCapture);
    		return true;
    	} else if (elm.attachEvent) {
    		var r = elm.attachEvent('on' + evType, fn);
    		return r;
    	} else {
    		elm['on' + evType] = fn;
    	}
    }
    
    function hand(str) {
    	var com = document.getElementById('com');
    	if (com.firstChild) {
    		com.removeChild(com.firstChild);
    	}
    	com.appendChild(document.createTextNode(str));
    }
    
    function sendQuery() {
    	var search = document.getElementById('search');
    	var qs = '?search=' + search.value;
    	if(xmlhttp)
    	{
    	xmlhttp.abort();
    	}
    	var xmlhttp = new Ajax();
    	xmlhttp.doGet('check.php' + qs, hand)
    }
    
    function addListeners() {
    	if (!document.getElementById) return;
    	if (!Ajax) return;
    	var search = document.getElementById('search');
    	addEvent(search, 'keyup', sendQuery, false);
    }
    
    addEvent(window, 'load', addListeners, false);
    International calls from the UK
    Cheap International Calls

  8. #8
    Web-coding NINJA! silver trophy beetle's Avatar
    Join Date
    Jul 2002
    Location
    Dallas, TX
    Posts
    2,900
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Give this a shot (with your specific HTML of course)
    HTML Code:
     <html>
     <head>
    	 <script type="text/javascript">
    		 var AjaxAutoCompleter = function( elem, ajaxObj, responseHandler )
    		 {
    			 var self = this;
    			 this.element = elem;
    			this.ajax = ajaxObj;
    			this.responseHandler = responseHandler;
    			addEvent( this.element, 'keyup', function() { self.triggerLookup() );
    			 this.timer = null;
    		 }
     
    		 AjaxAutoCompleter.prototype.triggerLookup = function()
    		 {
    			 var self = this;
    			 this.abortLookup();
    			 this.timer = setTimeout( function() { self.doLookup(); }, 1000 );
    		 }
     
    		 AjaxAutoCompleter.prototype.abortLookup = function()
    		 {
    			 clearTimeout( this.timer );
    			this.ajax.abort();
    		 }
     
    		 AjaxAutoCompleter.prototype.doLookup = function()
    		 {
    			this.ajax.doGet( 'check.php?search=' + this.element.value, this.responseHandler );
    		 }
    
    		 addEvent( window, 'load', function()
    		 {
    			new AjaxAutoCompleter( document.getElementById( 'search' ), new Ajax(), responseHandler );
    		 }, false );
    
    		function addEvent(elm, evType, fn, useCapture) {
    			 // cross-browser event handling for IE5+, NS6+ and Mozilla/Gecko
    			// By Scott Andrew
    			if (elm.addEventListener) {
    				elm.addEventListener(evType, fn, useCapture);
    				return true;
    			} else if (elm.attachEvent) {
    				var r = elm.attachEvent('on' + evType, fn);
    				return r;
    			} else {
    				elm['on' + evType] = fn;
    			}
    		}
    
    		function responseHandler(str) {
    			var com = document.getElementById('com');
    			if (com.firstChild) {
    				com.removeChild(com.firstChild);
    			}
    			com.appendChild(document.createTextNode(str));
    		}
    
    	 </script>
     </head>
     <body>
    	 <input type="text" name="test" id="search">
     </body>
     </html>
    beetle a.k.a. Peter Bailey
    blogs: php | prophp | security | design | zen | software
    refs: dhtml | gecko | prototype | phpdocs | unicode | charsets
    tools: ide | ftp | regex | ffdev




  9. #9
    SitePoint Addict JamieJelly's Avatar
    Join Date
    Jan 2004
    Location
    London
    Posts
    226
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    that works a treat thanks! If I could give you rep I would
    International calls from the UK
    Cheap International Calls


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •