Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

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?

share|improve this question

1 Answer 1

up vote 2 down vote accepted

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.