charlie
charlie

Reputation: 481

Jquery $.each loop counter

i am running this code when data is typed in a text input:

$("input#search").live("keyup", function(e) {       
        var search_string = $(this).val();
        var i = 0;
        var trHTML = '';
        if(search_string !== '') {
            $.ajax({
                type: "POST",
                dataType: "json",
                url: "/section/search_go",
                data: { query: search_string },
                cache: false,
                success: function(response) {
                    $.each(response, function(i, item) {


                        trHTML += '<tr>';
                        trHTML += '<td>' + item.accountnumber + '</td>';
                        trHTML += '<td>' + item.company + '</td>';
                        trHTML += '<td>' + item.phone + '</td>';
                        trHTML += '<td>' + item.postcode + '</td>';
                        trHTML += '</tr>';
                    });
                    $('#customers').html(trHTML);
                }
            });
            console.log(i);
        }

        /*if(counter === 0 || search_string == '') {
            $('#customers').html('<tr><td colspan="4">No Results</td></tr>');
        }*/
    });

i am trying to get the number of records in the $.each loop but i cannot seem to do that.

i have tried using i which is in the function and i also tried adding a counter variable and for each loop i added counter++ but that still isnt working

Upvotes: 0

Views: 2863

Answers (3)

Ken Bellows
Ken Bellows

Reputation: 6930

The main problem with your approach is that $.ajax() calls are asynchronous[1]. This is a very important part of web development: AJAX requests (and HTTP requests in general) can take a long time (occasionally on the order of 30 seconds or longer), and if your JavaScript code is blocked waiting for it to finish, the whole browser will lock up. (See the linked MDN article article for more details on this.)

What this means for you is that any code that relies on the results from your $.ajax() request must be triggered from within the success callback function that gets run when the HTTP request returns data successfully.

Another comment on your code, unrelated to your question: you're currently making an HTTP request on every single keyup event. This is going to really slow down your page, it can overload your server, and it can cause race conditions and other sorts of bugs if things don't go perfectly (remember that HTTP is somewhat unpredictable). You should debounce your keyup event handler. Use something like Ben Alman's jQuery throttle/debounce plugin [2] to debounce your handler (see example below). (You might want to change it to a keypress event too, though that's not as necessary; the keypress event object just includes some extra info that can sometimes be helpful.)

I would recommend something like this (assuming you've included some jQuery plugin to give you $.debounce()):

$("input#search").live(
    "keypress", // changed keyup to keypress; not necessary, but often preferred
    $.debounce(
        250,    // debounced by 250ms; might want longer, but I wouldn't go any less
        function(e) {
            var search_string = $(this).val(),
                no_results_str = '<tr><td colspan="4">No Results</td></tr>';
            if (search_string === '') {
                $('#customers').html(no_results_str);
            }
            else {
                if(search_string !== '') {
                    $.ajax({
                        type: "POST",
                        dataType: "json",
                        url: "/section/search_go",
                        data: { query: search_string },
                        cache: false,
                        success: function(response) {
                            console.log('Got '+response.length+' results');
                            if(response.length === 0) {
                                $('#customers').html(no_results_str);
                            }
                            else {
                                var trHTML = '';
                                $.each(response, function(i, item) {

                                    trHTML += '<tr>';
                                    trHTML += '<td>' + item.accountnumber + '</td>';
                                    trHTML += '<td>' + item.company + '</td>';
                                    trHTML += '<td>' + item.phone + '</td>';
                                    trHTML += '<td>' + item.postcode + '</td>';
                                    trHTML += '</tr>';
                                });
                                $('#customers').html(trHTML);
                            }
                        }
                    });
                }
            }
        }
    )
);

Links:

  1. https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests
  2. http://benalman.com/projects/jquery-throttle-debounce-plugin/

Upvotes: 0

Raja Sekar
Raja Sekar

Reputation: 2130

I hope if you need to get number of times loops run,

Simply do response.length. both will be same.

$("input#search").live("keyup", function(e) {       
        var search_string = $(this).val();
        var resultLength;   //Declare variable
        var i = 0;
        var trHTML = '';
        if(search_string !== '') {
            $.ajax({
                type: "POST",
                dataType: "json",
                url: "/section/search_go",
                data: { query: search_string },
                cache: false,
                success: function(response) {
                    resultLength = response.length;  //assign the length
                    $.each(response, function(i, item) {


                        trHTML += '<tr>';
                        trHTML += '<td>' + item.accountnumber + '</td>';
                        trHTML += '<td>' + item.company + '</td>';
                        trHTML += '<td>' + item.phone + '</td>';
                        trHTML += '<td>' + item.postcode + '</td>';
                        trHTML += '</tr>';
                    });
                    $('#customers').html(trHTML);
                }
            });
            console.log(i);
        }

        /*if(resultLength === 0 || search_string == '') {  //access here
            $('#customers').html('<tr><td colspan="4">No Results</td></tr>');
        }*/
    });

Upvotes: 2

sharma sk
sharma sk

Reputation: 651

console.log(i) must be inside of each function.

success: function(response) {
                $.each(response, function(i, item) {


                    trHTML += '<tr>';
                    trHTML += '<td>' + item.accountnumber + '</td>';
                    trHTML += '<td>' + item.company + '</td>';
                    trHTML += '<td>' + item.phone + '</td>';
                    trHTML += '<td>' + item.postcode + '</td>';
                    trHTML += '</tr>';
                    console.log(i);  // this "i" from here function(i, item)
                });

Upvotes: 0

Related Questions