355
votes

Is it valid html to have the following:

<form action="a">
    <input.../>
    <form action="b">
        <input.../>
        <input.../>
        <input.../>
    </form>
    <input.../>
</form>

So when you submit "b" you only get the fields within the inner form. When you submit "a" you get all fields minus those within "b".

If it isn't possible, what workarounds for this situation are available?

13
It seems to me that this is actually a very common need that is familiar from db interfaces -- If a form updates table A, and that table has a field linked to table B, we often want a way to update or create entries for that linked field without having to leave the current form. Nested sub-forms would be a very intuitive way to do it (and is the ui implemented by several desktop databases). - monotasker
It isn't valid. There are workarounds but you should be using another method to obtain this data. Consider one form sending all the data to a PHP mail script, which then submits part (the part from a) as one email, and part (the part from b) as another email. Or into a database, or whatever you're doing with this data. Nesting forms can be done but it is NOT the answer! - user1596138
possible duplicate of Can you nest html forms? - user
The question is good, but a quick google search (without clicking the provided links even) reveals whether forms within forms is valid or not. i, personally, liked @Andreas answer. - Jarett Lloyd

13 Answers

411
votes

A. It is not valid HTML nor XHTML

In the official W3C XHTML specification, Section B. "Element Prohibitions", states that:

"form must not contain other form elements."

http://www.w3.org/TR/xhtml1/#prohibitions

As for the older HTML 3.2 spec, the section on the FORMS element states that:

"Every form must be enclosed within a FORM element. There can be several forms in a single document, but the FORM element can't be nested."

B. The Workaround

There are workarounds using JavaScript without needing to nest form tags.

"How to create a nested form." (despite title this is not nested form tags, but a JavaScript workaround).

Answers to this StackOverflow question

Note: Although one can trick the W3C Validators to pass a page by manipulating the DOM via scripting, it's still not legal HTML. The problem with using such approaches is that the behavior of your code is now not guaranteed across browsers. (since it's not standard)

58
votes

In case someone find this post here is a great solution without the need of JS. Use two submit buttons with different name attributes check in your server language which submit button was pressed cause only one of them will be sent to the server.

<form method="post" action="ServerFileToExecute.php">
    <input type="submit" name="save" value="Click here to save" />
    <input type="submit" name="delete" value="Click here to delete" />
</form>

The server side could look something like this if you use php:

<?php
    if(isset($_POST['save']))
        echo "Stored!";
    else if(isset($_POST['delete']))
        echo "Deleted!";
    else
        echo "Action is missing!";
?>
29
votes

HTML 4.x & HTML5 disallow nested forms, but HTML5 will allow a workaround with "form" attribute ("form owner").

As for HTML 4.x you can:

  1. Use an extra form(s) with only hidden fields & JavaScript to set its input's and submit the form.
  2. Use CSS to line up several HTML form to look like a single entity - but I think that's too hard.
14
votes

As others have said, it is not valid HTML.

It sounds like your are doing this to position the forms visually within each other. If that is the case, just do two separate forms and use CSS to position them.

8
votes

No, the HTML specification states that no FORM element should contain another FORM element.

6
votes

A possibility is to have an iframe inside the outer form. The iframe contains the inner form. Make sure to use the <base target="_parent" /> tag inside the head tag of the iframe to make the form behave as part of the main page.

5
votes

You can answer your own question very easily by inputting the HTML code into the W3 Validator. (It features a text input field, you won't even have to put your code on a server...)

(And no, it won't validate.)

5
votes

rather use a custom javascript-method inside the action attribute of the form!

eg

<html>
    <head>
        <script language="javascript" type="text/javascript">
        var input1 = null;
        var input2 = null;
        function InitInputs() {
            if (input1 == null) {
                input1 = document.getElementById("input1");
            }
            if (input2 == null) {
                input2 = document.getElementById("input2");
            }

            if (input1 == null) {
                alert("input1 missing");
            }
            if (input2 == null) {
                alert("input2 missing");
            }
        }
        function myMethod1() {
            InitInputs();
            alert(input1.value + " " + input2.value);
        }
        function myMethod2() {
            InitInputs();
            alert(input1.value);
        }
        </script>
    </head>
    <body>
        <form action="javascript:myMethod1();">
            <input id="input1" type="text" />
            <input id="input2" type="text" />
            <input type="button" onclick="myMethod2()" value="myMethod2"/>
            <input type="submit" value="myMethod1" />
        </form>
    </body>
</html>
4
votes
1
votes

No, it is not valid. But a "solution" can be creating a modal window outside of form "a" containing the form "b".

<div id="myModalFormB" class="modal">
    <form action="b">
        <input.../>
        <input.../>
        <input.../>
        <button type="submit">Save</button>
    </form>
</div>

<form action="a">
    <input.../>
    <a href="#myModalFormB">Open modal b </a>
    <input.../>
</form>

It can be easily done if you are using bootstrap or materialize css. I'm doing this to avoid using iframe.

0
votes

A non-JavaScript workaround for nesting form tags:

Because you allow for

all fields minus those within "b".

when submitting "a", the following would work, using regular web-forms without fancy JavaScript tricks:

Step 1. Put each form on its own web page.

Step 2. Insert an iframe wherever you want this sub-form to appear.

Step 3. Profit.

I tried to use a code-playground website to show a demo, but many of them prohibit embedding their websites in iframes, even within their own domain.

0
votes

As workaround you could use formaction attribute on submit button. And just use different names on your inputs.

<form action="a">
<input.../>
    <!-- Form 2 inputs -->
    <input.../>
    <input.../>
    <input.../>
    <input type="submit" formaction="b">

</form>
<input.../>
-1
votes

If you need your form to submit/commit data to a 1:M relational database, I would recommend creating an "after insert" DB trigger on table A that will insert the necessary data for table B.