views:

843

answers:

4

I have a textbox that for each time a user inputs a letter I make a search with an ajax request and show the result "live" for the user. Often when a user types the letters it takes longer time for the request to be made than for the user to input a new letter, hence a new request is made before the first one have ended. It would be much better if the first one could end before I do the next request. Is there a good way to only make a new request if the latest request have ended?

This is my jquery code:

$("#MyTextBox").change(function() {
    if (this.value.length > 2) {
        $.ajax({
            type: "GET",
            url: "http://www.domain.com/Service.svc/Search?keyword=" + this.value,
            dataType: "json",
            success: function(data) {
                //here I have some code that shows the result for the user
            }
        });
    }
});
A: 

You can utilize ajaxComplete so that you know when a request has finished before making a new request.

You can combine this with bind/unbind so that the change event is added once manually, then unbound when an ajax request starts, and rebound when the ajax request finishes.

Tegeril
+3  A: 

You could create a boolean that will hold true or false depending on if there is a request already happening. Set it to true when you start a request and set it back to false in your callback function.

var request_in_process = false;
$("#MyTextBox").change(function() {
    if (this.value.length > 2 && !request_in_process) {
        request_in_process = true;
        $.ajax({
            type: "GET",
            url: "http://www.domain.com/Service.svc/Search?keyword=" + this.value,
            dataType: "json",
            success: function(data) {
                request_in_process = false;
                //here I have some code that shows the result for the user
            }
        });
    }
});
dl
Thanks! This was exactly what I was looking for. But for some reason when typing in my text it seems like everytime I enter a letter it's a little buggy and each letter shows up with a kind of delay. The ajax request should be sent async so it shouldn't affect the textbox should it?
Martin
+3  A: 

You can abort an AJAX request. Keep track of the request as a variable, and abort it before re-initiating the request.

var request = $.ajax({ ... });
request.abort();

This has the added advantage of being more responsive to user input. If the user has typed something more since the first request was initiated, he probably doesn't care about the first set of results anymore. Aborting and recreating the AJAX request means the user gets a better set of results back.

ceejayoz
A: 

As ceejayoz already mentioned, you should abort the previous request. (Waiting for the request will make the users mad if they can't type as they want. And prefering the older requests over the newer ones makes the results outdated.) So what about:

var request = null;
//...       
$("#MyTextBox").change(function() {
    if (this.value.length > 2) {
        if (request && request.abort)
            request.abort();
        request = $.ajax({
            type: "GET",
            url: "http://www.domain.com/Service.svc/Search?keyword=" + this.value,
            dataType: "json",
            success: function(data) {
            //here I have some code that shows the result for the user
            request = null;                
        });
    }             
});
ytg