scottM
scottM

Reputation: 468

Allow the user to add form input fields: Why is append() only working once?

I'm trying to create an order form that has an "add new product" section within a table. Basically the user should be able to click on the "Add Row" link and a new input line will appear to allow the user to add another product to the order list. I'm able to have this work once, but after that the form won't add any new lines. In the console.log I can see that the event handler is only working on the original form element, not the new product input line. I have a shortened fiddle of what I'm working with here:

http://jsfiddle.net/scottm1164/eTBr6/5/

Here is my jQuery:

<script>
 $(document).ready(function () {
    (function () {
        var start = $('table'),
            newRow = $('<tr><td><input type="text" class="quantity" /></td><td><input type="text" class="prodNum" /></td><td><textarea cols="15" rows="1"></textarea></td><td><p class="addRow">Add a Row</p></td></tr>');
        $('.addRow').on('click', function () {
            $(start).append(newRow);
            console.log(this);
        });

    })(); //end SIAF

}); //END document ready
</script>

Here is my Form:

<form enctype="multipart/form-data" method="post" action="#" id="orderForm">
    <ul>
        <li>Name:
            <br>
            <input type="text" id="name" />
        </li>
        <li>Email:
            <br>
            <input type="email" id="email" />
        </li>
        <li>Company:
            <br>
            <input type="text" id="company" />
        </li>
        <li>Phone:
            <br>
            <input type="tel" id="phone" />
        </li>
        <li>Delivery Address:
            <br>
            <input type="text" id="delAddress" />
        </li>
        <li>PO Number:
            <br>
            <input type="text" id="poNum" />
        </li>
        <li>If you have a document for your order, attach it here:
            <br>
            <input type="file" id="docs" />
        </li>
        <li>
            <table id="prodTable" width="auto" border="0" cellpadding="4" cellspacing="4">
                <tbody>
                    <tr>
                        <td>Quantity</td>
                        <td>Product Number</td>
                        <td>Product Description</td>
                        <td>&nbsp;</td>
                    </tr>
                    <tr>
                        <td>
                            <input type="text" class="quantity" name="quantity_" />
                        </td>
                        <td>
                            <input type="text" class="prodNum" name="prodNum_" />
                        </td>
                        <td>
                            <textarea cols="15" rows="1" name="prodDesc_"></textarea>
                        </td>
                        <td>
                            <p class="addRow">Add a Row</p>
                        </td>
                    </tr>
                </tbody>
            </table>
        </li>
        <li>Special Delivery Instructions:
            <br>
            <textarea cols="30" rows="10" id="instructions"></textarea>
        </li>  
    </ul>
    <input type="submit" id="submit" />
</form>

Can somebody explain to me what is going wrong with this code, I'm fairly new to jQuery/Javascript so I just don't understand why the code only works once, but not after subsequent clicks to the "add a row" link, and only on the original "add a row" links but not on the newly created link.

Upvotes: 0

Views: 2253

Answers (4)

Geoff
Geoff

Reputation: 1

http://jsfiddle.net/LK5sj/ stick your newrow inside the function and make the function recursive, and don't forget to clear and reassign the event handler or you'll get way more new rows than you want

var start = $('table');

function addRow(){    
    newRow = $('<tr><td><input type="text" class="quantity" /></td><td><input type="text" class="prodNum" /></td><td><textarea cols="15" rows="1"></textarea></td><td><p class="addRow">Add a Row</p></td></tr>');
    $(start).append(newRow);
    $('.addRow').off('click');
    $('.addRow').on('click', function() {
        addRow();
    });
}

$('.addRow').on('click', function() {
    addRow();
});

Upvotes: 0

Jonathan Marzullo
Jonathan Marzullo

Reputation: 7031

Try this

http://jsfiddle.net/eTBr6/8/

$('form').on('click', '.addRow', function () {
    var start = $('table'),
        newRow = $('<tr><td><input type="text" class="quantity" /></td>' +
                   '<td><input type="text" class="prodNum" /></td>' +
                   '<td><textarea cols="15" rows="1"></textarea></td>' +
                   '<td><p class="addRow">Add a Row</p></td></tr>');
    $(start).append(newRow);
});

Put variables inside the click handler and also use event delegation by having the form as your context

Upvotes: 3

Jaime Torres
Jaime Torres

Reputation: 10515

I did something similar to johnathan, just not as quickly.

Fiddle here: http://jsfiddle.net/xCNqP/1/

(function () {

        var start = $('table'),
            newRow = '<tr><td><input type="text" class="quantity" /></td><td><input type="text" class="prodNum" /></td><td><input type="text" maxlength="15"/></td><td><p class="addRow">Add a Row</p></td></tr>';


        $(document).on('click', '.addRow', function () {
            $(start).append($(newRow));
        });

    })(); //end SIAF

Primary change I used was set newRow to just a string, since declaring the element will allow you to only append it once. Re-declaring (which jonathan did by moving the declaration inside the handler) is required to re-append.

The correct usage of on so it will attach to new elements was also included.

Upvotes: 0

SarathSprakash
SarathSprakash

Reputation: 4624

Working DEMO

I guess this is what you need. For dynamically loaded elements a delegate $(document).on() is necessary than a normal function(), since normal event work only on page load.

here is the code

$(document).ready(function () {

    var start = $('table'),
        newRow = '<tr><td><input type="text" class="quantity" /></td><td><input type="text" class="prodNum" /></td><td><textarea cols="15" rows="1"></textarea></td><td><p class="addRow">Add a Row</p></td></tr>';


    $(document).on('click', '.addRow', function () {
        $(start).append(newRow);
    });
}); //end document.ready

Hope this helps, Thank you

Upvotes: 1

Related Questions