I have a very simple form on my website.
The bug: I click the ‘Yes‘ radio button then click ‘Add 1 more‘ 3 times and instead of having 4 rows in total, I have about 9(?)
Give it a try in the JS Fiddle here. I’ve also attached here in the post.
I’m assuming it’s my Counter but been racking my head all morning with no joy.
Many thanks for any guidance here.
$(function() {
// Initially hide both divs
$(".bulk").hide();
$(".individual").hide();
// Listen for changes in the radio button selection
$("input[name='bulkPayments']").change(function() {
if ($(this).val() === "Yes") {
// Show the bulk div and hide the individual div
$(".bulk").show();
$(".individual").hide();
} else if ($(this).val() === "No") {
// Show the individual div and hide the bulk div
$(".bulk").hide();
$(".individual").show();
}
});
});
$(document).ready(function() {
// Initialize the counter for generating unique names and IDs
var counter = 1;
// Add more sets when the "Add 1 more" button is clicked
$("#addMore").click(function(event) {
event.preventDefault(); // Prevent the default form submission
// Clone the "bulk" section and update the attributes
var newBulkSection = $(".bulk:first").clone();
// Increment the counter for the next set and update the IDs and names
counter++;
newBulkSection.find("input[type=text]").attr("id", "clientName" + counter).attr("name", "clientName" + counter);
newBulkSection.find("input[type=file]").attr("id", "attachments" + counter).attr("name", "attachments" + counter);
// Clear input values in the new section (optional)
newBulkSection.find("input[type=text]").val("");
newBulkSection.find("input[type=file]").val("");
// Append the newly modified section to the container
$("#bulkContainer").append(newBulkSection);
// Show the newly added section
newBulkSection.show();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<form action="" enctype="multipart/form-data" method="post">
<div class="form-group">
<label>Bulk Payments *:</label>
<div class="radio">
<label><input name="bulkPayments" type="radio" value="Yes"> Yes</label>
</div>
<div class="radio">
<label><input name="bulkPayments" type="radio" value="No"> No</label>
</div>
</div>
<div class="bulk" id="bulkContainer" style="display:none">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="clientName1">Client Name *:</label> <input autocomplete="one-time-code" class="form-control" id="clientName1" name="clientName1" placeholder="" required="" type="text">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="attachments1">Attachment:</label> <input class="form-control-file" id="attachments1" name="attachments1" type="file">
</div>
</div>
</div>
</div><button class="btn" id="addMore">Add 1 more</button>
</form>
>Solution :
The issue is because #bulkContainer
and .bulk
are the same element, so when you clone .bulk:first
you’re cloning the entire container with all previous clones within it.
To fix the issue, remove the .bulk
class from #bulkContainer
and add it to a new child div, like this:
$(function() {
// Initially hide both divs
$("#bulkContainer").hide();
$(".individual").hide();
// Listen for changes in the radio button selection
$("input[name='bulkPayments']").change(function() {
if ($(this).val() === "Yes") {
// Show the bulk div and hide the individual div
$("#bulkContainer").show();
$(".individual").hide();
} else if ($(this).val() === "No") {
// Show the individual div and hide the bulk div
$("#bulkContainer").hide();
$(".individual").show();
}
});
// Initialize the counter for generating unique names and IDs
var counter = 1;
// Add more sets when the "Add 1 more" button is clicked
$("#addMore").click(function(event) {
event.preventDefault(); // Prevent the default form submission
// Clone the "bulk" section and update the attributes
var newBulkSection = $(".bulk:first").clone();
// Increment the counter for the next set and update the IDs and names
counter++;
newBulkSection.find("input[type=text]").attr("id", "clientName" + counter).attr("name", "clientName" + counter);
newBulkSection.find("input[type=file]").attr("id", "attachments" + counter).attr("name", "attachments" + counter);
// Clear input values in the new section (optional)
newBulkSection.find("input[type=text]").val("");
newBulkSection.find("input[type=file]").val("");
// Append the newly modified section to the container
$("#bulkContainer").append(newBulkSection);
// Show the newly added section
newBulkSection.show();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<form action="" enctype="multipart/form-data" method="post">
<div class="form-group">
<label>Bulk Payments *:</label>
<div class="radio">
<label><input name="bulkPayments" type="radio" value="Yes"> Yes</label>
</div>
<div class="radio">
<label><input name="bulkPayments" type="radio" value="No"> No</label>
</div>
</div>
<div id="bulkContainer" style="display:none">
<div class="bulk">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="clientName1">Client Name *:</label> <input autocomplete="one-time-code" class="form-control" id="clientName1" name="clientName1" placeholder="" required="" type="text">
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="attachments1">Attachment:</label> <input class="form-control-file" id="attachments1" name="attachments1" type="file">
</div>
</div>
</div>
</div>
</div>
<button class="btn" id="addMore">Add 1 more</button>
</form>
Also, as an aside, note that creating incremental id
attributes using a counter variable is not ideal practice. I would strongly suggest you remove that logic and use common classes instead. If you need to identify a specific group of the cloned HTML, use its index.
Here’s a demonstration of how to do that:
$(function() {
const $bulkContainer = $("#bulkContainer");
const $individual = $('.individual');
$("input[name='bulkPayments']").on('change', e => {
const value = $(e.target).val();
$bulkContainer.toggle(value === "Yes");
$individual.toggle(value !== "Yes");
});
$("#addMore").on('click', e => {
e.preventDefault();
var $newBulkSection = $(".bulk:first").clone().insertAfter('.bulk:last');
$newBulkSection.find("input[type=text], input[type=file]").val("");
});
});
#bulkContainer,
.individual {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<form action="" enctype="multipart/form-data" method="post">
<div class="form-group">
<label>Bulk Payments *:</label>
<div class="radio">
<label><input name="bulkPayments" type="radio" value="Yes"> Yes</label>
</div>
<div class="radio">
<label><input name="bulkPayments" type="radio" value="No"> No</label>
</div>
</div>
<div id="bulkContainer">
<div class="bulk">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="clientName1">Client Name *:</label>
<input autocomplete="one-time-code" class="form-control" name="clientName" placeholder="" required="" type="text" />
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="attachments1">Attachment:</label>
<input class="form-control-file" name="attachments" type="file" />
</div>
</div>
</div>
</div>
<button class="btn" id="addMore">Add 1 more</button>
</div>
</form>