views:

26

answers:

2

I'm trying to limit inserting elements to the page:

<script type="text/javascript">
    $(function() {

        var i = 1;
//allow only 3 elements
        if (i < 4) {

            $('#add').click(function() {
                var add_input = '<input type="file" />'
                var add_link = '<a href="#" class="remove">Remove</a>'
                $('body').append('<p>' + add_input + add_link + '</p>');
            });

            i++;
        }

        $('.remove').live('click', function() {
            $(this).parent('p').remove();
        });


    });
</script>

But I can still add element a lot more than 4.

+1  A: 

You need to check your variable i within your event handler.

$('#add').click(function() {
    if(i < 4){
       var add_input = '<input type="file" />'
       var add_link = '<a href="#" class="remove">Remove</a>'
       $('body').append('<p>' + add_input + add_link + '</p>');
       i++;
    }
});

And you should decrease i within your live() handler.

See a working example : http://jsfiddle.net/CtGgg/

jAndy
Don't forget `i++;`
J-P
Yep, the if and the i++; need to be moved into the click handler.
Andrew Hedges
This wont work, when I added three elements, then try to add elements again.
Narazana
What *else* are you doing than? It works in this answer example.
Felipe Alsacreations
I need to add i-- when removing element like this also $('.remove').live('click', function() { $(this).parent('p').remove(); if (i > 0) { i--; } });
Narazana
@Morron: please checkout the example link. I guess you're missing the `i--` in your `live code`.
jAndy
A: 

You could count the number of elements already on the page and limit it that way. Personally, I like treating the DOM itself as the canonical representation of user state. If that's important to you, you could do something like the following, even though it's a little less performant:

$('#add').live('click', function (evt) {
    if ($('input[type=file]').length < 4) {
        $('body').append('<p><input type="file"> <a href="#" class="remove">Remove</a></p>');
    }
    evt.preventDefault();
});
Andrew Hedges
why accessing the `DOM` (which you should avoid whenever possible) ?
jAndy
Because it's fast and works. I'm not advocating an expensive manipulation of visible elements, just fetching some references and checking the length.
Andrew Hedges
@Andrew: that check already accesses the `DOM` which is **slow**.
jAndy
@jAndy Thanks for the edumication, but I know it accesses the DOM. My point is that it's *fast* despite that fact. Fast enough to be useful in a practical sense. Fast enough, probably, that you wouldn't even be able to detect that it happened. Premature optimization and all that.
Andrew Hedges
@Andrew: http://www.jsfiddle.net/6URCk/ just to give you an idea how slow the `DOM` is. It's just bad karma to access it for no reason.
jAndy
Wow, I'm really convinced (that's sarcasm). Sure, it took 1/5th of a second...to do the operation 10k times! This is a great example of premature optimization. There are trade-offs in each approach, that's all I'm saying. I've done dozens of tests of these kinds of operations over the years. I'm well aware of how expensive DOM access can be. Still, if you want to know what's in the DOM, in some cases it makes the most sense to ask the DOM!
Andrew Hedges
@Andrew: I can't share that oppinion at all. All I am saying is, don't touch the DOM if you don't need to. In this case, there was no reason to do it. You're saying you are aware of DOM access speeds, so I just don't get it. But whatsoever, I don't want to convince you, I just want to make clear (to any reader) that in general it's best practice to **avoid** access the DOM and especially if it's not worth the effort or completly unnecessary (that's no sarcasm). Cheers!
jAndy