jQuery clone form not working twice in the same page - javascript

I am trying to use the same form twice in the same page the form is working once but not twice i think the problem is with id or something but i am not sure i am not very good with javascript
Help appreciated.
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function () {
$('#btnAdd').click(function () {
var num = $('.clonedInput').length, // Checks to see how many "duplicatable" input fields we currently have
newNum = new Number(num + 1), // The numeric ID of the new input field being added, increasing by 1 each time
newElem = $('#entry' + num).clone().attr('id', 'entry' + newNum).fadeIn('slow'); // create the new element via clone(), and manipulate it's ID using newNum value
// H2 - section
newElem.find('.heading-reference').attr('id', 'ID' + newNum + '_reference').attr('name', 'ID' + newNum + '_reference').html('Entry #' + newNum);
// Title - select
newElem.find('.label_ttl').attr('for', 'ID' + newNum + '_title');
newElem.find('.select_ttl').attr('id', 'ID' + newNum + '_title').attr('name', 'ID' + newNum + '_title').val('');
// First name - text
newElem.find('.label_fn').attr('for', 'ID' + newNum + '_first_name');
newElem.find('.input_fn').attr('id', 'ID' + newNum + '_first_name').attr('name', 'ID' + newNum + '_first_name').val('');
// Insert the new element after the last "duplicatable" input field
$('#entry' + num).after(newElem);
$('#ID' + newNum + '_title').focus();
// Enable the "remove" button. This only shows once you have a duplicated section.
$('#btnDel').attr('disabled', false);
// Right now you can only add 4 sections, for a total of 5. Change '5' below to the max number of sections you want to allow.
if (newNum == 5)
$('#btnAdd').attr('disabled', true).prop('value', "You've reached the limit"); // value here updates the text in the 'add' button when the limit is reached
});
$('#btnDel').click(function () {
// Confirmation dialog box. Works on all desktop browsers and iPhone.
if (confirm("Are you sure you wish to remove this section? This cannot be undone."))
{
var num = $('.clonedInput').length;
// how many "duplicatable" input fields we currently have
$('#entry' + num).slideUp('slow', function () {$(this).remove();
// if only one element remains, disable the "remove" button
if (num -1 === 1)
$('#btnDel').attr('disabled', true);
// enable the "add" button
$('#btnAdd').attr('disabled', false).prop('value', "add section");});
}
return false; // Removes the last section you added
});
// Enable the "add" button
$('#btnAdd').attr('disabled', false);
// Disable the "remove" button
$('#btnDel').attr('disabled', true);
});
</script>
</head>
<body>
<div id="wrapper">
<div class="sign-up_box">
<form action="#" method="post" id="sign-up_area">
<div id="entry1" class="clonedInput">
<h2 id="reference" name="reference" class="heading-reference">Entry #1</h2>
<fieldset>
<label class="label_ln" for="last_name">Last name:</label>
<input class="input_ln" type="text" name="last_name" id="last_name" value="">
</fieldset>
</div><!-- end #entry1 -->
<div id="addDelButtons">
<input type="button" id="btnAdd" value="add section"> <input type="button" id="btnDel" value="remove section above">
</div>
<fieldset class="form-actions">
<input type="submit" value="Submit">
</fieldset>
</form>
</div><!-- end sign-up_box -->
</div>
<div id="wrapper">
<div class="sign-up_box">
<form action="#" method="post" id="sign-up_area">
<div id="entry1" class="clonedInput">
<h2 id="reference" name="reference" class="heading-reference">Entry #1</h2>
<fieldset>
<label class="label_ln" for="last_name">Last name:</label>
<input class="input_ln" type="text" name="last_name" id="last_name" value="">
</fieldset>
</div><!-- end #entry1 -->
<div id="addDelButtons">
<input type="button" id="btnAdd" value="add section"> <input type="button" id="btnDel" value="remove section above">
</div>
<fieldset class="form-actions">
<input type="submit" value="Submit">
</fieldset>
</form>
</div><!-- end sign-up_box -->
</div>
</body>
</html>

Id tags must be unique within an HTML document or they won't work right. You'll probably want to "class" instead of "id" and use jQuery class selectors to select the appropriate fields, depending on what exactly you're trying to do.
Here are a few existing StackOverflow questions related to this:
Using same ID for in multiple HTML tags?
Several elements with the same ID responding to one CSS ID selector
javascript duplication ID conflict

You cannot simply clone elements which have an id attribute. There mustn't be two elements with the same id on any single page. So please change the ids of the cloned elements accordingly, and the references to them in the code.

Related

Perform operations on a cloned form

I have created a form that contains two drop-down lists, when the user selects an item from the first list, the data for the second is automatically updated. I use jquery to do this and it works perfectly except that when I duplicate the form, the drop-down list N ° 1 of the duplicated form no longer updates the drop-down list N ° 2 so I would like to know how can I perform the same action on a cloned form (update a drop-down list by selecting one entered in another) and save the entries of all the cloned forms in a database.
Cordially!
here is the code i use
<form id="myForm">
<div id="clonedSection1" class="clonedSection">
<select class="form-control" name="productName[]" id="productName" >
<option value="0" selected>Selectionner le produit</option>
<option value="copy">Copie</option>
<option value="scan">Scan</option>
</select>
<select class="form-control" name="productPrice[]" id="quant" disabled>
<option value="pu" selected>P.U</option>
</select>
</div>
<div>
<input type="button" id="btnAdd" value="add another name" />
<input type="button" id="btnDel" value="remove name" />
</div>
<!-- script that allows you to modify the data in a drop-down list when an item is selected in another-->
<script type="text/javascript">
$("#productName").change(function () {
var val = $(this).val();
if (val == "copy") {
$("#quant").html("<option value='25'> 25$ </option>");
} else if (val == "scan") {
$("#quant").html("<option value='50'> 10$ </option>");
}
});
</script>
<!-- script that clones the form-->
<script type="text/javascript">
$(document).ready(function() {
$("#btnAdd").click(function() {
var num = $(".clonedSection").length;
var newNum = new Number(num + 1);
var newSection = $("#clonedSection" + num).clone().attr("id", "clonedSection" + newNum);
newSection.children(":nth-child(5)").children(":first").attr("id", "productName" + newNum).attr("name", "productName[]" + newNum);
newSection.children(":nth-child(6)").children(":first").attr("id", "quant" + newNum).attr("name", "productPrice[]" + newNum);
$(".clonedSection").last().append(newSection)
$("#btnDel").attr("disabled","");
});
$("#btnDel").click(function() {
var num = $(".clonedSection").length; // how many "duplicatable" input fields we currently have
$("#clonedSection" + num).remove(); // remove the last element
// enable the "add" button
$("#btnAdd").attr("disabled","");
// if only one element remains, disable the "remove" button
if (num-1 == 1)
$("#btnDel").attr("disabled","disabled");
});
$("#btnDel").attr("disabled","disabled");
});
</script>
I have written simple and clean code.
Follow below steps:
Don't use ID so you need to use class name instead of id because of ID should be unique.
If appending dynamically element then need to use .on() instead of .change() method.
.cloned-section section should be separate from Add Button.
Each time pick clone element by .cloned-section>div:nth-child(1) this nth-child method.
Set value in input field by onchange .product-name class.
Remove element by onclick .btn-remove class.
When append clone element by append() method then select+input values need to set null so you can see in my jQuesy code and also see commented text.
I hope below snippet will help you lot.
$(document).on('click', '#btnAdd', function(){
// Make clone by clone() method and append REMOVE button for remove section
var cloneElement = $('.cloned-section>div:nth-child(1)').clone();
cloneElement.append('<button type="button" class="btn btn-danger btn-remove"><span aria-hidden="true">×</span></button>');
// Select value set Zero (0)
cloneElement.find('select').val(0);
// Input value set empty
cloneElement.find('input').val('');
$('.cloned-section').append(cloneElement);
});
// On change product name then set price on price field
$(document).on('change', '.product-name', function(){
var getValue = $(this).val();
$(this).parent().find('.product-price').val(getValue+'%');
});
// Click on Remove button and delete product/price section
$(document).on('click', '.btn-remove', function(){
$(this).parent().remove();
});
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.1/css/bootstrap.min.css">
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<div class="container my-2">
<div class="row">
<div class="col-sm-12">
<form class="form-inline" id="myForm">
<div class="cloned-section w-100">
<div class="w-100 mt-2">
<select class="form-control w-50 product-name" name="productName[]">
<option value="0" selected>Select Product</option>
<option value="25">Copy</option>
<option value="50">Scan</option>
<option value="75">Paste</option>
<option value="100">Cut</option>
</select>
<input class="form-control w-25 product-price text-center" name="productPrice[]" readonly>
</div>
</div>
<div class="w-100 mt-2">
<button type="button" id="btnAdd" class="btn btn-success">Add Another Name</button>
</div>
</form>
</div>
</div>
</div>
There are some minor problems of your code:
Use classname instead of id for DOM elements that going to be cloned.
It is because id is unique. Different elements should not share the
same id. If you clone an element with id, there would be elements
sharing the same id.
Use .on() instead of .change() for elements that generate
dynamically.
I'm not sure if you really want to insert a new "clonedSection"
inside the last "clonedSection". If you are not going to do this and
would like to insert new "clonedSection" right after the last
"clonedSection", use
newSection.insertAfter($(".clonedSection").last());
value of .attr("disabled", <>) should be either true or false, but not "" and disabled
$(document).ready(function() {
//use on() instead of change() for elements that generate dynamically
$("body").on("change", ".productName", function() {
var _this = $(this);
var quant = _this.closest(".clonedSection").find(".quant");
var val = _this.val();
if (val == "copy") {
quant.html("<option value='25'> 25$ </option>");
} else if (val == "scan") {
quant.html("<option value='50'> 10$ </option>");
}
});
$("#btnAdd").click(function() {
var num = $(".clonedSection").length;
var newNum = num + 1;
var newSection = $("#clonedSection" + num).clone().attr("id", "clonedSection" + newNum);
newSection.children(":nth-child(5)").children(":first").attr("id", "productName" + newNum).attr("name", "productName[]" + newNum);
newSection.children(":nth-child(6)").children(":first").attr("id", "quant" + newNum).attr("name", "productPrice[]" + newNum);
newSection.insertAfter($(".clonedSection").last()); //insert right after the last clonedsection
$("#btnDel").attr("disabled", false); //disabled should be either true/false but not ""
});
$("#btnDel").click(function() {
var num = $(".clonedSection").length;
$("#clonedSection" + num).remove();
$("#btnAdd").attr("disabled", false);
if (num - 1 == 1)
$("#btnDel").attr("disabled", true);
});
$("#btnDel").attr("disabled", true);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="myForm">
<!--If you are going to clone DOM element, please use classname instead of id-->
<div id="clonedSection1" class="clonedSection">
<select class="form-control productName" name="productName[]">
<option value="0" selected>Selectionner le produit</option>
<option value="copy">Copie</option>
<option value="scan">Scan</option>
</select>
<select class="form-control quant" name="productPrice[]">
<option value="pu" selected>P.U</option>
</select>
</div>
<div>
<input type="button" id="btnAdd" value="add another name" />
<input type="button" id="btnDel" value="remove name" />
</div>
Hope this help :D

Running clone n number of times

i'm currently using this code to clone a text input field when clicking on a button with the id btnAdd
$(document).ready(function() {
$('#btnAdd').click(function() {
var num = $('.clonedInput').length;
var newNum = new Number(num + 1);
var newElem = $('#input' + num).clone().attr('id', 'input' + newNum);
newElem.children(':first').attr('id', 'name' + newNum).attr('name', 'name' + newNum);
$('#input' + num).after(newElem);
$('#btnDel').attr('disabled','');
if (newNum == 25)
$('#btnAdd').attr('disabled','disabled');
});
What i want to do is be able to press another button and have it add a certain number of cloned text fields, while still renaming the ids to name + n
I want to do this so i can have a button create fx. 5 text fields and then populate them with predetermined values.
Right now i have to first create 4 textfields for 5 total, and then call the function with another button, to alter the text fields.
A point in the right direction would be appreciated.
Example i used in comments:
Let’s say that i want to have a site where you can input a list of names
I start with one input boxes
<div id="input1" style="margin-bottom:4px;" class="clonedInput">
<input type="text" name="name1" id="name1" placeholder="Port" />
</div>
Then i want the user to be able to add more input boxes. so i use the clone code in the OP
This enables the user to manually add all the names they want.
But i want to be able to have the user be able to choose from pre selected lists, lets say a list of all the names of the football team.
So i want the user to be able to press a button, which creates fx. 11 input boxes, and then fills out the boxes with all the 11 names of the football team.
To do this i have been using this code:
function Input() {
$('#name1').val(‘John’)
$('#name2').val(’Steve’)
$('#name3').val(‘Maria’)
$('#name4').val(‘Ida’)
}
But if the user has not created enough clones of the input boxes, this just fills out the created ones.
I hope I understood the behaviour you wanted. It basically adds inputs in the div block you want with some random names as value.
var names = ["Chris", "Jimmy", "George", "Martin", "Keith"];
function createInputs(numberOfInputs, blockId) {
var i = 0;
var inputBlock = $("#" + blockId);
inputBlock.empty();
while(i < numberOfInputs && i < names.length) {
inputBlock.append($('<input type="text" name="name" id="name'+ i + '"/>').val(names[i]));
i++;
}
}
input {
display: block;
margin: 5px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button onclick="createInputs(3, 'input1')">Create 3 random inputs</button>
<div id="input1" style="margin-bottom:4px;" class="clonedInput">
<input type="text" name="name1" id="name1" placeholder="Port" />
</div>
<button onclick="createInputs(5, 'input2')">Create 5 random inputs</button>
<div id="input2" style="margin-bottom:4px;" class="clonedInput">
<input type="text" name="name1" id="name1" placeholder="Port" />
</div>

Hiding and showing div series using Javascript

I'm making basic GPA calculator using Javascript.
Here is my code:
<div class="list">
<div class="row">
<div class="col col-50">Subject 1</div>
<div class="col"><input type="text" name ="GR1" placeholder="Grade"></div>
<div class="col"><input type="tel" name="CR1" placeholder="Credits"></div>
</div>
<div class="row">
<div class="col col-50">Subject 2</div>
<div class="col"><input type="text" name ="GR2" placeholder="Grade"></div>
<div class="col"><input type="tel" name ="CR2" placeholder="Credits"></div>
</div>
<button class="button button-positive">
Add Another Field //it can add uptop 10 fields
</button>
</div>
It will increment the same div series while incrementing the input name up to 10 fields. User can click Add Another Field and add a new div field.
In every div field, it only changes the subject and input fields' name with an incrementation of 1.
Question:
What is the best way to achieve this without duplicating the same thing over and over? Or do I need to first create 10 div forms and hide all and show them one by one upon each click? Please give me example.
Here is a solution that is in pure Javascript that will allow you to add up to 10 "field blocks". In the HTML file, put:
<div id="list">
<button onclick="addRow()">Add another field</button>
</div>
And here's the Javascript function to add a new row, and initialise the two first row:
<script type="text/javascript">
window.onload = function() {
addRow();
addRow();
};
function addRow() {
var element = document.getElementById('list');
var nextId = element.childElementCount;
if (nextId <= 10) {
var div = document.createElement('div');
div.setAttribute('class', 'row');
div.innerHTML = '<div class="col col-50">Subject ' + nextId + '</div><div class="col"><input type="text" name ="GR' + nextId + '" placeholder="Grade"></div><div class="col"><input type="tel" name="CR' + nextId + '" placeholder="Credits"></div>';
element.insertBefore(div, element.getElementsByTagName('button')[0]);
}
}
</script>
You can try it online on the following fiddle: https://jsfiddle.net/w82t30r4/
Try jQuery's clone (read about it here)
$(document).ready(function(){
$row = $(".row").clone();
$("button").click(function(){
$(".list").append($row.clone());
})
})
What's happening is that I clone the row to start with (before any data is in it). Then I add a clone of that clone to .list when the button is clicked.

JS works in one place but not another

I'm stumped on something that is a little odd. I was tinkering with some code in an html file that had js and html on it until I got it to work like I wanted then I copied and pasted it to the php file that is linked to a JS page. The trouble is that in the php page I get the error message unrecognized expression: select[name=gateHeight] option: selected. If anyone could explain what I messed up I would appreciate it very much!
Here is the html file with JS and HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$('#btnAdd').click(function() {
var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
var newNum = new Number(num + 1); // the numeric ID of the new input field being added
// create the new element via clone(), and manipulate it's ID using newNum value
var newElem = $('#input' + num).clone().attr('id', 'input' + newNum);
// manipulate the name/id values of the input inside the new element
newElem.children($("select[name=gateHeight] option: selected")).attr('id', 'gateHeight' + newNum).attr('name', 'gateHeight' + newNum);
//newElem.children('input[type=text]:first').attr('id', 'name' + newNum).attr('name', 'name' + newNum);
newElem.children('input[type=checkbox]:first').attr('id', 'chk' + newNum).attr('name', 'chk' + newNum);
// insert the new element after the last "duplicatable" input field
$('#input' + num).after(newElem);
// enable the "remove" button
//$('#btnDel').attr('disabled','');
$('#btnDel').removeAttr('disabled');
// business rule: you can only add 5 names
if (newNum == 5)
$('#btnAdd').attr('disabled','disabled');
});
$('#btnDel').click(function() {
var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
$('#input' + num).remove(); // remove the last element
// enable the "add" button
//$('#btnAdd').attr('disabled','');
$('#btnAdd').removeAttr('disabled');
// if only one element remains, disable the "remove" button
if (num-1 == 1)
$('#btnDel').attr('disabled','disabled');
});
$('#btnDel').attr('disabled','disabled');
});
</script>
</head>
<body>
<form id="myForm">
<div id="input1" style="margin-bottom:4px;" class="clonedInput">
<!-- <input type="text" name="name1" id="name1" /> -->
<select name="gateHeight" id="gateHeight">
<option value="select">Select Gate Height</option>
<option value="4fg">4 Ft. Gate</option>
<option value="6fg">6 Ft. Gate</option>
<option value="8fg">8 Ft. Gate</option>
</select>
Include Spring Pool Latch: <input type="checkbox" name="chk1" id="chk1" />
</div>
<div>
<input type="button" id="btnAdd" value="add another name" />
<input type="button" id="btnDel" value="remove name" />
</div>
</form>
</body>
And here is the JS and HTML of the other file:
JS:
//Dynamic Gate Input Fields
$('#btnAdd').click(function() {
var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
var newNum = new Number(num + 1); // the numeric ID of the new input field being added
// create the new element via clone(), and manipulate it's ID using newNum value
var newElem = $('#input' + num).clone().attr('id', 'input' + newNum);
// manipulate the name/id values of the input inside the new element
newElem.children($("select[name=gateHeight] option: selected")).attr('id', 'gateHeight' + newNum).attr('name', 'gateHeight' + newNum);
//newElem.children('input[type=text]:first').attr('id', 'name' + newNum).attr('name', 'name' + newNum);
newElem.children('input[type=checkbox]:first').attr('id', 'chk' + newNum).attr('name', 'chk' + newNum);
// insert the new element after the last "duplicatable" input field
$('#input' + num).after(newElem);
// enable the "remove" button
//$('#btnDel').attr('disabled','');
$('#btnDel').removeAttr('disabled');
// business rule: you can only add 5 names
if (newNum == 5)
$('#btnAdd').attr('disabled','disabled');
});
$('#btnDel').click(function() {
var num = $('.clonedInput').length; // how many "duplicatable" input fields we currently have
$('#input' + num).remove(); // remove the last element
// enable the "add" button
//$('#btnAdd').attr('disabled','');
$('#btnAdd').removeAttr('disabled');
// if only one element remains, disable the "remove" button
if (num-1 == 1)
$('#btnDel').attr('disabled','disabled');
});
$('#btnDel').attr('disabled','disabled');
HTML:
<div id="input1" style="margin-bottom:4px;" class="clonedInput">
<select name="gateHeight" id="gateHeight">
<option value="select">Select Gate Height</option>
<option value="4fg">4 Ft. Gate</option>
<option value="6fg">6 Ft. Gate</option>
<option value="8fg">8 Ft. Gate</option>
</select>
Include Spring Pool Latch: <input type="checkbox" name="chk1" id="chk1" />
</div>
<div>
<input type="button" id="btnAdd" value="Add Another Gate" />
<input type="button" id="btnDel" value="Remove Gate" />
</div>
You are missing the document ready wrapper function your code is called before the element exist therefore fail.
Try with
$("select[name=gateHeight] option :selected")
:selected is the right one not : selected (no space)
OR
$("select[name=gateHeight] option").filter(":selected")
This will work
You need to get rid of the space after the colon in option: selected. Just change that to option:selected.
First you should use the updated version of jquery like jquery-1.9 or higher.
Second you should use newElem.children("select[name=gateHeight]") in place of
newElem.children($("select[name=gateHeight] option: selected"))
like
newElem.find("select[name='gateHeight']")
.attr({'id': 'gateHeight'+newNum, 'name': 'gateHeight' + newNum});// combine attr() using json
Demo

Dynamically remove a dynamically added input (type=file)

I have a form where user can add files to be uploaded. Change event on that input adds new input the same type and so on. But the new inputs have to have "X" character with click event attached to it to be able to remove the input field and the X chracter.
The form:
<form id="upload_form">
<div class="p_file">
<p class="icon">X</p>
<input type="file" name="userfile1" size="40" class="required" />
</div>
</form>
and the JavaScript:
$('#upload_form input[type="file"]').change(function(){
addUploadField($(this));
});
function addUploadField($field)
{
$current_count = $('#upload_form input[type="file"]').length
$next_count = $current_count + 1;
$field.parent('p').after('
<div class="p_file" >
<p class="icon">X</p>
<input type="file" name="userfile'+$next_count+'" size="40" />
</div>
');
$field.unbind('change');
$nextField = $('#upload_form input[type="file"]').last();
$nextField.bind('change',function(){
addUploadField($(this));
});
$("#upload_form .icon").on('click',function(){
removeUploadField($field);
});
}
function removeUploadField($field)
{
$field.parent('p').remove();
}
The code above remove all the fields after the clicked 'X' character. What I want to do is to remove only the next input field.
I tried to prepare this example in jsFiddle, but I can't make this work. Anyhow maybe this would help.
Putting "div" tag inside "p" tag is the main problem
Remove is corrected in this code
Note: In your html code "div" is is added inside "p" tag, this is invalid practice
HTML:
<form id="upload_form">
<div class="p_file">
<div class="icon">X</div>
<input type="file" name="userfile1" size="40" class="required" />
</div>
</form>
Script:
$('body')
.delegate('#upload_form input[type="file"]', 'change', inputChanged)
.delegate('#upload_form .icon', 'click', removeField);
function inputChanged() {
$current_count = $('#upload_form input[type="file"]').length;
$next_count = $current_count + 1;
$(this).closest('.p_file').after(
'<div class="p_file" ><div class="icon">X</div>' +
'<input type="file" name="userfile'
+ $next_count + '" size="40" /></div>');
}
function removeField(){
$(this).closest('.p_file').remove();
return false;
}
Link: http://jsfiddle.net/cBrQX/2/

Categories