Est-il valide d'avoir un formulaire html dans un autre formulaire html?

331

Est-ce que c'est du HTML valide pour avoir ce qui suit:

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

Ainsi, lorsque vous soumettez "b", vous obtenez uniquement les champs dans le formulaire interne. Lorsque vous soumettez "a", vous obtenez tous les champs moins ceux de "b".

Si ce n'est pas possible, quelles solutions de contournement pour cette situation sont disponibles?

allyourcode
la source
28
Il me semble que c'est en fait un besoin très courant qui est familier des interfaces db - Si un formulaire met à jour la table A et que cette table a un champ lié à la table B, nous voulons souvent un moyen de mettre à jour ou de créer des entrées pour cela champ lié sans avoir à quitter le formulaire actuel. Les sous-formulaires imbriqués seraient une manière très intuitive de le faire (et c'est l'interface utilisateur implémentée par plusieurs bases de données de bureau).
monotasker
3
Ce n'est pas valable. Il existe des solutions de contournement, mais vous devez utiliser une autre méthode pour obtenir ces données. Considérez un formulaire envoyant toutes les données à un script de messagerie PHP, qui soumet ensuite la partie (la partie de a) comme un seul e-mail, et la partie (la partie de b) comme un autre e-mail. Ou dans une base de données, ou quoi que vous fassiez avec ces données. Des formulaires d'emboîtement peuvent être faits mais ce n'est PAS la réponse!
2
doublon possible de Pouvez-vous imbriquer des formulaires html?
utilisateur
La question est bonne, mais une recherche rapide sur Google (sans même cliquer sur les liens fournis) révèle si les formulaires dans les formulaires sont valides ou non. Personnellement, j'ai aimé la réponse @Andreas.
Jarett Lloyd

Réponses:

380

A. Ce n'est pas du HTML valide ni du XHTML

Dans la spécification officielle W3C XHTML, la section B. «Interdictions d'éléments», stipule que:

"form must not contain other form elements."

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

Quant à l'ancienne spécification HTML 3.2 , la section sur l'élément FORMS indique que:

"Chaque formulaire doit être inclus dans un élément FORM. Il peut y avoir plusieurs formulaires dans un même document, mais l'élément FORM ne peut pas être imbriqué."

B. La solution de contournement

Il existe des solutions de contournement utilisant JavaScript sans avoir à imbriquer les balises de formulaire.

"Comment créer un formulaire imbriqué." (malgré le titre, il ne s'agit pas de balises de formulaire imbriquées, mais d'une solution de contournement JavaScript).

Réponses à cette question StackOverflow

Remarque: Bien que l'on puisse tromper les validateurs W3C pour passer une page en manipulant le DOM via des scripts, ce n'est toujours pas du HTML légal. Le problème avec l'utilisation de telles approches est que le comportement de votre code n'est plus garanti sur tous les navigateurs. (puisque ce n'est pas standard)

GeneQ
la source
4
Voir mon commentaire ci-dessus .... C'est une merveilleuse réponse, un excellent travail, mais une terrible pratique. Vous pouvez faire exactement la même chose avec moins de tracas en soumettant toutes les données à un script PHP et en divisant et en envoyant à leurs propres destinations à partir de là. Bien que vous ayez répondu à la question, ce qui est formidable, c'est juste une mauvaise pratique inutile car vous pourriez le faire de la bonne manière en moins de temps.
53

Si quelqu'un trouve ce post ici, c'est une excellente solution sans avoir besoin de JS. Utilisez deux boutons d'envoi avec des attributs de nom différents vérifiez dans la langue de votre serveur quel bouton d'envoi a été enfoncé car un seul d'entre eux sera envoyé au serveur.

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

Le côté serveur pourrait ressembler à ceci si vous utilisez php:

<?php
    if(isset($_POST['save']))
        echo "Stored!";
    else if(isset($_POST['delete']))
        echo "Deleted!";
    else
        echo "Action is missing!";
?>
Andreas
la source
Ce n'est pas la même chose, dans ce cas vous voulez aller sur la même page et faire différentes actions, avec 2 formulaires vous pouvez aller sur différentes pages et / OU avoir des informations différentes envoyées dans chaque cas.
Luis Tellez
Vous pouvez utiliser un fichier php comme wrapper et inclure n'importe quel fichier que vous voulez si vous voulez le code dans différents fichiers. Donc au lieu de (echo "stored!";) Vous pourriez écrire (inclure "a.php";)
Andreas
J'ai plusieurs boutons de suppression dans mon formulaire (la raison pour laquelle je venais ici en considérant un formulaire imbriqué) 1 pour chaque enregistrement et une case à cocher de liste sur chacun pour effectuer une suppression en bloc. Votre réponse m'a incité à repenser mon plan en pensant maintenant que je devrais nommer les boutons pour la suppression individuelle avec un identifiant numérique et la suppression en bloc comme cela. Il fait php faire le tri.
Chris
@Andreas est sur l'argent. C'est la solution naturelle pour varier la façon dont la saisie du formulaire est interprétée. Si vous utilisez Post / Redirect / Get, la destination peut également varier. Cependant, si vous n'avez pas la flexibilité côté serveur pour combiner vos actions en un seul point de terminaison «aORb», je pense que vous êtes coincé avec un hack, je le crains.
27

HTML 4.x et HTML5 interdisent les formulaires imbriqués, mais HTML5 permettra une solution de contournement avec l'attribut "form" ("propriétaire du formulaire").

Quant à HTML 4.x, vous pouvez:

  1. Utilisez un ou plusieurs formulaires supplémentaires avec uniquement des champs cachés et JavaScript pour définir ses entrées et soumettre le formulaire.
  2. Utilisez CSS pour aligner plusieurs formulaires HTML pour ressembler à une seule entité - mais je pense que c'est trop difficile.
Nishi
la source
1
Je ne sais pas pourquoi cela a été rejeté. Voici le lien vers la section W3C des propriétaires de formulaires: w3.org/TR/html5/…
SooDesuNe
5
@SooDesuNe votre lien est obsolète, voici le nouveau w3.org/TR/html5/forms.html#form-owner
chiliNUT
13

Comme d'autres l'ont dit, ce n'est pas du HTML valide.

Il semble que vous le fassiez pour positionner visuellement les formulaires les uns dans les autres. Si tel est le cas, faites simplement deux formulaires séparés et utilisez CSS pour les positionner.

user64075
la source
1
C'est ce que je pensais avoir besoin pour mon site Web, mais j'aimerais un exemple de la façon de procéder.
Brian Peterson
8

Non, la spécification HTML stipule qu'aucun FORM élément ne doit contenir un autre FORMélément.

David Grant
la source
5

Vous pouvez répondre très facilement à votre propre question en saisissant le code HTML dans le validateur W3 . (Il comporte un champ de saisie de texte, vous n'aurez même pas à mettre votre code sur un serveur ...)

(Et non, cela ne sera pas validé.)

Christian Studer
la source
5

utilisez plutôt une méthode javascript personnalisée dans l'attribut action du formulaire!

par exemple

<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>
Andreas Niedermair
la source
5

Une possibilité est d'avoir un iframe à l'intérieur du formulaire externe. L'iframe contient la forme intérieure. Assurez-vous d'utiliser la <base target="_parent" />balise à l'intérieur de la balise head de l'iframe pour que le formulaire se comporte comme faisant partie de la page principale.

Robin Manoli
la source
1

Non, ce n'est pas valable. Mais une "solution" peut être de créer une fenêtre modale en dehors de la forme "a" contenant la forme "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>

Cela peut être fait facilement si vous utilisez bootstrap ou matérialisez css. Je fais cela pour éviter d'utiliser iframe.

Jonathas Hortense
la source
0

Solution de contournement non JavaScript pour l'imbrication des balises de formulaire:

Parce que vous permettez

tous les champs moins ceux de "b".

lors de la soumission de "a", les éléments suivants fonctionneraient, en utilisant des formulaires Web standard sans astuces JavaScript sophistiquées:

Étape 1. Mettez chaque formulaire sur sa propre page Web.

Étape 2. Insérez un iframe où vous voulez que ce sous-formulaire apparaisse.

Étape 3. Bénéfice.

J'ai essayé d'utiliser un site Web de jeux de code pour montrer une démo, mais beaucoup d'entre eux interdisent d'incorporer leurs sites Web dans des iframes, même dans leur propre domaine.

ADJenks
la source
-1

Si vous avez besoin de votre formulaire pour soumettre / valider des données dans une base de données relationnelle 1: M, je recommanderais de créer un déclencheur de base de données "après insertion" sur la table A qui insérera les données nécessaires pour la table B.

cbWrites
la source
-2

Non, ce n'est pas valide mais vous pouvez tromper votre position de forme intérieure sur le HTMLavec l'aide CSSet l' jQueryutilisation. Créez d'abord un conteneur div à l'intérieur de votre formulaire parent, puis à tout autre endroit de la page, le div avec votre formulaire enfant (intérieur):

<form action="a">
    <input.../>
    <div class="row" id="other_form_container"></div>
    <input.../>
</form>

....

<div class="row" id="other_form">
    <form action="b">
        <input.../>
        <input.../>
        <input.../>
    </form>
</div>

Donnez à votre div de conteneur une hauteur stable

<style>
  #other_form_container {
    height:90px;
    position:relative;
  }
</style> 

Remerciez la position "other_form" par rapport à la division du conteneur.

<script>
  $(document).ready(function() {
    var pos = $("#other_form_container").position();
    $("#other_form").css({
      position: "absolute",
      top: pos.top - 40,
      left: pos.left + 7,
      width: 500,
    }).show();
  });
</script>

PS: Vous devrez jouer avec les chiffres pour que ça soit joli.

Yaroslav Varkhol
la source