24

I need to copy data values from one element to another, but jQuery's clone() method doesn't clone the data. And I can't iterate over the data either:

element.data().each

because data() is a function and not a jQuery object. It seems I have to keep a separate list of attribute names and reference those but that seems too hacky. So how can I do either of these:

a) Iterate over data items
OR
b) clone() an element with its data.

Racil Hilan
  • 24,690
  • 13
  • 50
  • 55
MDCore
  • 17,583
  • 8
  • 43
  • 48
  • Do you need to make a clone of the element as well? Or are you just trying to clone the variables/functions that you've added to the element? – Sugendran Oct 07 '08 at 11:17
  • [This question](http://stackoverflow.com/questions/122102/what-is-the-most-efficent-way-to-clone-a-javascript-object) discusses cloning in JQuery, and the difference between a deep copy and a shallow copy. The accepted answer is that given by [John Resig](http://ejohn.org/), who knows a thing or two about JQuery! – ConroyP Oct 07 '08 at 11:26
  • It is frustrating that many years later, there is still no way to report or undo questions falsely marked as duplicate. Who watches the watchmen? – Nexii Malthus Feb 22 '18 at 12:57
  • @NexiiMalthus To be fair John Resig's (!) answer sort of makes that question a more appropriate primary question. Surprised to see someone still putting value on Stack Overflow :) – MDCore Feb 22 '18 at 17:11
  • @MDCore deep cloning is irrelevant to copying data of an element – Nexii Malthus Aug 01 '22 at 16:32

4 Answers4

34

To really only copy the data-*, this is quite straightforward:

$(destination).data( $(source).data() );

This is because using .data() no arguments will return a key-value object of all pieces of data and vice versa you can also update multiple pieces data at once using a key-value object.


UPDATE 25th May 2017

A clever alternative in JavaScript without jQuery appears to be:

Object.assign(destination.dataset, source.dataset);
Nexii Malthus
  • 690
  • 5
  • 14
  • 4
    I believe your answer to be, by far, the best solution. Accepted answer is just a referral to another question which is about JavaScript objects, not specifically HTML elements and their data attributes. +1 – bozdoz May 15 '14 at 02:09
4

Answer to:

a) Iterate over data items

$.each(element.data(), function (name, value) {
    // ... do something
})

If element is a DOM element, use this:

$.each($.data(element), function (name, value) {
    // ... do something
})
DUzun
  • 1,693
  • 17
  • 15
1

Something that wasn't originally answered as a part of this question was whether or not you wanted the data attributes to be part of the DOM. Using many of the answers provided will make it accessible to jQuery's data() API, but, won't be visible in the DOM (to make things like debugging easier, for example).

A way to do this is:

$.each(original.data(), function (name, value) {
    new.attr('data-' + name, JSON.stringify(value));
});

Note that the stringify is not explicitly required. I have some JSON embedded into my original data tags and, if I don't do this, I get '[Object object]' as the string instead of the actual JSON.

JasCav
  • 34,458
  • 20
  • 113
  • 170
  • There is a bug in this solution! The name variable contains camelCase names, so attributes like "data-background-image" will become "data-backgroundimage". – Steffen Mar 18 '21 at 11:36
1

To give another alternative, i.e. instead of cloning the whole object you can copy the data object to a new array containing name/value pairs followingly:


function getOriginalElementData(domElementJQueryObject){
    var originalElementData = new Array();
    $.each(domElementJQueryObject.data(),function(name,value) {
       originalElementData.push({"name":name,"value":value});
    });

    return originalElementData;
}

To restore the data to another object:


function restoreOriginalElementData(domElementJQueryObject,originalElementData){
    for(var i=0;i<originalElementData.length;i++){
        domElementJQueryObject.data(originalElementData[i].name,originalElementData[i].value);
    }
}

The part to iterate through the data items is copied from this answer: jQuery loop through data() object

Community
  • 1
  • 1
simon
  • 12,666
  • 26
  • 78
  • 113