Search code examples
javascriptjqueryhtmlclone

Add/Remove button not working on duplicated form fields - jquery


I have used the code from the following answer: jquery clone form fields and increment id to created a clone-able area of my form and all is working well except for the "Add another" and "Remove row" button.

Only the original clone-able areas Add / Remove buttons work so the next cloned area's add / remove buttons don't do anything meaning you have use the first row's which is confusing.

I really can't see what is going on. Any help would be greatly appreciated!

The HTML:

<div id="previous-jobs">
<div class="panel-group" id="accordion">
    <div id="clonedInput1" class="clonedInput panel panel-default">
        <div class="panel-heading clearfix">
            <h4 class="panel-title pull-left">
                <a class="heading-reference accordion-toggle" data-toggle="collapse" data-parent="#accordion" href="#collapse1">
                    Entry #1
                </a>
            </h4>
            <div id="action-buttons" class="pull-right">
                <button type="button" class="btn btn-success clone">Add another</button>
                <button type="button" class="btn btn-danger remove">Delete Row</button>
            </div>
        </div>
        <div id="collapse1" class="input-panel panel-collapse collapse">
            <div class="panel-body">
                <div class="row">
                    <div class="form-group col-sm-6">
                        <label class="p-date-from-title input-title" for="p-date-from">Date From</label>
                        <input type="text" class="ci-df form-control" id="p-date-from1" name="p-date-from" value="[[+!fi.p-date-from]]" placeholder="Date from">
                    </div>
                    <div class="form-group col-sm-6">
                        <label class="p-date-to-title input-title"  for="p-date-to">Date To</label>
                        <input type="text" class="ci-dt form-control" id="p-date-to1" name="p-date-to" value="[[+!fi.p-date-to]]" placeholder="Date to">
                    </div>
                </div>
                <div class="form-group">
                    <label class="p-employer-title input-title"  for="p-employer">Employer</label>
                    <input type="text" class="ci-em form-control" id="p-employer1" name="p-employer" value="[[+!fi.p-employer]]" placeholder="Employer">
                </div>
                <div class="form-group">
                    <label class="p-position-title input-title"  for="p-position">Position</label>
                    <input type="text" class="ci-po form-control" id="p-position1" name="p-position" value="[[+!fi.p-position]]" placeholder="Position">
                </div>
                <div class="form-group">
                    <label class="p-salary-title input-title"  for="p-salary">Salary</label>
                    <input type="text" class="ci-sa form-control" id="p-salary1" name="p-salary" value="[[+!fi.p-salary]]" placeholder="Salary">
                </div>
                <div class="form-group">
                    <label class="p-full-part-time-title input-title"  for="p-full-part-time">Full/Part Time</label>
                    <select class="ci-fpt form-control" id="p-full-part-time1" name="p-full-part-time" value="[[+!fi.p-full-part-time]]">
                        <option value="Full Time">Full Time</option>
                        <option value="Part Time">Part Time</option>
                    </select>
                </div>
                <div class="form-group">
                    <label class="p-leaving-reason-title input-title"  for="p-leaving-reason">Reason for Leaving</label>
                    <input type="text" class="ci-rfl form-control" id="p-leaving-reason1" name="p-leaving-reason" value="[[+!fi.p-leaving-reason]]" placeholder="Reason for leaving">
                </div>
            </div>
        </div>
    </div>
</div>

The jQuery:

var regex = /^(.*)(\d)+$/i;
var cloneIndex = $(".clonedInput").length;

$("button.clone").click(function(){
cloneIndex++;
$(this).parents(".clonedInput").clone()
    .appendTo("#accordion")
    .attr("id", "clonedInput" +  cloneIndex)
        .find("*").each(function() {
        var id = this.id || "";
        var match = id.match(regex) || [];
        if (match.length == 3) {
                this.id = match[1] + (cloneIndex);
                this.name = match[1] + (cloneIndex);
    }
    $(this).find('.heading-reference').attr("href", "#collapse" + cloneIndex).html('Entry #' + cloneIndex);
    });
});

$("button.remove").click(function(){
    $(this).parents(".clonedInput").remove();
});

Solution

  • For dynamically added elements, use .on() jQuery documentation .on() (For jQuery 1.7 and above)

    In the example you posted, they used .live() which is for jQuery 1.7 and below.

    Add this outside of any $(document).ready() function:

    $(document).on('click', 'button.clone', function(){
        ...
    });
    

    By doing this, the event handler gets added to the document so any time an event bubbles up to it that originated from a button.clone element, it will trigger that function. So when buttons get added after the page is loaded, they will still trigger the click event, even when they weren't available when the page initially loaded.

    If you just use $('button.clone').click(...) only the buttons that are on the page when it is first loaded will trigger the click event.