Search code examples
jqueryformscloneform-fields

Duplicating form sections


Hoping someone could help me with this code snippet below. I'm trying to duplicate form fields on my site when a button is clicked.

The problem is, I'm having trouble making this work for multiple forms on the same html page. This is only working for the first form. When I try adding a second form, the button on the second form duplicates the first form within the second form. Any insight is greatly appreciated!

HTML

<div class="duplicate-sections">
 <div class="form-section">
    <fieldset>
      <p>
        <label for="firstName">First Name:</label>
        <input name="firstName[]" id="firstName" value="" type="text" />
      </p>
      <p>
        <label for="lastName">Last Name:</label>
        <input name="lastName[]" id="lastName" value="" type="text" />
      </p>
        <a href="#" class="remove">Remove Section</a>
    </fieldset>
  </div>
</div>

<a href="#" class="addsection">Add Section</a>

Jquery

//define template
var template = $('.duplicate-sections .form-section:first').clone();

//define counter
var sectionsCount = 1;

//add new section
$('body').on('click', '.addsection', function() {

    //increment
    sectionsCount++;

    //loop through each input
    var section = template.clone().find(':input').each(function(){

        //set id to store the updated section number
        var newId = this.id + sectionsCount;

        //update for label
        $(this).prev().attr('for', newId);

        //update id
        this.id = newId;

    }).end()

    //inject new section
    .appendTo('.duplicate-sections');
    return false;
});

//remove section
$('.duplicate-sections').on('click', '.remove', function() {
    //fade out section
    $(this).parent().fadeOut(300, function(){
        //remove parent element (main section)
        $(this).parent().parent().empty();
        return false;
    });
    return false;
});

Solution

  • Working codepen.

    You've to change this part in your remove action :

    $(this).parent().fadeOut(300, function(){
        //remove parent element (main section)
        $(this).parent().parent().empty();
        return false;
    });
    

    To be :

    $(this).closest('.form-section').fadeOut(300, function(){
        $(this).closest('.form-section').empty();
    });
    

    Using the closest() function and specific class form-section to target the parent div. also you've to replace :

    .appendTo('.duplicate-sections');
    

    By :

    .appendTo($(this).prev('.duplicate-sections'));
    

    Since if you leave you slector with just a class duplicate-sections the new form will be appended to all the elements with this class, you have to specify the one related with the clicked href Add Section.

    Last thing to do is adding an extra attribute data-section in every add section link to specify the number of the form (0 based) :

    <a href="#" class="addsection" data-section='0'>Add Section</a>
    

    Then store all the forms in an array :

    var forms = [];
    
    $('.duplicate-sections .form-section').each(function(){
      forms.push($(this).clone());                
    })
    

    And get the related form with clicked link using :

    var template = forms[$(this).data('section')];
    

    Hope this helps.