Pouvez-vous imbriquer des formulaires html?

451

Est-il possible d'imbriquer des formulaires html comme celui-ci

<form name="mainForm">
  <form name="subForm">
  </form>
</form>

pour que les deux formes fonctionnent? Mon ami a des problèmes avec cela, une partie des subFormœuvres, tandis qu'une autre partie n'en a pas.

Levi
la source
Il met en place un panier, où la quantité de mise à jour est à l'intérieur du formulaire qui garde la trace des totaux. Personnellement, je ne ferais pas ça, mais il a du mal à faire fonctionner ça.
Levi
1
Il semble qu'il serait préférable d'utiliser Javascript pour copier des valeurs d'un formulaire à l'autre, plutôt que d'essayer de les imbriquer. Je ne pense pas que l'imbrication fonctionnera.
Ben
15
Ancienne question, mais pour répondre au commentaire, des formulaires d'imbrication pourraient être nécessaires pour éviter JavaScript. Je rencontre cela parce que je voudrais imbriquer des formulaires pour les boutons de réinitialisation de sous-formulaire, qui ne nécessitent pas l'activation de JavaScript.
vol7ron
1
Copie possible de: stackoverflow.com/questions/597596/…
yankee

Réponses:

459

En un mot, non. Vous pouvez avoir plusieurs formulaires dans une page, mais ils ne doivent pas être imbriqués.

Du projet de travail html5 :

4.10.3 Le form élément

Modèle de contenu:

Contenu de flux, mais sans descendants d'éléments de formulaire.

Craig
la source
126
Je suis d'accord avec la réponse, mais pour en demander une autre, pourquoi pas? Pourquoi HTML n'autorise-t-il pas l'imbrication des formulaires? Pour moi, cela semble être une limitation sans laquelle nous serions mieux. Il existe de nombreux exemples où l'utilisation de formulaires imbriqués serait plus facile à programmer (c'est-à-dire en utilisant un formulaire de téléchargement de photos avec un formulaire de modification de profil).
Ryan
20
@Nilzor, il ne demande pas si cela ne peut pas être fait, il demande pourquoi pas. Je suis d'accord; l'imbrication des formulaires est en fait très utile. Donc, si vous avez une application d'une page avec des onglets, chaque onglet est son propre formulaire (vous pouvez donc le soumettre pour enregistrer la progression), et ils sont tous enveloppés dans un formulaire, que vous pouvez soumettre pour tout enregistrer. Ça a du sens pour moi.
Rob Grant
5
Je suis d'accord avec ce que les autres ont dit. Cette limitation semble arbitraire et nuisible.
aroth
12
Nous avons donc besoin de HTML 5.1 avec des formulaires imbriqués.
Hector
3
Le problème avec les formulaires imbriqués est l'architecture du formulaire dans HTML, où l'action dans ce formulaire conduit à un événement de soumission. La question se pose les cheveux sur ce qui doit être soumis. Vous pouvez avoir plusieurs champs dans un formulaire ou plusieurs formulaires dans un div, mais cela n'a pas vraiment de sens d'avoir des formulaires dans un formulaire. Si le contenu va de pair, ce n'est qu'une forme; si le contenu est soumis séparément, ce sont vraiment des formulaires séparés qui n'ont pas besoin d'un formulaire externe.
Kyle Baker
96

J'ai rencontré un problème similaire, et je sais que ce n'est pas une réponse à la question, mais cela peut être utile à quelqu'un avec ce genre de problème:
s'il est nécessaire de mettre les éléments de deux ou plusieurs formes dans une séquence donnée , l' attribut HTML5 <input> form peut être la solution.

Sur http://www.w3schools.com/tags/att_input_form.asp :

  1. L' attribut de formulaire est nouveau dans HTML5.
  2. Spécifie à quel <form>élément <input>appartient un élément. La valeur de cet attribut doit être l'attribut id d'un <form>élément du même document.

Scénario :

  • input_Form1_n1
  • input_Form2_n1
  • input_Form1_n2
  • input_Form2_n2

Réalisation :

<form id="Form1" action="Action1.php" method="post"></form>
<form id="Form2" action="Action2.php" method="post"></form>

<input type="text" name="input_Form1_n1" form="Form1" />
<input type="text" name="input_Form2_n1" form="Form2" />
<input type="text" name="input_Form1_n2" form="Form1" />
<input type="text" name="input_Form2_n2" form="Form2" />

<input type="submit" name="button1" value="buttonVal1" form="Form1" />
<input type="submit" name="button2" value="buttonVal2" form="Form2" />

Ici vous trouverez la compatibilité du navigateur.

Cliff Burton
la source
1
ça marche super! devrait être inclus dans la réponse acceptée
Nahouto
1
Juste pour pointer le tableau de prise en charge du navigateur: caniuse.com/#feat=form-attribute Reprise - cela fonctionne partout (Chrome, Firefox, Opera, Egde, Safari, navigateur Android ...) sauf IE (y compris le dernier à ce jour v11) .
dmikam
@ cliff-burton, quelle est la différence ici? Je peux juste voir les entrées en dehors du formulaire. Il lui faudrait encore JS pour soumettre les deux formulaires en même temps. N'est-ce pas?
sdlins
Euh, ça fait longtemps depuis la dernière fois que j'ai utilisé cela mais je pense que JS n'est pas requis pour soumettre le formulaire. À condition que le <input type="submit"soit lié à son <form>qui spécifie un action, le <input />ou les liés à ce même <form>seront utilisés dans cette demande
Cliff Burton
90

Le deuxième formulaire sera ignoré, voir l' extrait de WebKit par exemple:

bool HTMLParser::formCreateErrorCheck(Token* t, RefPtr<Node>& result)
{
    // Only create a new form if we're not already inside one.
    // This is consistent with other browsers' behavior.
    if (!m_currentFormElement) {
        m_currentFormElement = new HTMLFormElement(formTag, m_document);
        result = m_currentFormElement;
        pCloserCreateErrorCheck(t, result);
    }
    return false;
}
Vitalii Fedorenko
la source
43

Le html simple ne peut pas vous permettre de faire cela. Mais avec javascript, vous pouvez le faire. Si vous utilisez javascript / jquery, vous pouvez classer vos éléments de formulaire avec une classe, puis utiliser serialize () pour sérialiser uniquement ces éléments de formulaire pour le sous-ensemble des éléments que vous souhaitez soumettre.

<form id="formid">
    <input type="text" class="class1" />
    <input type="text" class="class2">
</form>

Ensuite, dans votre javascript, vous pouvez le faire pour sérialiser les éléments de classe 1

$(".class1").serialize();

Pour la classe 2, vous pourriez faire

$(".class2").serialize();

Pour l'ensemble du formulaire

$("#formid").serialize();

ou simplement

$("#formid").submit();
user2420019
la source
31

Si vous utilisez AngularJS, toutes les <form>balises à l'intérieur de votre ng-appsont remplacées au moment de l'exécution par des ngFormdirectives conçues pour être imbriquées.

Dans les formes angulaires peuvent être imbriquées. Cela signifie que le formulaire externe est valide lorsque tous les formulaires enfants sont également valides. Cependant, les navigateurs n'autorisent pas l'imbrication d' <form>éléments, donc Angular fournit la ngFormdirective qui se comporte de manière identique <form>mais peut être imbriquée. Cela vous permet d'avoir des formulaires imbriqués, ce qui est très utile lorsque vous utilisez des directives de validation angulaire dans des formulaires générés dynamiquement à l'aide de la ngRepeatdirective. ( source )

roufamatic
la source
C'était la réponse que je cherchais :) Et oui, il est logique d'imbriquer le formulaire parce que si vous avez plusieurs onglets mais que vous souhaitez effectuer la validation sur un seul onglet, vous pouvez le faire avec le formulaire imbriqué.
NeverGiveUp161
Est-ce la même chose pour les composants Web?
Gangadhar JANNU
31

Comme c'est 2019, je voudrais donner une réponse mise à jour à cette question. Il est possible d'obtenir le même résultat que les formes imbriquées, mais sans les imbriquer. HTML5 a introduit l'attribut de formulaire. Vous pouvez ajouter l'attribut de formulaire à des contrôles de formulaire en dehors d'un formulaire pour les lier à un élément de formulaire spécifique (par id).

https://www.impressivewebs.com/html5-form-attribute/

De cette façon, vous pouvez structurer votre html comme ceci:

<form id="main-form" action="/main-action" method="post"></form>
<form id="sub-form"  action="/sub-action"  method="post"></form>

<div class="main-component">
    <input type="text" name="main-property1" form="main-form" />
    <input type="text" name="main-property2" form="main-form" />

    <div class="sub-component">
        <input type="text" name="sub-property1" form="sub-form" />
        <input type="text" name="sub-property2" form="sub-form" />
        <input type="submit" name="sub-save" value="Save" form="sub-form" />
    </div>

    <input type="submit" name="main-save" value="Save" form="main-form" />
</div>

L'attribut formulaire est pris en charge par tous les navigateurs modernes. IE ne le prend pas en charge, mais IE n'est plus un navigateur, mais plutôt un outil de compatibilité, comme l'a confirmé Microsoft lui-même: https://www.zdnet.com/article/microsoft-security-chief-ie-is-not-a -browser-so-stop-using-it-as-your-default / . Il est temps que nous cessions de nous soucier de faire fonctionner les choses dans IE.

https://caniuse.com/#feat=form-attribute
https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fae-form

De la spécification html:

Cette fonctionnalité permet aux auteurs de contourner le manque de prise en charge des éléments de formulaire imbriqués.

Créatif
la source
Quelle est la différence ici? Je peux juste voir les entrées en dehors du formulaire. Il lui faudrait encore JS pour soumettre les deux formulaires en même temps. N'est-ce pas?
sdlins
@sdlins Non, l'idée est de styliser le composant principal et le sous-composant selon leur apparence, imbriqués. Les 2 balises de formulaire réelles seront invisibles. Chaque bouton d'envoi déclenchera sa soumission respective. Aucun javascript n'est requis.
Creative
si vous ne voulez déclencher que l'un ou l' autre formulaire, ok. Mais comment cela se résoudrait-il lorsque vous auriez besoin de déclencher le & quot; parent & quot; forme avec ses formes enfant comme c'était un et sans js?
sdlins
@sdlins ce n'est pas le sujet de cette question. La question porte sur 2 formes différentes, mais faites-les imbriquer. Je me demande pourquoi vous voulez avoir 2 formulaires mais toujours 1 fonction soumettre? Tu ne peux pas avoir juste 1 formulaire alors? Vous devrez en effet recourir au javascript pour quelque chose d'aussi bizarre que cela: P
Creative
oui, vous avez raison, ce n'est pas la question OP. Je posterai le mien. Je vous remercie!
sdlins
12

Une autre façon de contourner ce problème, si vous utilisez un langage de script côté serveur qui vous permet de manipuler les données publiées, est de déclarer votre formulaire html comme ceci:

<form>
<input name="a_name"/>
<input name="a_second_name"/>
<input name="subform[another_name]"/>
<input name="subform[another_second_name]"/>
</form>

Si vous imprimez les données publiées (j'utiliserai PHP ici), vous obtiendrez un tableau comme celui-ci:

//print_r($_POST) will output :
    array(
    'a_name' => 'a_name_value',
    'a_second_name' => 'a_second_name_value',
    'subform' => array(
      'another_name' => 'a_name_value',
      'another_second_name' => 'another_second_name_value',
      ),
    );

Ensuite, vous pouvez simplement faire quelque chose comme:

$my_sub_form_data = $_POST['subform'];
unset($_POST['subform']);

Votre $ _POST a maintenant seulement vos données de "formulaire principal", et vos données de sous-formulaire sont stockées dans une autre variable que vous pouvez manipuler à volonté.

J'espère que cela t'aides!

Pierre
la source
11

Comme Craig l'a dit, non.

Mais, en ce qui concerne votre commentaire à pourquoi :

Il pourrait être plus facile d'utiliser 1 <form>avec les entrées et le bouton "Mettre à jour", et d'utiliser la copie des entrées cachées avec le bouton "Soumettre la commande" dans un autre <form>.

Jonathan Lonowski
la source
J'ai fait ma page de panier comme ça, il est juste allé dans un sens différent et ne voulait pas le changer. Je n'étais pas sûr non plus que sa méthode soit aussi valable.
Levi
9

Notez que vous n'êtes pas autorisé à imbriquer des éléments FORM!

http://www.w3.org/MarkUp/html3/forms.html

https://www.w3.org/TR/html4/appendix/changes.html#hA.3.9 (la spécification html4 ne note aucune modification concernant les formes d'imbrication de 3.2 à 4)

https://www.w3.org/TR/html4/appendix/changes.html#hA.1.1.12 (la spécification html4 ne note aucune modification concernant les formes d'imbrication de 4.0 à 4.1)

https://www.w3.org/TR/html5-diff/ (la spécification html5 ne note aucun changement concernant les formes d'imbrication de 4 à 5)

https://www.w3.org/TR/html5/forms.html#association-of-controls-and-forms commente "Cette fonctionnalité permet aux auteurs de contourner le manque de prise en charge des éléments de formulaire imbriqués", mais ne ne cite pas où cela est spécifié, je pense qu'ils supposent que nous devrions supposer que cela est spécifié dans la spécification html3 :)

Mark Peterson
la source
23
Je ne sais pas pourquoi vous postez sur une question à laquelle il a été répondu 3 ans et demi, mais plus problématique est le lien vers HTML3 qui n'a pas été une recommandation depuis longtemps.
Aidiakapi
7
C'est une référence à la durée de la réponse à la question sous-jacente, que j'ai jugée constructive. J'ai également trouvé le sans tact "Notez que vous n'êtes pas autorisé à imbriquer les éléments FORM!" dans la spécification pour être humoristique.
Mark Peterson
1
C'est un problème car je dois insérer une API qui est un formulaire et parce que l'application .net (qui enveloppe une balise <form> autour de tout). Comment surmontez-vous ce problème?
jelly46
4

Une solution de contournement simple consiste à utiliser un iframe pour contenir le formulaire "imbriqué". Visuellement, le formulaire est imbriqué, mais du côté du code, il se trouve dans un fichier html distinct.

Ezion
la source
1
Le temps est
compté
3

Vous pouvez également utiliser formaction = "" à l'intérieur de la balise button.

<button type="submit" formaction="/rmDog" method='post' id="rmDog">-</button>

Cela serait imbriqué dans le formulaire d'origine en tant que bouton séparé.

Copain en chef
la source
cela ne répond pas à la question, mais cela m'a juste aidé à résoudre un autre problème que j'éprouvais alors à abandonner
codeAndStuff
ignorer ci-dessus (ne me laisserait pas éditer après 5 minutes ... hmm). une grande aide ici - exactement sur ce que j'essayais de faire ce matin. c'est pourquoi nous aimons tous SO
codeAndStuff
2

Même si vous pouviez le faire fonctionner dans un seul navigateur, rien ne garantit qu'il fonctionnerait de la même manière dans tous les navigateurs. Donc, bien que vous puissiez le faire fonctionner une partie du temps, vous ne pourrez certainement pas le faire fonctionner tout le temps.

Mike Hofer
la source
2

Vous auriez même des problèmes pour le faire fonctionner dans différentes versions du même navigateur. Alors évitez d'utiliser ça.

MP.
la source
2

Bien que je ne présente pas de solution aux formulaires imbriqués (cela ne fonctionne pas de manière fiable), je présente une solution de contournement qui fonctionne pour moi:

Scénario d'utilisation: Une superforme permettant de changer N éléments à la fois. Il a un bouton "Soumettre tout" en bas. Chaque élément souhaite avoir son propre formulaire imbriqué avec un bouton «Soumettre l'élément n ° N». Mais je ne peux pas ...

Dans ce cas, on peut effectivement utiliser une forme unique, et ensuite le nom des boutons soient submit_1.. submit_Net submitAllet le manipuler côté des serveurs, en ne regardant que params se terminant en _1si le nom du bouton était submit_1.

<form>
    <div id="item1">
        <input type="text" name="foo_1" value="23">
        <input type="submit" name="submit_1" value="Submit Item #1">
    </div>
    <div id="item2">
        <input type="text" name="foo_2" value="33">
        <input type="submit" name="submit_2" value="Submit Item #2">
    </div>
    <input type="submit" name="submitAll" value="Submit All Items">
</form>

Ok, donc pas vraiment une invention, mais ça fait l'affaire.

Peter V. Mørch
la source
1

A propos des formes d'imbrication: j'ai passé 10 ans un après-midi à essayer de déboguer un script ajax.

ma réponse / exemple précédent ne tenait pas compte du balisage html, désolé.

<form id='form_1' et al>
  <input stuff>
  <submit onClick='ajaxFunction(That_Puts_form_2_In_The_ajaxContainer)' >
  <td id='ajaxContainer></td>
</form>

form_2 échouait constamment en disant form_2 invalide.

Quand j'ai déplacé le ajaxContainer qui a produit form_2 <i>outside</i>de form_1, j'étais de retour dans les affaires. C'est la réponse à la question de savoir pourquoi on pourrait imbriquer des formes. Je veux dire, vraiment, à quoi sert l'ID sinon pour définir quel formulaire doit être utilisé? Il doit y avoir un meilleur travail, plus lisse.

larry
la source
1

Utilisez une balise de formulaire vide avant votre formulaire imbriqué

Testé et travaillé sur Firefox, Chrome

Non testé sur IE

<form name="mainForm" action="mainAction">
  <form></form>
  <form name="subForm"  action="subAction">
  </form>
</form>
Fatih
la source
lorsque j'ai essayé cela sur Chrome, il affiche ce <form name = "mainForm"> </form> <form name = "subForm"> </form>
ianace
1
Avez-vous essayé avec le bouton soumettre. J'ai utilisé cette méthode plusieurs fois et j'ai toujours travaillé.
Fatih
10
Il s'agit d'une violation de la spécification et son utilisation implore de futurs problèmes.
Oskar Berggren
Les nouvelles versions de webkit suppriment simplement les éléments de formulaire imbriqués.
woens
0

Bien que la question soit assez ancienne et je suis d'accord avec @everyone que l'imbrication de formulaire n'est pas autorisée en HTML

Mais ce quelque chose que tout le monde voudra peut-être voir

où vous pouvez pirater (je l'appelle un hack car je suis sûr que ce n'est pas légitime) html pour permettre au navigateur d'avoir une forme imbriquée

<form id="form_one" action="http://apple.com">
  <div>
    <div>
        <form id="form_two" action="/">
            <!-- DUMMY FORM TO ALLOW BROWSER TO ACCEPT NESTED FORM -->
      </form>
    </div>
      <br/>
    <div>
      <form id="form_three" action="http://www.linuxtopia.org/">
          <input type='submit' value='LINUX TOPIA'/>
      </form>
    </div>
      <br/>

    <div>
      <form id="form_four" action="http://bing.com">
          <input type='submit' value='BING'/>
      </form>
    </div>
      <br/>  
    <input type='submit' value='Apple'/>
  </div>  
</form>

JS FIDDLE LINK

http://jsfiddle.net/nzkEw/10/

Viren
la source
0

Non, vous ne pouvez pas avoir de formulaire imbriqué. Au lieu de cela, vous pouvez ouvrir un modal qui contient un formulaire et effectuer une soumission de formulaire Ajax.

Shree Sthapit
la source
0

Vraiment pas possible ... Je ne pouvais pas imbriquer de balises de formulaire ... Cependant j'ai utilisé ce code:

<form>
    OTHER FORM STUFF

    <div novalidate role="form" method="post" id="fake_form_id_0" data-url="YOUR_POST_URL">
        THIS FORM STUFF
    </div>
</form>

avec {% csrf_token %}et des trucs

et appliqué un peu de JS

var url = $(form_id).attr("data-url");

$.ajax({
  url: url,
  "type": "POST",
   "data": {
    'csrfmiddlewaretoken': '{{ csrf_token }}',
    'custom-param-attachment': 'value'
  },
  success: function (e, data) {
      if (e.is_valid) {
         DO STUFF
      }
  }
});
diogosimao
la source
-1

Aujourd'hui, je suis également resté coincé dans le même problème, et résoudre le problème, j'ai ajouté un contrôle utilisateur et
sur ce contrôle, j'utilise ce code

<div class="divformTagEx">

</div>

<asp:Literal runat="server" ID="litFormTag" Visible="false">
'<div> <form  style="margin-bottom: 3;" action="http://login.php" method="post" name="testformtag"></form> </div>'</asp:Literal>

et sur l'événement PreRenderComplete de la page, appelez cette méthode

private void InitializeJavaScript()
{
        var script = new StringBuilder();
        script.Append("$(document).ready(function () {");
        script.Append("$('.divformTagEx').append( ");
        script.Append(litFormTag.Text);
        script.Append(" )");
        script.Append(" });");
        ScriptManager.RegisterStartupScript(this, GetType(), "nestedFormTagEx", script.ToString(), true);
    }

Je crois que cela vous aidera.

Shivanshu
la source
-1

Avant de savoir que je n'étais pas censé faire cela, j'avais des formulaires imbriqués dans le but d'avoir plusieurs boutons d'envoi. Ran de cette façon pendant 18 mois, des milliers de transactions d'inscription, personne ne nous a appelé pour des difficultés.

Les formulaires imbriqués m'ont donné une pièce d'identité à analyser pour prendre la bonne mesure. Je n'ai pas cassé jusqu'à ce que j'essaie de joindre un champ à l'un des boutons et que Validate se soit plaint. Ce n'était pas un gros problème pour le démêler - j'ai utilisé une chaîne explicite sur le formulaire externe, donc peu importait la soumission et le formulaire ne correspondait pas. Ouais, ouais, j'aurais dû prendre les boutons d'une soumission à un onclick.

Le fait est qu'il y a des circonstances où il n'est pas entièrement cassé. Mais "pas entièrement cassé" est peut-être une norme trop basse pour laquelle tirer :-)

Roger Krueger
la source