389

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?

TylerH
  • 20,799
  • 66
  • 75
  • 101
  • 30
    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 Feb 29 '12 at 19:38
  • 3
    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! –  May 16 '13 at 21:48
  • 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 May 08 '19 at 15:33

15 Answers15

434

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)

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
GeneQ
  • 7,485
  • 6
  • 37
  • 53
  • 4
    See my comment up above.... This is a wonderful answer, great work-around, but a terrible practice. You can do the exact same thing with less hassle submitting all the data to a PHP script and dividing and sending to their own destinations from there. Although, you did answer the question which is great, it's just a bad and pointless practice because you could do it the right way in less time. –  May 16 '13 at 21:51
71

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!";
?>
altocumulus
  • 21,179
  • 13
  • 61
  • 84
Andreas
  • 989
  • 1
  • 8
  • 10
  • 2
    This is not the same, in this case you want to go to the same page and do different actions, with 2 forms you can go to different pages And/ OR have different information sent in each case. – Luis Tellez Mar 10 '14 at 20:35
  • You could use a php file as wrapper and include any file you want if you want the code in different files. So instead of (echo "stored!";) you could write (include "a.php";) – Andreas Jun 27 '14 at 13:55
  • I have multiple delete buttons in my form (the reason i was coming here considering a nested form) 1 for each record and a list checkbox on each to do a bulk delete. Your response has prompted me to rethink my plan im thinking now that i should name the buttons for the individual delete with a numeric id and the bulk delete as that. Il make php do the sorting. – CodingInTheUK Mar 21 '15 at 18:01
  • @Andreas is on the money. This is the natural solution to vary how form input is interpreted. If you use Post/Redirect/Get then the destination can vary also. However, if you don't have the flexibility on the server side to combine your actions into a single 'aORb' endpoint then I think you're stuck with a hack I'm afraid. –  Feb 14 '16 at 22:31
36

HTML 4.x & HTML5 disallow nested forms, but HTML5 allows a workaround with the "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 it might be complicated to do.
Nishi
  • 10,634
  • 3
  • 27
  • 36
  • 1
    Not sure why this was down-voted. Here the link to the W3C section of form owners: http://www.w3.org/TR/html5/association-of-controls-and-forms.html#form-owner – SooDesuNe Jan 09 '11 at 16:11
  • 5
    @SooDesuNe your link is out of date, here is the new one http://www.w3.org/TR/html5/forms.html#form-owner – chiliNUT May 12 '14 at 19:33
15

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.

user64075
  • 583
  • 4
  • 10
9

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

Munam Yousuf
  • 431
  • 1
  • 6
  • 17
David Grant
  • 13,929
  • 3
  • 57
  • 63
6

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.

Robin Manoli
  • 2,162
  • 2
  • 25
  • 30
5

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>
5

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.)

Christian Studer
  • 24,947
  • 6
  • 46
  • 71
4

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.../>
Szel
  • 110
  • 1
  • 10
  • What if the methods are different though? If I need a POST method for one form and a GET method for another it won't work. – picklepirate28 Oct 01 '20 at 15:40
  • 1
    @delivey probably a bit late for you, but the documentation linked by @Szel also shows a `formmethod` attribute see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/submit#attr-formmethod – AxelTheGerman Sep 21 '21 at 08:59
3

no, see w3c

tliff
  • 1,714
  • 1
  • 16
  • 17
2

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.

jphortense
  • 131
  • 1
  • 11
2

Fast Solution: To obtain different validations to different forms and keep their submits in separated functions you can do this:

<form id="form1" onsubmit="alert('form1')"></form>
<form id="form2" onsubmit="alert('form2')"></form>

<div>
  <input form="form1" required />
  <input form="form1" required />

  <div>
      <input form="form2" required />
      <input form="form2" required />
      <button form="form2" type="submit">Send form2</button>
  </div>

  <input form="form1" required />
  <button form="form1" type="submit">Send form1</button>
</div>
Ítalo Sérvio
  • 128
  • 1
  • 4
0

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.

ADJenks
  • 2,973
  • 27
  • 38
0

You are trying to implement nested form which is not supported in HTML.

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.

Workaround

You can implement this functionality with some change in HTML and JavaScript. (without using html forms)

Steps
1. Create both forms with div tag as follows (do not use form tag)

<div id="form_a">
 <input.../>
     <div id="form_b">
        <input.../>
        <input.../>
        <button id="submit_b">Submit B</button>
     </div>
 <input.../>
 <button id="submit_a">Submit A</button>
</div >

2. Add JQuery and Ajax to submit each form data

    <script>
    // Submit form A data
    $('#submit_a').click( function() {
          $.ajax({
            url: 'ajax-url',
            type: 'post',
            dataType: 'json',
            data: $('#form_a input').not( "#form_b input" ).serialize(),
            success: function(data) {
                       // ... do something with the data...
                     }
        });
        });

   // Submit form B data
    $('#submit_b').click( function() {
          $.ajax({
            url: 'ajax-url',
            type: 'post',
            dataType: 'json',
            data: $('#form_b input').serialize(),
            success: function(data) {
                       // ... do something with the data...
                     }
        });
        });
    </script>
Irfan
  • 215
  • 2
  • 8
-2

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.

cbWrites
  • 5
  • 1