views:

832

answers:

1

Hi,

I'm trying to construct a table with Prototype's New Element function. I was experiencing problems in Firefox when I was updating the thead with the complete content: all th elements plus contents. Firefox was stripping the tags and displays only the contents.

Anyways I decided to construct every single th element and then append it to the thead utilizing the Element.update() function. But I haven't found a way to append multiple objects with this function.

The th elements look like this:

var thead_amount = new Element('th', {
    'id': 'amount'
}).update('amount');

This works fine:

new Element('thead').update(thead_amount);

This outputs the same as above:

new Element('thead').update(thead_amount, thead_pdf, thead_tags, thead_date, thead_options);

This outputs '[object HTMLTableCellElement][object HTMLTableCellElement][object HTMLTableCellElement][object HTMLTableCellElement][object HTMLTableCellElement]'

new Element('thead').update(thead_amount + thead_pdf + thead_tags + thead_date + thead_options);

How can I append multiple objects with Prototype's update() function?

Thanks!

A: 

Edit

It just jumped out at me that you are adding "TH" elements to a "THEAD". This is bad! A THEAD should contain only TR's. TR's can contain TH's, but if you're using THEAD I would use TD's instead.

Remember: tbody, thead, and tfoot are subdivisions of table, and must contain tr elements. You should not put td or th elements directly into these, as the results are unpredictable at best.

End Edit

The problem here is that Element.update() has to be passed a string, HTML snippet, or a javascript object that implements toString (e.g. Element). However, Element does not support the '+' operator as you are using it, and adds together the object names as you see. You would have to explicitly call the toString method on each child as such:

new Element('thead').update(thead_amount.toString()
  + thead_pdf.toString() 
  + thead_tags.toString() 
  + thead_date.toString() 
  + thead_options.toString());

If you are using script.aculo.us in your app (a Prototype extension), you can use the Builder class to assist in easier Element construction. It provides a much more intuitive interface, especially when creating large numbers of Elements. Here is an example:

var table = Builder.node('table', {
  width: '100%',
  cellpadding: '2',
  cellspacing: '0',
  border: '0'
});

var tbody = Builder.node('tbody'),
    tr = Builder.node('tr', { className: 'header' }),
    td = Builder.node('td', [Builder.node('strong', 'Category')]);

tr.appendChild(td);
tbody.appendChild(tr);
table.appendChild(tbody);

$('divCat').appendChild(table);

Check out http://wiki.github.com/madrobby/scriptaculous/builder for details.

hobodave
Scriptaculous' Builder function is wonderful! Just what I was looking for, thanks a lot! Also thanks for clearing that up about thead and th, in fact I was using tr's before but a friend of me gave me a wrong suggestion on that :P Works perfect now in FF where nothing did before because of it not creating the nodes :) Thanks!
richard