0

how to copy an object with some elements?

I want to copy this object, but each elm still refers to the same DOM element?

var fields = {
    account_id_ : {
        name : Lang.get('HDL_ACCOUNT'),
        width : 60,
        elm : $('<input class="inp" type="text" style="text-align:right" />'),
        value : '',
        focus : true
    },
    name : {
        name : Lang.get('HDL_NAME'),
        width : null,
        elm : $('<input class="inp" type="text" />'),
        value : ''
    }
};
clarkk
  • 27,151
  • 72
  • 200
  • 340
  • What do you mean it still refers to the same DOM element. The `elm` variable is assigned a newly created element which is not even yet inserted into the DOM. – Darin Dimitrov Jun 18 '11 at 19:57
  • no, but its still somehow added to the DOM.. I want to use multiple instances of this object.. this is a template to some rows I want to add to a table – clarkk Jun 18 '11 at 20:00

3 Answers3

1

You can just loop through and .clone() the jQuery object (and the elements, 1 in this case, that it references. A very concise method would look like this:

var fields2 = $.extend(true, {}, fields);
$.each(fields2, function(n, f) { f.elm = f.elm.clone(); });

Now fields2 has it's own elements, you can test it here, compare it to here which doesn't run the clone line, and references/re-appends the same elements, instead of clones in the first example.

For clarity, a raw javascript version of the clone loop would look like this:

for(var fieldName in newFields) {
    var field = newFields[fieldName];
    if(field .hasOwnProperty("elm"))
        field.elm = field.elm.clone();
}
Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
0

I'd refer to John Resig's answer. Short answer: use .extend()

Community
  • 1
  • 1
kinakuta
  • 9,029
  • 1
  • 39
  • 48
0

If you really wanted to include references to DOM elements, you'd have to:

  1. Use $(...).get(0) so that there's only DOM elements rather than jQuery objects in the tree
  2. Do a deep $.extend() of the original object
  3. Recursively search the copy for any value which is an instanceof HTMLElement
  4. Convert each such value into a .clone() of itself

Something like (untested):

var fields = {
    account_id_ : {
        name : Lang.get('HDL_ACCOUNT'),
        width : 60,
        elm : $('<input class="inp" type="text" style="text-align:right" />').get(0),
        value : '',
        focus : true
    },
    ...
};

function cloneDOM(obj) {
    for (var key in obj) {
        if (Object.hasOwnProperty(key)) {
            var val = obj[key];
            if (val instanceof HTMLElement) {
                obj[key] = $.clone(val);
            } else if (val instanceof Object) {
                cloneDOM(val);
            }
        }
    }
}

var copy = $.extend(true, {}, fields);
cloneDOM(copy);
Alnitak
  • 334,560
  • 70
  • 407
  • 495