1

How I do a Loop with 8 times with this entire function?

Only changing the var n

$(document).ready(function(){
    var n=2;                                   
    $forms = $('#form'+n);
    $('#toogle'+n).hide();
    $('#hide'+n).hide();

$('a').bind('click', function(){
        switch(this.id){
            case 'c'+n:
                $('#change'+n).hide();
                $('#phone'+n).hide();
                $('#hide'+n).show();
                $('#toogle'+n).show(); 
                return false;
                break;
             case 'd'+n:
                $('#change'+n).show();
                $('#phone'+n).show();
                $('#hide'+n).hide();
                $('#toogle'+n).hide(); 
                return false;
                break;
        }
    })

    $forms.bind('submit', function(){
        var $button = $('button',this).attr('disabled',true);
        var params = $(this.elements).serialize();

        var self = this;
        $.ajax({
            type: 'POST',
            url: this.action,
            data: params,

        beforeSend: function(){
                $('#phone'+n).show();
                $('#hide'+n).hide();

                $('#phone'+n).html("Loading...");
            },
            success: function(txt){

                $('#top'+n).show();
                $('#cadastro'+n).hide   ();
                $('#hide'+n).hide   ();
                $('#toogle'+n).hide();
                $('#change'+n).show();

                $button.attr('disabled',false);

                $('#phone'+n).html(txt);

                self.reset();
            },

            error: function(txt){
                $('#phone'+n).html(txt);
            }
        })
        return false;
    });

});
Mango
  • 175
  • 9
  • 18
  • Thanks a lot SLaks, could you show this in the code, a tried but didnt work. – Mango Sep 15 '09 at 03:44
  • I just wanted to comment that you shouldn't be using numbers only in your ID -> switch(this.id), maybe put the number into the rel tag instead. – Mottie Sep 15 '09 at 05:45

6 Answers6

2

Move your code to a separate function that takes n as a parameter, then call that function in a loop.

The problem that you probably ran into is that the nested functions use the same n every time they're defined. Therefore, n would be 8 in all of the handlers. By moving the nested functions to a separate function, you create a different closure for each one, solving the problem.

For a more detailed explanation, see this answer.

Community
  • 1
  • 1
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Wouldn't declaring `n` outside of the original for loop fix this too? Don't functions in js handle global variables without them being passed to the function explicitly? – Anthony Sep 15 '09 at 02:18
  • That wouldn't help - you'd still have only 1 `n` shared by all 8 handlers. – SLaks Sep 15 '09 at 02:20
  • I just wrote a really simple script to see what you're getting at, and I'm still seeing what I expected, which is each function is picking up the new value of n on each loop. Is this unique to handlers or how he has nested the functions? Are you saying that each function is only called once out of all of the loops, and thus only get n passed to it once? – Anthony Sep 15 '09 at 02:30
  • He needs each event handler to keep its separate value of `n` after the loop finishes, when the user actually clicks. If you only use `n` during the loop and don't save it for later in an event handler (or timer or other thing), you'd be correct. – SLaks Sep 15 '09 at 02:32
  • Okay, at least now we're on the same page as to our opposing solutions. So you're saying that it doesn't bind to each event that the function runs through? Because if it sets it for `#phone3`, `#phone6`, etc, doesn't that event binding maintain after the loop? I guess you're saying, no... – Anthony Sep 15 '09 at 03:14
  • You don't understand. The binding will be maintained after the loop. However, all of the functions that were bound to the event will share the same value of `n`. Therefore, if you click on #2, it will behave as if you clicked on #11 because `n` will be 11 in all of the handlers. Try writing a function that returns an array of functions that return the numbers 1 - 10, and you'll see what I mean. – SLaks Sep 15 '09 at 11:00
0

Loops that are to be executed a fixed number of times are very well done with a For Loop. W3C for loop reference

It would look something like this...

for (n = 2; n < 10; n++) {
    // your code with 'n' in it here...
}
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
T. Stone
  • 19,209
  • 15
  • 69
  • 97
0

Have you thought about why do you need a loop? Maybe instead of using the id selector, you can use a class selector to select a bunch of elements at once.

<div id="div1" class="thumbnail"></div>
<div id="div2" class="thumbnail"></div>
<div id="div3" class="thumbnail"></div>

jQuery(".thumbnail").doStuff(); //will apply for all 3 divs.
Chetan S
  • 23,637
  • 2
  • 63
  • 78
0

As an aside, instead of adding 8 click handlers to every link in the document, you can do something like this:

$('a#c' + n).click(function() {
    $('#change'+n).hide();
    $('#phone'+n).hide();
    $('#hide'+n).show();
    $('#toogle'+n).show();

    return false;
});
$('a#d' + n).click(function() {
    $('#change'+n).show();
    $('#phone'+n).show();
    $('#hide'+n).hide();
    $('#toogle'+n).hide(); 

    return false;
});

Also, you misspelled toggle.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
0

Here is a complete code sample that incorporates both of my answers.

function handleForm(n) {
    $forms = $('#form'+n);
    $('#toggle'+n).hide();
    $('#hide'+n).hide();

    $('a#c' + n).click(function() {
        $('#change'+n).hide();
        $('#phone'+n).hide();
        $('#hide'+n).show();
        $('#toggle'+n).show();

        return false;
    });
    $('a#d' + n).click(function() {
        $('#change'+n).show();
        $('#phone'+n).show();
        $('#hide'+n).hide();
        $('#toggle'+n).hide(); 

        return false;
    });



    $forms.bind('submit', function(){
        var $button = $('button',this).attr('disabled',true);
        var params = $(this.elements).serialize();

        var self = this;
        $.ajax({
            type: 'POST',
            url: this.action,
            data: params,

            beforeSend: function(){
                $('#phone'+n).show();
                $('#hide'+n).hide();

                $('#phone'+n).html("Loading...");
            },
            success: function(txt){

                $('#top'+n).show();
                $('#cadastro'+n).hide   ();
                $('#hide'+n).hide       ();
                $('#toggle'+n).hide();
                $('#change'+n).show();

                $button.attr('disabled',false);

                $('#phone'+n).html(txt);

                self.reset();
            },

            error: function(txt){
                $('#phone'+n).html(txt);
            }
        });
        return false;
    });
}

for (n = 2; n < 10; n++) {
    handleForm(n);
}
eduardogoncalves
  • 173
  • 3
  • 11
SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
-1
$(document).ready(function(){
    var n = 2;
    for(n = 2; n < 11; n++) {                                                           
    $forms = $('#form'+n);
    $('#toogle'+n).hide();
    $('#hide'+n).hide();

$('a').bind('click', function(){
        switch(this.id){
            case 'c'+n:
                        $('#change'+n).hide();
                        $('#phone'+n).hide();
                        $('#hide'+n).show();
                $('#toogle'+n).show(); 
                return false;
                break;
                 case 'd'+n:
                        $('#change'+n).show();
                        $('#phone'+n).show();
                        $('#hide'+n).hide();
                $('#toogle'+n).hide(); 
                return false;
                break;
        }
    })

    $forms.bind('submit', function(){
        var $button = $('button',this).attr('disabled',true);
        var params = $(this.elements).serialize();

        var self = this;
        $.ajax({
            type: 'POST',
            url: this.action,
            data: params,

        beforeSend: function(){
                $('#phone'+n).show();
                        $('#hide'+n).hide();

                $('#phone'+n).html("Loading...");
            },
            success: function(txt){

                        $('#top'+n).show();
                $('#cadastro'+n).hide   ();
                        $('#hide'+n).hide       ();
                        $('#toogle'+n).hide();
                        $('#change'+n).show();

                        $button.attr('disabled',false);

                $('#phone'+n).html(txt);

                self.reset();
            },

            error: function(txt){
                $('#phone'+n).html(txt);
            }
        })
        return false;
    });
  }   
});

Would be the easiest way to go, but I'd actually recommend adding all of your elements into the DOM in one for loop, and using selectors to take care of the rest of the code.

Anthony
  • 36,459
  • 25
  • 97
  • 163