views:

455

answers:

2

I am copying a table cell with javascript.

It works fine, just that it doesn't copy the style. I wanted to copy like below, but that didn't work. newCell.style=oldCell.style;

So I figured that for my text-align, I have to copy it like this: newCell.style.textAlign=oldCell.style.textAlign;

That worked, but whenever I add a new style item, I have to remember to register it here.

So, my problem now is how can I loop over the style and copy every item in there?

With chrome, I managed to do it like this:

 var strAttribute = GetDomNameFromAttributeName(oRow.cells[1].style[0]);
    var styletocopy = eval('oRow.cells[1].style.'+strAttribute);
    eval("newCell.style."+strAttribute+"='"+styletocopy+"'"); // //newCell.style.textAlign='center';

But that doesn't work with IE. Haven't tested it with FF, but assume chrome compatibiity.

Is there any way to loop over the style elements in IE? Or is there any better way to copy all style elements?

+2  A: 

You can copy a DOM Element with all its content (including attributes) with .cloneNode(true) :

var clonedTr = document.getElementById('id').cloneNode(true);

Then clonedTr is a exact copy of the tr #id. The "true" means you want to copy the content of the element.

Pikrass
It's just that that doesn't work... besides, I can't get my trs by id, because they don't have one.
Quandary
Really ? I just tested, and cloneNode(true) copy the style. The `getElementById('id')` was just for my example, you can access to your element by any method you want (for instance with `table.rows[y].cells[x]`).If it really doesn't work, you could use a CSS class, it'll be easier than copying every style element.
Pikrass
cloneNode works fine for me. Whether you get the cell element node by ID or by `oRow.cells[i]` is of no importance.
bobince
It works if you do a appendchild to the tbody. But not if you do insertrow in the middle of a table.
Quandary
That's because insertRow creates a new row. It doesn't take your row to put it in the table. You can use insertBefore on your table's tbody instead, like this : `tab.getElementsByTagName('tbody')[0].insertBefore(tr, tab.rows[2]);`
Pikrass
+1  A: 
eval('oRow.cells[1].style.'+strAttribute)

Never use eval like this(*). In JavaScript you can access a property whose name is stored in a string using square brackets. object.plop is the same as object['plop']:

to.style[name]= from.style[name];

(*: never use eval at all if you can help it. There are only a few very specific and rare occasions you need it.)

Is there any way to loop over the style elements

The style object is supposed to support the DOM Level 2 CSS CSSStyleDeclaration interface. You could loop over the rules and apply them to another element like this:

for (var i= from.style.length; i-->0;) {
    var name= from.style[i];
    to.style.setProperty(name,
        from.style.getPropertyValue(name),
        priority= from.style.getPropertyPriority(name)
    );
}

in IE?

No, IE does not support the whole CSSStyleDeclaration interface and the above won't work. However there is a simpler way not involving looping that will work on IE and the other browsers too:

to.style.cssText= from.style.cssText;

As simple as that! IE doesn't quite preserve the CSS text the way it should, but the difference doesn't matter for simple inline style copying.

However, as Pikrass said (+1), if you are copying a whole element and not just the styles, cloneNode is by far the most elegant way to do that.

bobince
obj.style.cssText +1works excellently
Quandary