Forme à l'intérieur d'une table

239

J'inclus certains formulaires dans un tableau HTML pour ajouter de nouvelles lignes et mettre à jour les lignes actuelles. Le problème que je reçois est que lorsque j'inspecte les formulaires dans mes outils de développement, je vois que les éléments du formulaire sont fermés immédiatement après l'ouverture (les entrées, etc. ne sont pas incluses dans le formulaire).

En tant que tel, l'envoi d'un formulaire n'inclut pas les champs.

La ligne du tableau et les entrées sont les suivantes:

<tr>
    <form method="post" action="">
        <td>
            <input type="text" name="job_num">
        </td>

        <td>
            <input type="text" name="desc">
        </td>
    </form>
</tr>

Toute aide serait formidable, merci.

Alex
la source
6
<form>ne peut pas être mis à l'intérieur <tr>.
Derek 朕 會 功夫
1
Et vous avez oublié de fermer le <tr>.
Derek 朕 會 功夫
1
Utilisez display: table-row pour votre formulaire et abandonnez complètement la balise table. Voir ma réponse ici: stackoverflow.com/a/15600151/1038812
Matthew
Ça ne peut pas, mais ça marche ...
Sandburg

Réponses:

371

Un formulaire n'est pas autorisé à être un élément enfant d'un table, tbodyou tr. Tenter d'en mettre un aura tendance à faire déplacer le formulaire vers le navigateur pour qu'il apparaisse après le tableau (tout en laissant son contenu - lignes du tableau, cellules du tableau, entrées, etc. - derrière).

Vous pouvez avoir une table entière dans un formulaire. Vous pouvez avoir un formulaire à l'intérieur d'une cellule de tableau. Vous ne pouvez pas avoir une partie d'une table dans un formulaire.

Utilisez un formulaire autour de la table entière. Utilisez ensuite le bouton Soumettre cliqué pour déterminer la ligne à traiter (pour être rapide) ou traiter chaque ligne (autorisant les mises à jour groupées).

HTML 5 introduit l' form attribut . Cela vous permet de fournir un formulaire par ligne en dehors du tableau , puis d'associer tous les contrôles de formulaire d'une ligne donnée à l'un de ces formulaires à l'aide de its id.

Quentin
la source
2
Faites attention en utilisant un formulaire pour toute la table, tous les champs seront envoyés au serveur, même s'ils sont vides. Cela pourrait être une énorme quantité de données !!! S'il vous plaît pour une utilisation en masse / publique, préférez utiliser une boîte de dialogue (formulaire non dans le tableau) ouverte à partir d'un bouton de cette ligne.
Loenix
1
@Loenix: Il est très peu probable que vous mettiez suffisamment de données dans le tableau pour que cela constitue un fardeau important sur la bande passante des gens (du moins par rapport à la taille d'une page Web typique). OTOH, obliger les utilisateurs à charger une autre page entre choisir d'éditer une ligne et pouvoir apporter leurs modifications, serait une interaction supplémentaire ennuyeuse qu'ils devraient effectuer.
Quentin
1
Vous n'avez pas besoin d'un bouton d'édition pour la solution proposée dans la question d'origine.
Quentin
1
Pourquoi l'interdit à l' <form>intérieur des <table>normes?
1234ru
4
@Qentin assez juste. C'est dommage que cela se maintienne après deux décennies sans raison évidente.
1234ru
188

Utilisez l' attribut "formulaire" , si vous souhaitez enregistrer votre balisage:

<form method="GET" id="my_form"></form>

<table>
    <tr>
        <td>
            <input type="text" name="company" form="my_form" />
            <button type="button" form="my_form">ok</button>
        </td>
    </tr>
</table>

(* Champs de formulaire en dehors de la balise <form>)

Voir aussi les 2 premiers commentaires

Vladimir
la source
64
Notez que cette solution n'est valable qu'avec HTML5.
threenplusone
18
en plus, ça ne marchera pas dans internet explorer plus d'infos ici
Souhaieb Besbes
1
Le statut de l'attribut de formulaire est `` à l'étude '', ce qui signifie que vous devez être très patient developer.microsoft.com/en-us/microsoft-edge/platform/status/… pendant ce temps, vous pouvez essayer ce polyfill et voir s'il fonctionne pour vous. stackoverflow.com/a/26696165/648484
Souhaieb Besbes
1
Semble "en développement" maintenant et peut être utilisé
user1156544
1
@ user1156544 Il est désormais pris en charge dans Edge, mais pas dans IE. Si vous devez prendre en charge IE, vous n'avez pas de chance avec cette solution. Mon plan est d'utiliser deux tables pour deux éléments de formulaire (je ne peux pas croire que je doive le faire). Merci Microsoft!
Pluton
41

Si vous voulez une « grille modifiable » soit une table comme la structure qui vous permet de faire l' une des lignes d' une forme, utilisez CSS qui imite la mise en page de la balise TABLE: display:table, display:table-rowet display:table-cell.

Il n'est pas nécessaire d'envelopper votre table entière dans un formulaire et pas besoin de créer un formulaire et une table séparés pour chaque ligne apparente de votre table.

Essayez plutôt ceci:

<style>
DIV.table 
{
    display:table;
}
FORM.tr, DIV.tr
{
    display:table-row;
}
SPAN.td
{
    display:table-cell;
}
</style>
...
<div class="table">
    <form class="tr" method="post" action="blah.html">
        <span class="td"><input type="text"/></span>
        <span class="td"><input type="text"/></span>
    </form>
    <div class="tr">
        <span class="td">(cell data)</span>
        <span class="td">(cell data)</span>
    </div>
    ...
</div>

Le problème avec l'encapsulation de la TABLE entière dans un FORMULAIRE est que tous les éléments du formulaire seront envoyés lors de la soumission (peut-être que cela est souhaité mais probablement pas). Cette méthode vous permet de définir un formulaire pour chaque "ligne" et d'envoyer uniquement cette ligne de données lors de la soumission.

Le problème avec enrouler une balise FORM autour d'une balise TR (ou TR autour d'un FORM) est que c'est du HTML non valide. Le FORMULAIRE permettra toujours de soumettre comme d'habitude mais à ce stade le DOM est cassé. Remarque: Essayez d'obtenir les éléments enfants de votre FORM ou TR avec JavaScript, cela peut conduire à des résultats inattendus.

Notez qu'IE7 ne prend pas en charge ces styles de table CSS et IE8 aura besoin d'une déclaration doctype pour le mettre en mode "standard": (essayez celui-ci ou quelque chose d'équivalent)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Tout autre navigateur prenant en charge display: table, display: table-row et display: table-cell doit afficher votre tableau de données css de la même manière que si vous utilisiez les balises TABLE, TR et TD. La plupart d'entre eux le font.

Notez que vous pouvez également imiter THEAD, TBODY, TFOOT en encapsulant vos groupes de lignes dans une autre DIV avec display: table-header-group, table-row-groupet table-footer-grouprespectivement.

REMARQUE: la seule chose que vous ne pouvez pas faire avec cette méthode est colspan.

Découvrez cette illustration: http://jsfiddle.net/ZRQPP/

Matthieu
la source
4
+1 pour avoir mentionné cela ne permet pas à colspan ... dont j'ai dû manquer la première lecture ;-)
Johannes Rudolph
1
Cela devrait être la réponse vérifiée en vert (même si vous n'utilisez pas vraiment de balise de table)
Alessio