Search code examples
htmlformsnested

How do you overcome the HTML form nesting limitation?


I know that XHTML doesn't support nested form tags and I have already read other answers here on Stack Overflow regarding this subject, but I still haven't figured out an elegant solution to the problem.

Some say you don't need it and that they can't think of a scenario where this would be needed. Well, I can't think of a scenario that I haven't needed it.

Let's see a very simple example:

You are making a blog app and you have a form with some fields for creating a new post and a toolbar with "actions" like "Save", "Delete", and "Cancel".

<form
 action="/post/dispatch/too_bad_the_action_url_is_in_the_form_tag_even_though_conceptually_every_submit_button_inside_it_may_need_to_post_to_a_diffent_distinct_url"
method="post">

    <input type="text" name="foo" /> <!-- several of those here -->
    <div id="toolbar">
        <input type="submit" name="save" value="Save" />
        <input type="submit" name="delete" value="Delete" />
        <a href="/home/index">Cancel</a>
    </div>
</form>

Our objective is to write the form in a way that doesn't require JavaScript, just plain old HTML form and submit buttons.

Since the action URL is defined in the Form tag and not in each submit button, our only option is to post to a generic URL and then start "if...then...else" to determine the name of the button that was submitted. Not very elegant, but our only choice, since we don't want to rely on JavaScript.

The only problem is that pressing "Delete", will submit ALL the form fields on the server even though the only thing needed for this action is a Hidden input with the post-id. Not a very big deal in this small example, but I have forms with hundreds (so to speak) of fields and tabs in my LOB applications that (because of requirements) have to submit everything in one go and in any case this seems very inefficient and a waste. If form nesting was supported, I would at least be able to wrap the "Delete" submit button inside its form with only the post-id field.

You may say "Just implement the "Delete" as a link instead of submit". This would be wrong on so many levels, but most importantly because Side-effect actions like "Delete" here, should never be a GET request.

So my question (particularly to those that say they haven't needed form nesting) is What do YOU do? Is there any elegant solution that I'm missing or the bottom line is really "Either require JavaScript or submit everything"?


Solution

  • I would implement this exactly as you described: submit everything to the server and do a simple if/else to check what button was clicked.

    And then I would implement a Javascript call tying into the form's onsubmit event which would check before the form was submitted, and only submit the relevant data to the server (possibly through a second form on the page with the ID needed to process the thing as a hidden input, or refresh the page location with the data you need passed as a GET request, or do an Ajax post to the server, or...).

    This way the people without Javascript are able to use the form just fine, but the server load is offset because the people who do have Javascript are only submitting the single piece of data needed. Getting yourself focused on only supporting one or the other really limits your options unnecessarily.

    Alternatively, if you're working behind a corporate firewall or something and everybody has Javascript disabled, you might want to do two forms and work some CSS magic to make it look like the delete button is part of the first form.