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 class="input-group-addon"><i class="fa fa-text-width"></i>
</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?
1 Answer 1
The current code does essentially this:
- Clone the dirtied first item and append to the end
- 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:
- Move the dirtied first item to the end
- 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.