We do something similar on a project I am on... only we approach it from the client side completely.
I'll just explain an overview of the algorithm here. So let me know if you need more help. But there are a number of good resources for information on the HTML Dom, attributes and functions of various node types. Even at MSDN (and it looks like your targetting IE
http://msdn.microsoft.com/library/de...ce/objects.asp ).
Here is our algorithm:
A. Create a template row, give it a unique name. (We also create a header row and an empty table row - but this is optional).
B. Create a Javascript object to handle the dynamic table. And instantiate it with a reference to the template row using the unique ID, we remove this row node from the document (but we maintain a reference to it in the table object).
C. When a user wants a new row, they click a button. We create a deep clone of template and append the clone to the table. Updating the number of rows in the table object (when row count is zero, we show the empty table header, otherwise we show the other header).
Why our algorithm uses templates:
We are drawing JSP using XSLT (which isn't done on the fly... so I don't agree with this architecture... but this seems to be our architects baby). Because our JSP is drawn from XSLT using XSD files to define the data content (and style!!), we don't know anything about the content of the data (except the type), so we draw a template and allow this to be cloned as required by the user.
How our algorithm got dirty:
We were J2EE and JSPs and we actually needed to show any dynamic rows we had saved to the database. But we already had the above algorithm in place. So when we read some dymanic rows from the database, we don't just draw the HTML using JSP, we actually draw the JavaScript functions to create and populate the rows. Its dirty, and it means we have to escape all the data so it isn't literally written by JSP (think newlines, quotes etc).
What would be cleaner and nicer, is if we drew the HTML and then told the javascript object how many rows we had drawn (this is important in our implementation for a number of reasons).