Reputation: 2284
I am using the following script to clone a div with form elements inside; however, it currently adding sequential numbers (1, 2, 3) to the container div id correctly, but then is adding a "name2" and "name3" to the sub-divs in the clone, instead of to the actual form elements.
Example of problem:
<div class="clonedInput" id="container1">
<div>First Name:
<input type="text" id="first_name1" name="first_name1">
</div>
<div>Last Name:
<input type="text" id="last_name1" name="last_name1">
</div>
<div>Phone:
<input type="text" id="phone1" name="phone1">
</div>
</div>
<div class="clonedInput" id="container2">
<div id="name2" name="name2">First Name:
<input type="text" id="first_name1" name="first_name1">
</div>
<div>Last Name:
<input type="text" id="last_name1" name="last_name1">
</div>
<div>Phone:
<input type="text" id="phone1" name="phone1">
</div>
</div>
<div class="clonedInput" id="container3">
<div id="name3" name="name3">First Name:
<input type="text" id="first_name1" name="first_name1">
</div>
<div>Last Name:
<input type="text" id="last_name1" name="last_name1">
</div>
<div>Phone:
<input type="text" id="phone1" name="phone1">
</div>
</div>
Full code:
<html>
<head>
<title></title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script type="text/javascript">
jQuery( 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
var newElem = $( '#container' + num ).clone().attr( 'id', 'container' + newNum );
newElem.children( ':first' ).attr( 'id', 'name' + newNum ).attr( 'name', 'name' + newNum );
$( '#container' + num ).after( newElem );
$( '#btnDel' ).attr( 'disabled', false );
if ( newNum == 25 )
$( '#btnAdd' ).attr( 'disabled', 'disabled' );
});
$( '#btnDel' ).click( function() {
var num = $( '.clonedInput' ).length; // how many "duplicatable" input fields we currently have
$( '#container' + num ).remove(); // remove the last element
$( '#btnAdd' ).attr( 'disabled', false ); // enable the "add" button
// 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="container1" class="clonedInput">
<div>
First Name:
<input type="text" name="first_name1" id="first_name1">
</div>
<div>
Last Name:
<input type="text" name="last_name1" id="last_name1">
</div>
<div>
Phone:
<input type="text" name="phone1" id="phone1">
</div>
</div>
<div>
<input type="button" id="btnAdd" value="add another name" />
<input type="button" id="btnDel" value="remove name" />
</div>
</form>
</body>
</html>
Upvotes: 2
Views: 6098
Reputation: 2904
Though not a solution to the OP question, I found Jquery Form Clone Plugin to be quite helpful. Its has everything preset, index, nested forms, controls and even callbacks like beforeAdd, after add etc. I mentioned it because when searching for a jQuery's solution, I ended up here. So I thought it might help others searching for jQuery's solution for cloning forms
Upvotes: 0
Reputation: 1152
Here's what I do: if you have multiple layers of div, tables (like me), you have to change the code provided by Brian Glaz from newElem.children to newElem.find. Here is his fiddle: http://jsfiddle.net/B7bgN/10/
All I did was change one word. From children to find. (Children will only traverse one level while find will get descendants of each element.
http://jsfiddle.net/the7th/sSS3c/1/
$(document).ready(function () {
var newNum = 1;
cloneMe = function (el) {
var newElem = el.clone().attr('class', 'firstrow' + newNum).insertAfter(".firstrow0");
newElem.find('input').each(function (index, elem) {
$(elem).attr('id', $(elem).attr('id') + newNum).attr('name', $(elem).attr('name') + newNum);
});
if (newNum == 2) {
$("#cloneb").hide();
};
newNum++;
};
});
Upvotes: 1
Reputation: 15666
The problem is this line here:
newElem.children( ':first' ).attr( 'id', 'name' + newNum ).attr( 'name', 'name' + newNum );
Only the first child of each newElem
is being selected, which is why only the first input element is being changed. What you want to do is select ALL the children that are input elements. Try this:
newElement.children('input').attr('id',$(this).attr('id') + newNum).attr('name',$(this).attr('name') + newNum);
Upvotes: 1
Reputation: 169383
var cloneEl = (function () {
var counter = 1;
return function cloneEl(id) {
var el = document.getElementById("container");
var clone = el.cloneNode(true);
clone.id = el.id+counter;
[].forEach.call(clone.children, function (node, key) {
var oldNode = el.children[key];
node.id = oldNode.id+counter;
node.name = oldNode.id+counter;
});
counter++;
return clone;
};
})();
Upvotes: 1