To clone the fieldset and add it to the same parent:
var fieldset = $("#question1"); // Get the fieldset
var clone = fieldset.clone(); // Clone it
clone.attr("id", "question2"); // Set its ID to "question2"
clone.appendTo(fieldset.parent()); // Add to the parent
Note we're changing the ID before adding it to the tree, since you can't have two elements with the same ID.
To do things with the elements within it, you can use .children()
or .find()
on your clone
variable with a selector to select the children/descendants you want (once you've added the clone to the parent). For instance, to clean up the id
s on the inputs:
clone.find('input').each(function() {
if (this.id) {
// It has an ID, which means the original had an ID, which
// means your DOM tree is temporarily invalid; fix the ID
this.id = /* ...derive a new, unique ID here... */;
}
});
Note that within the each
callback, this
is not a jQuery instance, it's the raw element. (Hence my setting this.id
directly.) If you wanted to get a jQuery instance for the element, you'd do var $this = $(this);
and then use $this.attr("id", ...)
instead. But there's no particular need unless you're doing something other than changing the ID.
Answering your question about renumbering IDs, you'll need to be sure you update whatever's using those IDs as well as the actual IDs on the input elements.
But in terms of doing the update on the input elements, you could do it by reading the number and incrementing it until you get one that isn't used:
clone.find('input').each(function() {
var id;
if (this.id) {
id = this.id;
do {
id = id.replace(/[0-9]+$/g, function(num) {
return String(Number(num) + 1);
});
}
while ($("#" + id).length > 0);
this.id = id;
}
});
...which will give you "input_radio2" if the original ID was "input_radio1", but I think I'd probably use a different naming convention instead. For instance, you could prefix your various input IDs with the ID of the question:
<fieldset id='question1'>
...
<input id=-'question1:input_radio1' />
</fieldset>
...and then just replace 'question1' with 'question2' in the cloned IDs. (Colons [:
] are perfectly valid in IDs.)
If you can avoid having IDs on all of your inputs, though, that would be the way to go. For instance, unless your markup prevents it for a different reason, you can associate an input
with its label
via containment rather than using for
:
<label>First name: <input type='text' ... /></label>
Lots of options. :-)