1

Can someone explain to me why, when I clone an element with jquery .clone(), store it in $(windows).data('myclone') and append this cloned data element to another element, the cloned data present in $(windows).data('myclone') changes? (points toward my newly created element in html inspector)

<li class="clone">
    <button class="file-list-delete"><a href="#">clone this</a>
    </button>
    <input type="file" size="30" id="files" multiple="multiple" name="files" class="upload-files">
</li>
<button id="append">append clone</button>

<script>
    $('.clone button').on('click', function() {
        var cloneNode = $(this).parent().clone();
        $(window).data('cloneNode', cloneNode);
        console.log(cloneNode);
    });
    $('#append').on('click', function() {
        console.log($(window).data('cloneNode'));
        var clone = $(window).data('cloneNode');
        $('.clone').after(clone);
    });
</script>

Here's a fiddle to see it in your console. First created element is just cloned data, then when you append it, it changes it http://jsfiddle.net/50eu0bnp/

bipen
  • 36,319
  • 9
  • 49
  • 62
Holmeron
  • 140
  • 1
  • 9
  • 2
    That probably happens because they are the same object, it is not cloned again when you append() it. – Matteo Tassinari Sep 26 '14 at 14:21
  • 1
    What exactly _changes_? – Spokey Sep 26 '14 at 14:25
  • It should be noted that a LI can only be a child of a list, and an anchor can not live inside a button. Also, you're creating a node, storing a reference to it in jQuery's data, then you're trying to insert that node after itself, which of course doesn't work, and even if it did, it's the same element, so it's moved, and moving it after itself would result in the exact same markup etc. – adeneo Sep 26 '14 at 14:36

3 Answers3

0

Well, first step for me would be to remove the ID attribute in favor of class attributes. From jQuery.com:

"Note: Using .clone() has the side-effect of producing elements with duplicate id attributes, which are supposed to be unique. Where possible, it is recommended to avoid cloning elements with this attribute or using class attributes as identifiers instead."

What happens when you use .clone(true)? This does a "deep copy".

Scott
  • 3,736
  • 2
  • 26
  • 44
0

You need to clone the clone, otherwise you are reusing the same element.

You also need to target only one of the elements or you duplicate it after each existing class="clone" element which causes additional copies to be created.

JSFiddle: http://jsfiddle.net/TrueBlueAussie/50eu0bnp/1/

$('.clone button').on('click',function(){
   var cloneNode = $(this).parent().clone();
    $(window).data('cloneNode',cloneNode);
});
$('#append').on('click',function(){
    var clone = $(window).data('cloneNode').clone();  // Clone the clone
    $('.clone:last').after(clone);
});

If the elements you clone can vary (they do not at the moment), you need to shift to delegated event handlers as the original $('.clone button') is not connected to the new copies: http://jsfiddle.net/TrueBlueAussie/50eu0bnp/3/

$(document).on('click', '.clone button', function () {
    var cloneNode = $(this).parent().clone();
    $(window).data('cloneNode', cloneNode);
});

You also need to address the issue of duplicating id="files" as that is a complete no-no. jQuery will only be able to see the first one (e.g. with $('#files')) as ids must be unique.

iCollect.it Ltd
  • 92,391
  • 25
  • 181
  • 202
  • thanks to you and Matteo Tassinari comment, I solved my issue. Sorry about the id='files', I made a quick copy/paste of some code to make the fiddle quickly, but didn't have this 'copied id issue' in my code – Holmeron Sep 26 '14 at 16:02
0
$('.clone button').on('click', function() {
    var cloneNode = $(this).parent().clone();
    $(window).data('cloneNode', cloneNode);
    console.log(cloneNode);

when you grab $('.clone button'), you are grabbing every single clone button in the doc. grab just one.

$('.clonebutton')[0].on(...)
jollarvia
  • 349
  • 4
  • 9