views:

98

answers:

4

Hello,

I have a situation when there's a table and you can add a new row by clicking a button. The row is dynamically generated by a server and it is passed back in HTML. So basically what i need to do is prefix the new row to the old table. Something like this:

tableelement.innerHTML = newHtml + tableelement.innerHTML;

That surely works, but i have a table header and, obviously, i need to insert the new html after it. How would i do this? insertBefore or insertAfter can't help (afaik), because they're meant for inserting elements and not unparsed HTML. So how could i, having an object of the header's row, insert another row (in HTML) after it (or before) ?

Thank you for your ideas

+1  A: 

Use jQuery.after().

In general, become familiar with jQuery, as it is a fantastic library for this sort of thing.

John Bledsoe
It's a personal project, i hate using third party libraries in personal projects :)
Marius
if i make personal projects i always include jquery just for the sake of a bit faster programmingfor that kind of cases i use :<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
Spidfire
A: 

How much control do you have on the server-side? If you have any control at all, I would suggest that rather than pass back HTML from the server-side, pass back the data for the table.

Then you are free to use JQuery or MooTools to dynamically insert DOM structure in the table rather than HTML.

Randolpho
Since i completely trust the server response and have full control over it, it's easier for me to insert HTML than generate the row in JavaScript and add data to it. Ofcourse, if my method is impossible, then i'll have to do as you've suggested.
Marius
@Marius: I'm not saying it's impossible to add inner HTML, I'm just saying it's not necessarily the best practice. DOM insertion is generally faster, more stable, and more flexible than dynamically inserting raw HTML. Faster probably doesn't matter to you given that you're getting the HTML from server, but the stability and flexibility might be worth it. If this is a personal project for the purposes of learning, it might be better for you to practice DOM manipulation rather than dynamic HTML generation -- dynamic HTML is so 1996 -- and JQuery, frankly, is the best way to do DOM manipulation.
Randolpho
A: 

I would consider rethinking the approach. innerHTML is read-only for tables in Internet Explorer, so you're bound to run into interoperability issues with your current method. You could restructure your code to build the elements using the DOM instead of specifying the innerHTML. It's fairly straightforward, much more efficient (doesn't invoke the parser) and more cross-browser compatible.

Mozilla seems to agree with Microsoft on this, and to quote the element.innerHTML documentation:

[innerHTML] should never be used to write parts of a table—W3C DOM methods should be used for that—though it can be used to write an entire table or the contents of a cell.

The process involves using the DOM Level 2 methods, table.insertRow() and tr.insertCell(). For a decent read, see Building Tables Dynamically (MSDN).

Example (from MDC):

function addRow(tableID)
{
  // Get a reference to the table
  var tableRef = document.getElementById(tableID);

  // Insert a row in the table at row index 0
  var newRow   = tableRef.insertRow(0);

  // Insert a cell in the row at index 0
  var newCell  = newRow.insertCell(0);

  // Append a text node to the cell
  var newText  = document.createTextNode('New top row')
  newCell.appendChild(newText);
}
Andy E
OK i guess i'll have to add a few lines of code and do it as you suggest, since i don't see any other easy way of doing it.
Marius
A: 

If the new HTML element is just a string, your code was correct and no problem. But, when the HTML element contain HTML DOM element (especially part of form like input, textarea etc), you should use document.createElement() method. If you use prototype and scriptaculous, you should try Builder.node().

/* using native DOM */
//create new row
var new_row = document.createElement('tr');
//create new column
var new_column = document.createElement('td');
//add a text to column or cell
new_column.innerHTML = 'my new string';
new_row.appendChild(new_column);
tableelement.insertBefore(new_row, tableelement.firstChild);

/* using prototype & script.aculo.us */
var new_cell = Builder.node('tr', [
    Builder.node('td', 'my new string')
]);
new Insertion.Top(tableelement, new_cell);
iroel