Dynamically repeat and remove form elements using JQuery

Viewed 1037

I have a form with additional add and remove buttons. Upon clicking these buttons, the same form row is repeated or completely removed.

    <script>
        function addFormElements(current) {
            $(current).parent().parent().append($(current).parent().parent().html());
        }
    
        function removeFormElements(current) {
            $(current).parent().parent().remove();
        }
    </script>
<div class="container">
        <div class="row justify-content-center align-items-center">
            <div class="col-10 col-md-10 col-lg-8">
                <form>
                    <div class="form-row" style="padding-top: 50px;" id="someId">
                        <div class="form-group col-md-4">
                            <select class="selectpicker form-control single-select" placeholder="Select an Option..." required>
                                <option></option>
                                <option>Mustard</option>
                                <option>Ketchup</option>
                                <option>Barbecue</option>
                            </select>
                        </div>
                        <div class="form-group col-md-6">
                            <input type="password" class="form-control" placeholder="">
                        </div>
                        <div class="form-group col-md-1">
                            <button type="button" class="btn btn-success" onclick="addFormElements(this)">+</button>
                        </div>
                        <div class="form-group col-md-1">
                            <button type="button" class="btn btn-danger" onclick="removeFormElements(this)">-</button>
                        </div>
                    </div>
    
                    <div class="form-row" style="padding-top: 50px;">
                        <button type="button" class="btn btn-primary">
                            Submit
                        </button>
                    </div>
                </form>
            </div>
        </div>
    </div>

You can check out the demo for the same here at JSFiddle

Problem 1: Adding rows

When, I click on the + button for the first time, it adds one row. enter image description here

The above becomes this:

enter image description here

However, if I add click on the + button one more time, then 2 rows are added. After that 4 rows are added and so on.

enter image description here

Problem 2: Deleting rows

Similarly, on clicking the - button, the entire row is deleted. It should ideally only the current row.

I think I am missing something pretty basic here (about figuring out paths), but am not able to get it running even after multiple attempts. Can someone please have a look.

1 Answers

It is because you need to clone the elements, if not you will keep the same pointer and thus deleting one will result in deleting the whole list. This solution mantains your style:

function addFormElements(current) {
    $(current).parents('.form-list').append($(current).parents('.form-row').clone())
}

function removeFormElements(current) {
    $(current).parents('.form-row').remove();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
    <div class="row justify-content-center align-items-center">
        <div class="col-10 col-md-10 col-lg-8">
            <form>
               <div class="form-list">
                <div class="form-row" style="padding-top: 50px;" id="someId">
                    <div class="form-group col-md-4">
                        <select class="selectpicker form-control single-select" placeholder="Select an Option..." required>
                            <option></option>
                            <option>Mustard</option>
                            <option>Ketchup</option>
                            <option>Barbecue</option>
                        </select>
                    </div>
                    <div class="form-group col-md-6">
                        <input type="password" class="form-control" placeholder="">
                    </div>
                    <div class="form-group col-md-1">
                        <button type="button" class="btn btn-success" onclick="addFormElements(this)">Add</button>
                    </div>
                    <div class="form-group col-md-1">
                        <button type="button" class="btn btn-danger" onclick="removeFormElements(this)">Remove</button>
                    </div>
                </div>
                </div>
                <div class="form-row" style="padding-top: 50px;">
                    <button type="button" class="btn btn-primary">
                        Submit
                    </button>
                </div>
            </form>
        </div>
    </div>
</div>

An improved solution would use passive event listener, to split HTML and JS, and will probably use a separate template to clone (in your solution, writing in one element and then clicking on add will result in two items with the same content).

function addFormElements() {
    $('.form-list').append($("#form-template .form-row").clone())
}

function removeFormElements() {
    $(this).parents('.form-row').remove();
}

$(document).ready(addFormElements); 
$(document).on("click", ".add-btn", addFormElements);
$(document).on("click", ".remove-btn", removeFormElements);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
    <div class="row justify-content-center align-items-center">
        <div class="col-10 col-md-10 col-lg-8">
            <form>
               <div class="form-list">
                
                </div>
                <div class="form-row" style="padding-top: 50px;">
                    <button type="button" class="btn btn-primary">
                        Submit
                    </button>
                </div>
            </form>
        </div>
    </div>
    
    
    <div id="form-template" style="display: none"> 
      <div class="form-row" style="padding-top: 50px;">
        <div class="form-group col-md-4">
            <select class="selectpicker form-control single-select" placeholder="Select an Option..." required>
                <option></option>
                <option>Mustard</option>
                <option>Ketchup</option>
                <option>Barbecue</option>
            </select>
        </div>
        <div class="form-group col-md-6">
            <input type="password" class="form-control" placeholder="">
        </div>
        <div class="form-group col-md-1">
            <button type="button" class="btn btn-success add-btn">Add</button>
        </div>
        <div class="form-group col-md-1">
            <button type="button" class="btn btn-danger remove-btn">Remove</button>
        </div>
    </div>
  </div>
    
</div>

Related