web-dev-qa-db-fra.com

HTML: Est-il possible d'avoir une balise FORM dans chaque TABLE ROW de manière XHTML valide?

Je peux mieux décrire cela comme suit:

Je veux cela (tableau complet dans editmode et bouton d'enregistrement dans chaque ligne).

<table>
    <tr>
        <td>Id</td>
        <td>Name</td>
        <td>Description</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td><input type="hidden" name="id" value="1" /></td>
        <td><input type="text" name="name" value="Name" /></td>
        <td><input type="text" name="description" value="Description" /></td>
        <td><input type="submit" value="Save" /></td>
    </tr>
    <tr>
        <td><input type="hidden" name="id" value="2" /></td>
        <td><input type="text" name="name" value="Name2" /></td>
        <td><input type="text" name="description" value="Description2" /></td>
        <td><input type="submit" value="Save" /></td>
    </tr>
    <!-- and more rows here ... -->
</table>

Où dois-je mettre le <form> Mots clés?

69
Ropstah

Tu ne peux pas. Votre seule option est de diviser cela en plusieurs tables et de placer la balise de formulaire à l'extérieur. Vous pourriez finir par imbriquer vos tables, mais ce n'est pas recommandé:

<table>
  <tr><td><form>
    <table><tr><td>id</td><td>name</td>...</tr></table>
  </form></td></tr>
</table>

Je supprimerais complètement les tables et les remplacerais par des éléments html stylisés comme les divs et les span.

38
stereoscott

Il convient de mentionner que cela est possible en HTML5, en utilisant l'attribut "form" pour les éléments d'entrée:

<table>
    <tr>
        <td>Id</td>
        <td>Name</td>
        <td>Description</td>
        <td>&nbsp;</td>
    </tr>
    <tr>
        <td><form id="form1"><input type="hidden" name="id" value="1" /></form></td>
        <td><input form="form1" type="text" name="name" value="Name" /></td>
        <td><input form="form1" type="text" name="description" value="Description" /></td>
        <td><input form="form1" type="submit" value="Save" /></td>
    </tr>
    <tr>
        <td><form id="form2"><input type="hidden" name="id" value="1" /></form></td>
        <td><input form="form2" type="text" name="name" value="Name" /></td>
        <td><input form="form2" type="text" name="description" value="Description" /></td>
        <td><input form="form2" type="submit" value="Save" /></td>
    </tr>
</table>

Bien que propre par son manque de JS et l'utilisation d'éléments d'origine, malheureusement, cela ne fonctionne pas dans IE10.

71
tjbp

J'avais une question similaire et cette réponse en question HTML: tableau des formulaires? l'a résolu pour moi. (Je ne sais pas s'il s'agit de XHTML, mais cela fonctionne dans un navigateur HTML5.)

Vous pouvez utiliser css pour donner la disposition du tableau à d'autres éléments.

.table { display: table; } 
.table>* { display: table-row; }
.table>*>* { display: table-cell; }

Ensuite, vous utilisez le code HTML valide suivant.

<div class="table"> 
    <form>
        <div>snake<input type="hidden" name="cartitem" value="55"></div>
        <div><input name="count" value="4" /></div>
    </form>
</div>
58
Alexx Roche

Je dirais que vous pouvez, même si cela ne valide pas et Firefox réorganisera le code (donc ce que vous voyez dans "Afficher la source générée" lors de l'utilisation de Web Developer peut très bien surprendre). Je ne suis pas un expert, mais je mets

<form action="someexecpage.php" method="post">

juste devant le

<tr>

puis en utilisant

</tr></form>

à la fin de la ligne donne certainement la fonctionnalité (testée dans Firefox, Chrome et IE7-9). Travailler pour moi, même si le nombre d'erreurs de validation qu'il a produit était un nouveau record personnel/pire! Aucun problème vu en conséquence, et j'ai une table assez fortement stylisée. Je suppose que vous pouvez avoir une table produite dynamiquement, comme je le fais, c'est pourquoi l'analyse des lignes de la table est un peu non évidente pour nous mortels. Fondamentalement, ouvrez le formulaire au début de la ligne et fermez-le juste après la fin de la ligne.

3
Geoff Kendall

Il suffit de mettre le <form ... > tag avant le <table> tag et le </form> à la fin.

J'espère que ça aide.

1
Timothée Martin

Si vous essayez d'ajouter un formulaire déformant un élément tr comme celui-ci

<table>
<form>
<tr>
<td><input type="text"/></td>
<td><input type="submit"/></td>
</tr>
</form>
</table>

certains navigateurs en cours de rendu fermeront la balise de formulaire juste après la déclaration en laissant les entrées en dehors de l'élément

quelque chose comme ça

<table>
    <form></form>
    <tr>
    <td><input type="text"/></td>
    <td><input type="submit"/></td>
    </tr>
    </table>

Ce problème est toujours valable pour la déformation de plusieurs cellules de tableau

Comme l'a dit plus haut stéréoscopique, les tables d'imbrication sont une solution possible qui n'est pas recommandée. Évitez d'utiliser des tables.

0
Lothre1

En fait j'ai le problème avec un formulaire sur chaque ligne d'une table, avec javascript (en fait jquery):

comme l'a dit Lothre1, "certains navigateurs en cours de rendu fermeront la balise de formulaire juste après la déclaration, laissant les entrées en dehors de l'élément"

ce qui rend mes champs de saisie EN DEHORS du formulaire, donc je ne peux pas accéder aux enfants de mon formulaire via le DOM avec JAVASCRIPT ..

généralement, le code JQUERY suivant ne fonctionne pas:

$('#id_form :input').each(function(){/*action*/});
// this is supposed to select all inputS 
// within the form that has an id ='id_form'

MAIS l'exemple ci-dessus ne fonctionne pas avec le HTML rendu:

<table>
    <form id="id_form"></form>
    <tr id="tr_id">
    <td><input type="text"/></td>
    <td><input type="submit"/></td>
    </tr>
    </table>

Je suis toujours à la recherche d'une solution propre (bien que l'utilisation du paramètre TR 'id' pour parcourir le DOM résoudrait ce problème spécifique)

sale solution serait (pour jquery):

$('#tr_id :input').each(function(){/*action*/});
// this will select all the inputS
// fields within the TR with the id='tr_id'

l'exemple ci-dessus fonctionnera, mais ce n'est pas vraiment "propre", car il fait référence au TR au lieu du FORM, ET il nécessite AJAX ...

EDIT: le processus complet avec jquery/ajax serait:

//init data string
// the dummy init value (1=1)is just here 
// to avoid dealing with trailing &
// and should not be implemented
// (though it works)
var data_str = '1=1'; 
// for each input in the TR
$('#tr_id :input').each(function(){

 //retrieve field name and value from the DOM
 var field = $(this).attr('name');
 var value = $(this).val();

 //iterate the string to pass the datas
 // so in the end it will render s/g like
 // "1=1&field1_name=value1&field2_name=value2"...
 data_str += '&' + field + '=' + value; 


});

//Sendind fields datawith ajax 
// to be treated 
$.ajax({
 type:"POST",
 url: "target_for_the_form_treatment",
 data:data_string,
 success:function(msg){
    /*actions on success of the request*/
 });
});

de cette façon, le "target_for_the_form_treatment" devrait recevoir les données POST comme si un formulaire lui avait été envoyé (à part le message [1] = 1, mais pour implémenter cette solution, je recommanderais de traiter avec le à la place '&' de data_str à la place).

je n'aime toujours pas cette solution, mais je suis obligé d'utiliser la structure TABLE en raison du plugin jquery dataTables ...

0
renard