# Better way of clone and then replace some attributes with jQuery

I have HTML code like this :

<a class="btn btn-default" href="#" id="addTxt">Add Text</a>
<div id="nF">
<div class="form-inline">
<div class="input-group">
</div>
<input class="form-control" id="project_components_attributes_32943600_name" name="project[components_attributes][32943600][name]" type="text">
<span class="input-group-btn">
<input id="project_components_attributes_32943600__destroy" name="project[components_attributes][32943600][_destroy]" type="hidden" value="false">
<a class="btn btn-default" data-selector="removeField" href="#">
<i class="fa fa-remove"></i>
</a>
</span>
</div>
</div>
</div>


If I click link "Add Text", It will clone div with class form-inline and append to div#nF and then replacing all attribute of input tag in form-inline (id and name) with new value from new date and time.

For Illustration :

id => project_components_attributes_32943600_name => replace "32943600" with new value

name => project[components_attributes][32943600][_destroy] => replace "32943600" with new value

And this javascript :

$(document).ready(function(){$('#addTxt').click(function(){
var time = new Date().getTime();
var $target =$('#nF').find('div.form-inline:first');
$target.clone().appendTo('#nF');$target.find('input').each(function(){
$(this).val(''); var tID =$(this).attr("id").split(/_/);
var re = new RegExp(tID[3],"g");
var newID = $(this).attr('id').replace(re, time); var newName =$(this).attr('name').replace(re, time);
$(this).attr('id', newID);$(this).attr('name', newName);
});
});
});


Live Demo : http://jsfiddle.net/gjj8mzya/

Is there any way to clone element and replace attributes?

The current code does essentially this:

1. Clone the dirtied first item and append to the end
2. Modify the dirtied first item to make it clean again

It would be better to use a clean prototype / template from which you can easily create clean new instances. Then the operations can become:

1. Move the dirtied first item to the end
2. Recreate the first item from the clean template

The first approach is not so good, because:

• Cloning is always a suspicious operation. For example, you have to make sure that:
• all fields correctly copied
• no references accidentally leaked
• deep objects correctly deep-copied: although this is not a concern in this specific example, but I'm adding it anyway as a reminder of general concerns about the concept of cloning
• Reseting an object to a clean state is always a suspicious operation. For example, you have to make sure that:
• all fields are correctly reset: often duplicating the same logic that must exist (explicitly or implicitly) in the initializer / constructor

The new approach doesn't have any of these tricky issues. It's conceptually much cleaner, with much fewer hidden traps and bugs waiting to happen.