I'm relatively new to Javascript/jQuery and I'm trying to clone a form to record scores. I can add as many input as I want to the pre-cloned form but I can't add, nor remove, any additional text inputs in the subsequent cloned forms.
Let's say before I add a pre-requisite, I placed in 5 input boxes. In that first form, I can remove and add as many input boxes as I want.
Now let's say I add a prequisite, it will clone the first form, but in the cloned form I cannot add nor remove any of the input boxes. That is my issue.
At this point I am stumped on how to fix this.
$(document).ready(function() {
var max_fields = 10;
var wrapper = $(".form-input");
var add_button = $(".add_item");
var x = 1;
$(add_button).click(function(e) {
e.preventDefault();
if (x < max_fields) { //max input box allowed
x++; //text box increment
$(wrapper).append('<div><input type="text" name="items[]"/><a href="#" class="remove_field">X</a></div>'); //add input box
}
});
$(wrapper).on("click", ".remove_field", function(e) { //user click on remove text
e.preventDefault();
$(this).parent('div').remove();
x--;
})
});
//Write code to clone form here, but set everything to default and add
//a button to remove any prerequisites.
$(document).ready(function() {
var ctr = 1;
$(".add_req").click(function() {
$(".myForm").eq(0)
.clone()
.find("input")
.val("")
.end()
.show()
.insertAfter(".myForm:last");
});
$('.all').on('click', ".remove-req", function() {
$(this).closest('.myForm').remove();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="all">
<button class="add_req">Add Preq-Requisite</button>
<form class="myForm">
<section class="selection-menus">
<select name="major" class="major">
<option selected="selected">SELECT MAJOR</option>
<option value="CS">Computer Science</option>
<option value="CIS">Computer Information Systems</option>
</select>
<select name="course-no" class="course-no">
<option value="CS_000">SELECT COURSE</option>
<option value="CS_140">140</option>
<option value="CS_210">210</option>
<option value="CS_220">220</option>
<!--THERE IS NO CIS DATA, THIS IS JUST FOR FUNCTIONALITY-->
<option value="CIS_000">SELECT COURSE</option>
<option value="CIS_315">315</option>
<option value="CIS_330">330</option>
<option value="CIS_497">497</option>
</select>
<button class="add_item">Add Item</button>
</section>
<div class="form-input">
<div><input type="text" name="items[]"></div>
</div>
<span class="remove-req">Remove Req</span>
</form>
</div>
</body>
It has to do with the way you select your wrapper
element.
When the page loads you get the wrapper
element with $(".form-input");
. This means you have now selected the elements with the .form-input
class that are currently on the page. This works fine.
However, from here you clone your form and create a second element with the .form-input
, that comes from the original form. But the difference here is that the wrapper
variable never found this second .form-input
because it didn't exist yet. Same will count for all consequent .form-input
elements.
A fix for this is to change the event listener for .remove_field
. Instead of listening to only the first wrapper
, listen on the document
for the click
. All clicks eventually bubble to the document, unless they're intercepted and stopped.
$(document).ready(function() {
var max_fields = 10;
var wrapper = $(".form-input");
var add_button = $(".add_item");
var x = 1;
$(document).on('click', '.add_item', function(e) {
e.preventDefault();
var $this = $(this);
var $formInput = $this.parent().next();
if (x < max_fields) { //max input box allowed
x++; //text box increment
$formInput.append('<div><input type="text" name="items[]"/><a href="#" class="remove_field">X</a></div>'); //add input box
}
});
$(document).on("click", ".remove_field", function(e) { //user click on remove text
e.preventDefault();
$(this).parent('div').remove();
x--;
})
});
//Write code to clone form here, but set everything to default and add
//a button to remove any prerequisites.
$(document).ready(function() {
var ctr = 1;
$(".add_req").click(function() {
$(".myForm").eq(0)
.clone()
.find("input")
.val("")
.end()
.show()
.insertAfter(".myForm:last");
});
$('.all').on('click', ".remove-req", function() {
$(this).closest('.myForm').remove();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<head>
<meta charset=utf-8 />
<title>JS Bin</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="all">
<button class="add_req">Add Preq-Requisite</button>
<form class="myForm">
<section class="selection-menus">
<select name="major" class="major">
<option selected="selected">SELECT MAJOR</option>
<option value="CS">Computer Science</option>
<option value="CIS">Computer Information Systems</option>
</select>
<select name="course-no" class="course-no">
<option value="CS_000">SELECT COURSE</option>
<option value="CS_140">140</option>
<option value="CS_210">210</option>
<option value="CS_220">220</option>
<!--THERE IS NO CIS DATA, THIS IS JUST FOR FUNCTIONALITY-->
<option value="CIS_000">SELECT COURSE</option>
<option value="CIS_315">315</option>
<option value="CIS_330">330</option>
<option value="CIS_497">497</option>
</select>
<button class="add_item">Add Item</button>
</section>
<div class="form-input">
<div><input type="text" name="items[]"></div>
</div>
<span class="remove-req">Remove Req</span>
</form>
</div>
</body>
I would recommend that you didn't clone the entire <form>
element, as I can imagine that all data has to be sent as a whole. But each <form>
element is its own entity and won't work together with other forms.