9

I have a dynamic table that I want to attach <col> elements with jQuery.

I have this:

var tds = jQuery("tr > td").length; // count how many tds
jQuery("#colgroup-compare > col").clone() // clone
    .appendTo('#colgroup-compare'); // and append

Obviously this only appends 1 <col>, I want to append (n) numbers. How would I do this?

I have the length, I have the clone ability, now how do I combine it?

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
user1737413
  • 105
  • 1
  • 3

2 Answers2

7

With a loop :

var $col = $("#colgroup-compare > col");
for(var i = 0; i < n; i++){
    $col.clone().appendTo('#colgroup-compare');
}

You can't use jQuery("#colgroup-compare > col").clone().appendTo('#colgroup-compare'); in your loop because that would append more cols at iterations > 0...

This can be optimized :

var $colgroup = $('#colgroup-compare'); // this saves the colgroup collection to avoid recomputing it later
var $col = $colgroup.children("col"); // this makes the clonable col(s) from the col children of $colgroup
for (var i=n; i-->0;){ // n times (from n-1 to 0)
    $colgroup.append($col.clone()); // append a clone of the col(s)
}

EDIT : to count the th in your first row, you may do this :

var n=$("tr").first().children('th').length;

(this avoid counting on more than one row)

Demonstration

Denys Séguret
  • 372,613
  • 87
  • 782
  • 758
  • Good point, but maybe more caching of the selectors' results. – Tadeck Oct 11 '12 at 08:49
  • @Tadeck Why not, but this isn't so important with a small n (document.getElementById is fast) and this would make the code less readable. But I agree this could be done. – Denys Séguret Oct 11 '12 at 08:50
  • @Tadeck I made a new version : do you like it better ? – Denys Séguret Oct 11 '12 at 08:53
  • Thanks, but could you expand on that answer for me? I am new to javascript (and stackoverflow, damn that answer came fast) and this got complicated quickly. I did some quick research and each() seems to be the jQuery equivalent. Edit: It seems like you start counting the col elements while I need to count the td element first so I can append the col after!? – user1737413 Oct 11 '12 at 09:06
  • I commented the second one and added a demonstration (link at the bottom). – Denys Séguret Oct 11 '12 at 09:09
  • Thanks for your detailed help and patience, it now works!
    – user1737413 Oct 11 '12 at 09:33
  • Should you not save the clone in a variable and then append in the loop? – itsazzad Dec 11 '14 at 16:43
  • 1
    @SazzadTusharKhan No, because an element can't be at two places at the same time. When you append it, you remove it from its other location. – Denys Séguret Dec 11 '14 at 16:47
1

If you don't want deep clones, then you can avoid the manual iteration by passing the outerHTML of the element to an arrays join() method resulting in an HTMLString corresponding to n number of elements as shown below:

var elementString = new Array(++n).join($(selector).get(0).outerHTML)

which you can append to any element you wish.


In your case you can do:

var n= $("tr > td").length,
$colgroup = $("#colgroup-compare");
$colgroup.append(new Array(++n).join($colgroup.find("col").get(0).outerHTML));
T J
  • 42,762
  • 13
  • 83
  • 138