Archives

Form and Table Row Nesting Workaround

Have you ever tried to nest elements in a way that is valid as far as XML is concerned, but isn’t “valid”? For example, have a table containing a different form per table row? This article describes a workaround for that.

So no matter how much you may hate tables in HTML, sometimes it just makes life much easier. Now I don’t want to get into a Div vs Table discussion, but I think we can at least agree that tables have a place and most of us use them at some point.

To set the stage, basically I was making a content management system for a client, and so I had several items with several editable properties. The most straightforward way I thought to implement this is to have a table, with one item per row, one property per column. For example:

Name

Email

The only real problem is that structurally we’d have <table><form><tr>…</tr></form></table>, which is not valid, and actually doesn’t work in Google Chrome.

Now, before anyone suggests just surrounding the table with one huge form, the table was dynamic (using php in my case) and could have arbitrarily many rows. Thus the entire form, including fields that weren’t even being used, would be sent every time a row was to be updated by the user. This greatly increases the amount POSTed. Not only that, but fields would need to be named something akin to name1, email1, name2, email2, etc. and that’s just a huge mess on the back-end.

My solution uses an invisible form outside of the table and javascript. The gist is once the submit button is pressed, move all input, select, and textarea elements from the desired “virtual form” to the invisible form and submit that invisible form.

In my example, which is basically identical to the above table, I’ve added the invisible form, the necessary javascript function, the class “form” to the table rows, and onclick="submitForm(this);" to the submit buttons.

You can add the “form” class to whichever container you want which defines your “form” as the javascript just takes the submit button and keeps going up the node tree until it hits a node with class="form".

Do note that because the submit button isn’t actually being clicked as far as the invisible form is concerned, the javascript converts the button into a hidden field so that the button name-value pair still appear in the POST.

Also note that since elements are being shuffled around, there is a slight “flicker” after the submit button is pressed, but before the page reloads. There are workarounds to this if absolutely necessary, but most users won’t care or even notice.

While all the code is very straightforward and easy to understand, it can be pretty powerful and hopefully prevent a lot of headaches and/or code rearrangement/hacks.

12 comments to Form and Table Row Nesting Workaround

You’re a freakin miracle worker. This worked for me like a charm in Chrome and FF. For IE I just nested the dynamic forms in the table “invalidly” (still posts in IE), and commented my submit buttons for the different browsers. Nice!

So glad I found this… Currently rewriting it to use jquery – it would be good to see that posted with this page, as well.

In our case, I need to navigate the DOM to gather the right children of the right parent element. I’ll be curious to see whether the separate handling of input, select, and textarea are needed for my jquery version.

Speechless.
I came across same problem, same scenario: N number of rows set dynamically from query result… and each MUST submitted independently.
After several unsuccessful tries to enclose a row table with form tag, start thinking of cumbersome, heavy loaded JS workaround solutions… and just one word to define it: Brilliant.
Thank You.