views:

536

answers:

5

So I'm sorry the title is so vague I'm not really even sure how to word this question in just a few words.

So I have a form for adding items to a webstore. Within that form is the option to add different varieties of a product, say different sizes or colors for clothing, etc...

I wanted to only offer a field for the first variety onload, then have an 'add' button to display an additional field for each further desired variety.

After you click the add button, the old add button becomes a subtract button, and a new input field as well as a new add button are appended to the previous.

I'd like this process to work continuously.

When adding the first new field, the process works perfectly, however, adding additional elements do not work as expected. The new fields are added as well as new add buttons, however the old add buttons are not converted to subtract buttons. I'm really not sure what the issue is here. I'm not exactly a jquery wizard.

Here's the relevant part of the form:

<label for="varieties">Varieties</label><input type="text" name="varieties[]" id="varieties1" value="Default" /> <a href="#" class="add-variety"><img src="../img/plus.png" alt="Add" title="Add Another Variety" /></a><br />

And here's the jquery that i've written:

    $('a.add-variety').click(function() {
 $(this).removeClass('add-variety');
 $(this).addClass('subtract-variety');
 $(this).append('<br /><input type="text" name="varieties[]" value="Default" /> <a href="#" class="add-variety"><img src="../img/plus.png" alt="Add" title="Add Another Variety" /></a>');
 $(this).children('img').attr('src','../img/minus.png');
 return false;
});

Thanks so much for any help!

A: 

Sorry I don't have an anwer to your question yet, but have a query that bugs me...

Wouldn't it make more sense to 'prepend' a subtract button? So your code will be:

$('a.add-variety').click(function() {
$(this).prepend('<input type="text" name="varieties[]" value="Default" /> <a href="#" class="subtract-variety"><img src="../img/minus.png" alt="Reomve" title="Remove a Variety" /></a><br/>');

});

And I don't think you are ment to 'return' anything in this jQuery block.

rockacola
actually, prepend gives me the same problem. because I'm targetting the anchor tag, prepend just inserts it before the image rather than after but still within the anchor tag. I need it to be outside the anchor. Turns out there's a nifty and conveniently named function called after(). hah. This fixes the problem with inserting it within the anchor tag. However, it still only works once. not repeatedly.
seventeen
A: 

Actually, I see now that the append() is dropping the new html INSIDE the <a> tag. And there's my problem. Anyone know how I can force jquery to drop the new html after the </a>..?

seventeen
A: 

$(this).append says to append something to the CONTENT of the current element (in this case, the ).

$(this).after may be what you're looking for...

Additionally, new elements added to the dom will not have click handlers, so you'll have to apply the click handler code to the new elements as well.

JBristow
A: 

To answer your 2nd question:

You can perform manipulation on 'parent' level:

$('a.add-variety').parent().click(function() {
    ...
});
rockacola
+4  A: 

Your "add variety" function is only bound to ".add-variety" element once, when the page is loaded. Any newly created "add variety" buttons don't get any code bound to them, since they are created after the page has loaded. You might want to use the live function instead of click.

Another problem, as you pointed out, is that you are appending additional lines inside your a element instead of afterward.

I'd recommend wrapping the whole thing in a div tag to give you easy access to each line. This will allow you to remove some duplicate code by copying the HTML of an existing line, instead of including it again in your JavaScript code.

Here's my proposed version:

<div>
     <label for="varieties">Varieties</label><input type="text" name="varieties[]" id="varieties1" value="Default" /> <a href="#" class="add-variety"><img src="../img/plus.png" alt="Add" title="Add Another Variety" /></a><br />
</div>

And jQuery:

$(function() {
    $('a.add-variety').live('click', function() {
        $(this).removeClass('add-variety');
        $(this).addClass('subtract-variety');

        var parent = $(this).parent();
        parent.after($('<div />').html(parent.html()));

        $('img', this).attr('src','../img/minus.png');
    });
});

I've used $(string, element) instead of children to get access to the sub-image - I'm not sure if this will help with the minus-image problem, but I've found this form seems to work a bit better, since it includes all matching sub-elements of an element, not just immediate children.

Tobias Cohen
thanks so much!
seventeen
wow this was exactly the same problem I was having and using live() worked perfectly!
justinl