Throttling an ajax livesearch function
Asked Answered
G

2

2

I would like to throttle the following ajax live search function I wrote.

I made it so that requests are only sent if a minimum of 2 characters are entered. I also want to throttle the ajax for a quarter of a second to give the user a chance to type what they want. I wrapped the ajax in a setTimeout function, but that didn't work.

        $('#search').keyup(function() {
            var string = $(this).val();
            if (string.length >= 2) {
                $.ajax({
                    'type': 'GET',
                    dataType: 'html',
                    'url': url,
                    'success': function(data){
                                    // show the search data
                    }
                });                                             
            } else if (string.length <= 1) {
                        // restore page content as of when it was loaded
            }
        });

Another thing I should ask, I should probably cache the results of the ajax, no?

Guyette answered 6/8, 2011 at 3:7 Comment(3)
I see no setTimeout in your code.Tael
I took it out since it was causing an error.Guyette
It's hard for us to tell you why it was causing an error if we can't see what you did.Tael
E
1

Just the code inside if (string.length >= 2) :

var elem = $(this);
// save newest search
elem.data('search',search)
// clear pending searches
.clearQueue().stop()
// waits
.delay(250)
// runs search
.queue(function() {
    $.ajax({
        'type': 'GET',
        dataType: 'html',
        'url': url,
        'success': function(data){

        // check if can be run
        if(elem.data('search') != search)
            return;

                // show the search data
        }
    });
});
Extricate answered 6/8, 2011 at 3:20 Comment(8)
thank you. It's a start. It seems to work for the first request, but subsequent ones do not appear to be affect. For example, if I type call of duty really fast, I end up with three requests when the delay is on 1000... no way it takes me longer than a second between key strokes.Guyette
i forget to add stop(), that shoud fix time issueExtricate
i've added handling of subsequent ajax callsExtricate
I want to accept this, but I tested it's behavior and there is something amiss. The jQuery UI autocomplete uses soemthing similar, although I can't figure out how, but they filter the key strokes so spaces make no difference... Button mashing on this causes a ton of requests... button mashing on there's does nothing, and then suddenly the query gets sent. I'll investigate further.Guyette
works for me - jsfiddle.net/4xLVp. Look at the console log - there is only one execution of inner function after many chars writtenExtricate
I'm going to accept this answer because it does what I intended. But I still believe it's not the best implementation based on my experience with the jQuery UI autocomplete. I'll look into that and report back what I found. Thanks again!Guyette
Here's the one I'm talking about: jqueryui.com/demos/autocomplete It's behavior is noticeably different than the above.Guyette
I guess in the end a setTimeout() clearTimeout() pair of functions around the ajax request did the trick! See this: #6968285 - Thanks for the additional solution.Guyette
G
1

Take a look at the source code for (or consider using) Jquery Autocomplete It does pretty much exactly what you want, it only submits data after a pause to make sure the user is done and it has a cache, amongst other features.

Globate answered 6/8, 2011 at 3:17 Comment(1)
Since you're already using jQuery I would go with this. Otherwise, you need to use setTimeout and clearTimeout to make sure you cancel the setTimeout if a user is still entering data (otherwise setTimeout will always run).Flopeared
E
1

Just the code inside if (string.length >= 2) :

var elem = $(this);
// save newest search
elem.data('search',search)
// clear pending searches
.clearQueue().stop()
// waits
.delay(250)
// runs search
.queue(function() {
    $.ajax({
        'type': 'GET',
        dataType: 'html',
        'url': url,
        'success': function(data){

        // check if can be run
        if(elem.data('search') != search)
            return;

                // show the search data
        }
    });
});
Extricate answered 6/8, 2011 at 3:20 Comment(8)
thank you. It's a start. It seems to work for the first request, but subsequent ones do not appear to be affect. For example, if I type call of duty really fast, I end up with three requests when the delay is on 1000... no way it takes me longer than a second between key strokes.Guyette
i forget to add stop(), that shoud fix time issueExtricate
i've added handling of subsequent ajax callsExtricate
I want to accept this, but I tested it's behavior and there is something amiss. The jQuery UI autocomplete uses soemthing similar, although I can't figure out how, but they filter the key strokes so spaces make no difference... Button mashing on this causes a ton of requests... button mashing on there's does nothing, and then suddenly the query gets sent. I'll investigate further.Guyette
works for me - jsfiddle.net/4xLVp. Look at the console log - there is only one execution of inner function after many chars writtenExtricate
I'm going to accept this answer because it does what I intended. But I still believe it's not the best implementation based on my experience with the jQuery UI autocomplete. I'll look into that and report back what I found. Thanks again!Guyette
Here's the one I'm talking about: jqueryui.com/demos/autocomplete It's behavior is noticeably different than the above.Guyette
I guess in the end a setTimeout() clearTimeout() pair of functions around the ajax request did the trick! See this: #6968285 - Thanks for the additional solution.Guyette

© 2022 - 2024 — McMap. All rights reserved.