tags:

views:

154

answers:

6
+1  Q: 

Loop with 8 times

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;
    });

});
A: 

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...
}
T. Stone
Please correct: this loop will execute nine times.
David Andres
Wrong. This will use the same value of `n` (11) in all of the handlers. See my answer.
SLaks
A: 
$(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
Wrong. This will use the same value of `n` (12) in all of the handlers. See my answer.
SLaks
11, not 12.
SLaks
Do I get to vote you down for getting it wrong in your first comment. :P
Anthony
No, you don't. If you want to lose my downvote, correct your answer.
SLaks
+2  A: 

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.

SLaks
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
That wouldn't help - you'd still have only 1 `n` shared by all 8 handlers.
SLaks
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
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
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
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
A: 

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 Sastry
A: 

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
A: 

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

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

    $('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;
    });



    $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;
    });
}

for (n = 2; n < 10; n++) {
    handleForm(n);
}
SLaks
Thanks you all, I learned a lot from this problem
Mango