Une interface de formulaire à base de tableaux dynamiques

Oui, je sais, les tableaux de mise en page c’est mal. Mais quand il s’agit de présenter des données en tableau, par exemple : le prix des carottes en fonction de la vitesse du vent et de l’age du capitaine, alors ils sont indispensables. Je dirais même plus, ça serait une erreur de ne pas les utiliser. Maintenant, imaginons que nous ayons à programmer une interface pour saisir le prix des carottes : comment faire simple, léger, accessible, rapide à développer et agréable à utiliser ? L’idéal serait de se rapprocher du fonctionnement d’un tableur : pouvoir ajouter, supprimer ou éditer des lignes, et sauvegarder le document à la fin. Et bien en interface web, c’est possible grâce à Javascript et DOM (et un peu de PHP pour le traitement).

Première étape : construire la page

Tout d’abord, il faut faire la page web. Pour cela, on utilise du XHTML tout à fait classique, et on construit un tableau. Je vous invite à lire l’article Habillage de tableaux avec des CSS sur Openweb pour en savoir plus sur la manière de faire un tableau conforme aux standards.

Le tableau que j’ai choisi de dessiner est on-ne-peut-plus simple : il contient 4 colonnes contenants chacunes un champ de type “text”, et une dernière colonnes contenant les actions possibles. Pour l’instant, la seule action possible est la suppression d’une ligne.

Le code donne (vous pouvez consulter l’exemple 1) :

<table class="dTable">
	<thead>
		<tr>
			<th>Colonne 1</th>
			<th>Colonne 2</th>
			<th>Colonne 3</th>
			<th>Colonne 4</th>
			<th>Actions</th>
		</tr>
	</thead>
	<tfoot>
		<tr>
			<th colspan="5"><a href="#">Ajouter une ligne</a></th>
		</tr>
	</tfoot>
	<tbody>
		<tr>
			<td><input type="text" name="champ1[]" /></td>
			<td><input type="text" name="champ2[]" /></td>
			<td><input type="text" name="champ3[]" /></td>
			<td><input type="text" name="champ4[]" /></td>
			<td><a href="#">Supp</a></td>
		</tr>
	</tbody>
</table>

Les liens ont tous pour trajet (href) la valeur #. Cela revient à dire qu’ils n’ont pas d’effet… pour l’instant. J’ai appliqué la classe dTable au tableau (comme « Dynamic Table ») afin de pouvoir l’identifier parmi d’autres éventuels tableaux, qui, eux, ne seront pas dynamiques. Enfin, dernier détails, les champs input ont tous un nom finissant par []. Nous verrons dans la troisième partie à quoi ça va servir.

Deuxième étape : rendre le tableau dynamique

Maintenant on rentre dans le vif du sujet. Pour rendre ce tableau dynamique, on va utiliser du Javascript et du DOM, en s’arrangeant pour qu’il soit compatible Internet Explorer et Firefox.

Première chose : inclure un script. Pour cela, on rajoute dans le header de la page html la ligne suivante (avec dtable.js le nom du fichier script) :

<script type="text/javascript" src="dtable.js"></script>

Bien ensuite, un peu de conception… Comment allons nous procéder ?

Ajout

Pour ajouter une ligne, le plus simple est d’utiliser la méthode DOM cloneNode() qui permet de dupliquer un nœud (par exemple un tr, donc une ligne du tableau) et appendChild() qui permet d’ajouter un nœud à un autre (par exemple le tr cloné au tbody, donc au corps du tableau). Cette méthode est très simple à condition d’avoir une ligne « de référence », c’est à dire une ligne vide que l’on pourra cloner pour simuler l’ajout de ligne. La première ligne du tableau (la seule que j’ai saisis dans le code html ci-dessus) fera office de référence.

Nous allons faire une fonction addLigne qui prend en paramètre l’élément appelant (en l’occurrence il s’agira d’un lien, donc d’un élément A). A partir du lien, il faudra retrouver le tableau en « remontant » dans l’arbre html à la recherche du parent s’appelant TABLE. A partir du tableau, on pourra retrouver le TBODY et la première ligne, et effectuer l’ajout.

Pour retrouver le parent d’un élément, j’utilise une fonction récursive, getParent(element, parentTagName), dont voici l’implémentation :

/* trouve le tag "parentTagName" parent de "element" */
function getParent(element, parentTagName) {
	if ( ! element )
		return null;
	else if ( element.nodeType == 1 && element.tagName.toLowerCase() == parentTagName.toLowerCase() )
		return element;
	else
		return getParent(element.parentNode, parentTagName);
}

Le code pour ajouter une ligne devient :

/* ajoute une ligne */
function addLigne(link) {
	// 1. récuperer le node "TABLE" à manipuler
	var td = link.parentNode;
	var table = getParent(td,'TABLE');
	// 2. on va manipuler le TBODY
	var tbody = table.tBodies[0];
	// 3. on clone la ligne de reference
	var newTr = tbody.rows[0].cloneNode(true);
	tbody.appendChild(newTr);
}

Pour appeler cette fonction, on peut transformer le lien « Ajouter une ligne » comme ceci :

<a href="#" onclick="addLigne(this); return false;"> 

Le return false; permet de stopper le traitement normal du lien et donc de ne pas executer le href.

Suppression

Là encore, une fonction DOM nous mâche tout le travail : removeChild(). Il suffit de trouver le TR à supprimer en remontant l’arbre html depuis le lien appelant, et de le retirer du TBODY

/* supprimer une ligne */
function delLigne(link) {
	// 1. récuperer le node "TABLE" à manipuler
	var td = link.parentNode;
	var table = getParent(td, 'TABLE');
	// 2. récuperer le TBODY
	var tbody = table.tBodies[0];
	// 3. Supprimer le TR
	tbody.removeChild(getParent(td, 'TR'));
}

Pareil que pour l’ajout, on peut transformer les liens « Supp » comme ceci :

 <a href="#" onclick="delLigne(this); return false;"> 

L’ajout et la suppression donnent l’exemple 2.

Protéger la première ligne

Le problème de l’exemple 2, que vous avez peut-être remarqué en testant, est que la première ligne, la ligne de référence donc, est supprimable comme les autres. Et lorsqu’on supprime tous les lignes, il n’y en a plus aucune à cloner ! On va donc masquer la première ligne avec la propriété CSS display="none" et en ajoute une vide supplémentaire.

On ajoute au code :

window.onload = dtableInit;
/* initialise le script */
function dtableInit() {
	var table = document.getElementsByTagName('TABLE');
	for ( var i = 0; i < table.length; i++ ) {
		// on récupère tous les tableaux dynamiques
		if ( table[i].className == 'dTable' ) {
			var tbody = table[i].tBodies[0];
			var newTr = tbody.rows[0].cloneNode(true);
			// on masque la première ligne du tbody (la ligne de reference)
			tbody.rows[0].style.display = 'none';
			// on en ajoute une
			tbody.appendChild(newTr);
		}
	}
}

Un dernier problème subsiste : lorsqu'on clone cette ligne, son style est cloné également. Toutes les lignes sont donc invisibles ! Il faut ajouter à la fin de addLigne de quoi les remettre visibles :

	if ( document.all )
		newTr.style.display = "block"; // pour IE
	else
		newTr.style.display = "table-row"; // pour Gecko

L'utilisation de document.all permet de détecter s'il s'agit d'IE ou pas. En effet, seul ce navigateur implémente cette propriété (non-standard).

Vous pouvez tester ce code dans l'exemple 3.

Troisième étape : traiter les données

Grâce à leur nom finissant par [], les valeurs des champs input seront assemblées dans un tableau lors du post du formulaire. Résultat : on se retrouve avec 4 tableaux : champ1, champ2, champ3 et champ4 correspondants aux 4 colonnes du tableaux html. Les lignes de ces tableaux correspondent aux lignes du tableau html (en commençant par 0).

Imaginons qu'il faille mettre à jour une base, le plus rapide est de tout supprimer puis de réinsérer les données directement ! Pas besoin de s'embêter à trouver ce qui a changé puisque tout est renvoyé.

Dernière chose : au moment de traiter ces données, il ne faut pas oublier d'oublier l'index 0, qui correspond à la ligne de référence.

Vous pouvez tester le résultat renvoyé par le serveur grâce à l'exemple 4 (voir la source, mais qui n'a rien de bien extraordinaire).

Conclusion

Rajouter des fonctions à ce script est extrêmement simple : il suffit de veiller à ne pas toucher à la première ligne. On peut par exemple imaginer des fonctions permettant de monter une ligne, de la descendre, de la dupliquer, etc. Bref, les possibilités de créer des interfaces web se rapprochant de celles des clients lourds sont de plus en plus nombreuses et de plus en plus simples à mettre en œuvre grâce notamment aux standards du W3C !

58 comments.

  1. Je constate avec plaisir qu’un problème le vendredi soir est résolu et expliqué le dimanche!

    Plus sérieusement, cette technique ouvre en effet de nombreuses perspectives, notamment lorsqu’il s’agit de gérer des back-offices assez denses, bourrés de statistiques :)

  2. Ah bah, un article comme ça je suis obligé d’y mettre mon grain de sel. :)

    note générale : c’est ma periode "sale code mais c’est plus court et plus rapide".
    Pourquoi avoir fait la fonction getParent en récursif alors qu’il est aisé de se passer de la récursivité ?

    Un peu dans ce genre :
    function getParent(element, parentTagName) {
    while (!(element.nodeType == 1 && element.tagName.toLowerCase() == parentTagName.toLowerCase())) {
    if (!(element = element.parentNode)) return false;
    }
    return element;
    }

    À propos de la première ligne du tableau qui-fait-bien-chier durant tout le reste du script, pour quoi ne pas simplement la sauvgarder dans une variable et la réutiliser plus tard ? Par contre ça implique qu’une fois le première ligne copié via la méthode cloneNode, la variable qui contient la ligne de ref devra à son tour être copié avec la même méthode afin d’être réutilisée.
    Mais on a un problème au niveau du stoquage de la variable qui contient ce node de référence car pour qu’elle persiste entre deux appel de addLigne il faudra que cette variable soit de portée globale, ce qui peut être gênant si on veut que le script soit réutilisable. Donc à la limite il existe une solution qui relève du bidouillage et qui nécéssite une bonne compréhension des méchanismes internes de l’interprêteur javascript et qui de toutes façon revient à créer une variable globale. Mais juste histoire d’étler ma science je vais vous en faire part.

    <la théorie>
    Les variables locales à une fonction sont détruites (ou du moins le devraient) lorsque l’on quite la fonction.
    mais lorsque l’on crée une fonction B à l’interieur d’une fonction A et que l’on utilise une variable locale à A à l’interieur de B, alors B va utiliser une sorte de pointeur vers la variable locale à A, et la variable ainsi pointé ne sera pas détruite lorsque la fonction A va se terminer. Ou plus précisément, la variable pointé va continuer à être accessible à B mais au prochain appel de A une nouvelle pile est créé sans pour autant que la variable utilisé par B soit détruite.
    </la théorie>

    Un petit bout de code pour illustrer la théorie :
    <html>
    <head>
    <title>bla</title>
    <script type="text/javascript">
    function foo (id) {
    if (id == 0) {
    var bar = ‘truc’;
    bla = function () { return bar; };
    bar = ‘machin’;
    } else alert(bla());
    }
    </script>
    </head>
    <body onload="foo(0); foo(1)">
    </body>
    </html>

    Essayez de comparer ce que vous attendez avec ce que vous voyez.
    Cette technique est utilisé pour afficher des variables locales via un setTimeout ou encore pour pallier certains problèmes de "this" en POO.

    Dans notre cas, on pourrait dans dtableInit créer une fonction qui retourne la ligne de ref, puis utiliser cette fonction dans addLigne.
    Mais le problème est que créer une fonction revient à déclarer une variable globale car d’un certain point de vue une fonction est une variable globale (donc une propriété de l’objet window) qui contient un objet function.
    Tien, et toujours à propos du stoquage de cette ligne de ref, je pense qu’un documentFragment pourrait être utile. cf : http://www.w3.org/TR/2000/WD-DOM...

    Ça peut parraitre un peu compliqué, mais si il n’y a plus cette ligne de référence dans le tableau alors il n’y aura plus à s’en soucier lors de l’effacement des lignes, ni dans aucune autre furtur fonction ajouté par la suite.

    Bref, tout ça pour dire et pour me convaincre que je suis aussi ze masteur auv JavaScript. :)

    Celelibi

  3. "Pourquoi avoir fait la fonction getParent en récursif alors qu’il est aisé de se passer de la récursivité ?" > Parceque c’est plus lisible, et souvent aussi efficace (voir plus)

    Et pour le reste ben c’est très simple: avec ta technique de goret comment tu fais si tu as plusieurs dTable dans la même page ?

  4. Et bah rien ne t’empêches de faire un truc du style :
    function dtableInit() {
    var table = document.getElementsByTagName(‘TABLE’);
    var lignes = new Array();
    for ( var i = 0; i < table.length; i++ ) {
    // on récupère tous les tableaux dynamiques
    if ( table[i].className == ‘dTable’ ) {

    var tbody = table[i].tBodies[0];
    // on stoque la ligne de ref et une référence vers le tableau
    lignesRef.push(Array(table[i], tbody.row[0].cloneNode(true)));
    }
    }
    lignesRef = function (tablo) {
    for (var i=0; i<lignes.length; i++) {
    if (lignes[i][0] == tablo) return lignes[i][1];
    }
    return false;
    };
    }

    Et pour addLigne :
    function addLigne(link) {
    // 1. récuperer le node "TABLE" à manipuler
    var td = link.parentNode;
    var table = getParent(td,’TABLE’);

    // 2. on va manipuler le TBODY
    var tbody = table.tBodies[0];

    // 3. on clone la ligne de reference
    var newTr = lignesRef(table).cloneNode(true);
    tbody.appendChild(newTr);
    }

    Y’a aussi toujours moyen de créer de toute pièce des lignes de tableau via insertRow et insertCell. De plus ces deux méthodes permettent de les insérer au millieu du tableau, ce qui est à mon avis plus propre qu’un insertBefore ou appelChild.
    Mais ça je pense que tu le savais déjà. :)

    Quand on commence avec du goret, on peut finir avec du goret non ?

  5. "De plus ces deux méthodes permettent de les insérer au millieu du tableau, ce qui est à mon avis plus propre qu’un insertBefore ou appelChild."

    Je ne dois surement pas avoir la même définition de "plus propre", parceque se taper un insertRow, itérer sur des insertCell, être obligé d’avoir en dur dans le javascript le code html des cellules à ajouter (ce qui pose un problème de réutilisabilité), puis passer des coups de truc.style.bidule pour mettre à jour les styles de tes cellules que tu viens de créer (et j’en passe) au lieu de faire un cloneNode et appendChild, c’est pas ce que j’appelle "propre".

    J’ai l’impression que tu cherches absolument à faire ton malin, et sans remettre en cause tes compétences en javascript je te signale que j’ai précisé en début d’article, mon objectif était : "comment faire simple, léger, accessible, rapide à développer et agréable à utiliser ?" Or ce que tu proposes est loin d’être léger et rapide à développer (et plus ça va, pire c’est).

  6. Bonjour,Le code est sympa et lisible, bravo.Par contre j’ai une erreur dans la console JavScript sur la ligne "var newTr = tbody.row[0].cloneNode(true);" dans la fonction init!

  7. Quelle erreur exactement ? C’est peut-être que ta source html est mal formée (s’il ne trouve pas la ligne dans le tbody il va raler)

  8. Il me met "tbody.row has no properties". Quand je supprime toutes les lignes, il ne réaffiche plus de ligne !

  9. Il y a ce problème dans l’exemple 2, puis j’explique après comment éviter ça. Peut-être as-tu pris le mauvais script ? Si non, l’hypothèse la plus probable est que ta source html est mal formée.

  10. Je pense plutôt que c’est mon "dtable.js" qui n’est pas bien. Si tu peux m’envoyer le tien par mail ca serait sympa. Merci, une dernière chose, je souhaiterais maintenant copier tout le tableau et l’insérer par un bouton, mais je n’y arrive pas avec DOM, il faut dire que je suis novice en HTML.

  11. Il suffit de prendre celui du dernier exemple. Pour le reste, je te conseille de poster sur le forum :
    forum.the-asw.com

  12. Re bonjour,
    En fait il y’a une erreur de syntaxe dans le code de la fonction "dtableInit". Il faut mettre un "s" à tbody.row"s" pour que ca fonctionne. Merci pour tout cgo2.

  13. Hum en effet… C’est plutôt suprenant puisque le “s” était bien présent dans les exemples, et que j’ai copié/collé les exemples dans l’article ! Bah, il faut croire que mon doigt à du ripper sur une mauvaise touche :) Bravo pour l’avoir remarqué en tous cas !

  14. Juste pour dire merci pour cette fonctionnalité que même un néophyte comme moi à pu mettre en oeuvre.

  15. je suis en train de développer une application web qui utilise le DOM pour rajouter des lignes dans un tableau. je viens de recopier exactement le code que tu propose et quand je l’éxécute sous ie, j ai l erreur suivante : tBodies.0 a la valeur null ou n est pas un objet !
    peux tu m éclairer ca fait 2 jours que je cherche à résouvre se probleme d ‘ajout de ligne ! merci d’@vance

  16. Autre chose j’ai une fonction qui sert a ajouter des lignes dans un tableau. j utilise un autre procédé !
    le probleme c que le script s’exécute tres bien sous firefox mais pas sous ie6: voici le code, j ai vraiment beson d’avancer alors aider mo svp.

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD...
    <html xmlns="http://www.w3.org/1999/xhtml&quo... xml:lang="fr">
    <head>
    <title>tab.html</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    </head>
    <body>
    <table id="t">
    <tr>
    <th>Piste</th><th>Titre</th>
    </tr>
    <tr>
    <td><input type="text" name="t_tracknumber" value="1" size="1"></td>
    <td><input type="text" name="t_title"></td>
    </tr>
    </table>
    <script language="javascript" type="text/javascript">
    function addline()
    {
    var col1 = document.createElement(‘td’);
    var col2 = document.createElement(‘td’);

    col1.innerHTML =’<td><input type="text" name="t_tracknumber" value="1" size="1"></td>’ ;
    col2.innerHTML =’<td><input type="text" name="t_title"></td></tr>’ ;

    var newRow = document.createElement(‘tr’);

    newRow.appendChild(col1) ;
    newRow.appendChild(col2) ;

    document.getElementById("t").appendChild(newRow);
    }
    </script>

    <input type="button" value="add" onClick="addline()">

    </body></html>

  17. Pour faciliter les discussions, utilisez le forum pour toute demande d’aide en javascript/DOM et compagnie.
    forum.the-asw.com/viewfor…

    Merci !

  18. Bonjour
    Merci de bien vouoir m’envoyer le dtable.js . En effet j ‘ai deux problemes pour tester l’ajout de ligne.
    1/ Si je supprimme toutes les ligne la lien Ajouter une lingne ne ragit plus.
    2/ Si j’ajout une ligne elle est toujours intialisée par ce qui a ete saisi dans la ligne precedente (ligne de reference)

  19. Bonjour,

    Grande débutante, j’ai trouvé ton article vraiment bien fait. Cependant je n’arrive pas à récuperer les valeurs.
    Peux-tu m’indiquer comment je récupere les valeurs des tableaux dans la page affichant les résulats. Un tout grand merci !

  20. en travaillant dessus voila ce que j’ai pu faire pour proteger la derniere ligne en retirant "window.onload = dtableInit;" et la fonction dTableInit() :

    /**************************/
    function delLigne(link) {
    var td = link.parentNode;
    var table = getParent(td, ‘TABLE’);
    var tbody = table.tBodies[0];

    if (tbody.rows.length > 1) {
    tbody.removeChild(getParent(td, ‘TR’));
    } else {
    alert(‘Vous ne pouvez pas supprimer cette ligne’);
    }
    }

    /***************************/

  21. Moi j’aimerais savoir comment je fais si je veux ajouter des colonnes parce que je recois un tableau dynamique de mon php et la j’utilise une section pour faire afficher le tableau mais si je ne fais pas sa :
    <td>{$tableau[index][0]}</td>
    <td>{$tableau[index][1]}</td>
    bien je ne vois que la première colonne

  22. Bonjour,

    Super le code javascript merci beaucoup.

    J’ai seulement dû remplacer dans la fonction dtableInit le "appendChild" par un "insertBefore". En effet ma page est un formulaire PHP qui se rappelle elle-même pour la vérification, et sans faire ces changements les lignes de mon tableau se retrouvaient décalées d’une position à chaque soumission du formulaire. La ligne 3 devenait la 2, la ligne 2 devenait la 1, la ligne 1 devenait la 3, et ainsi de suite…

    Enfin bon, encore merci quand même :-)

  23. Dans la fonction dtableInit()
    ce n’est pas
    if ( table[i].className = ‘dTable’ )
    mais
    if ( table[i].className == ‘dTable’ )

    ca peut faire perdre du temps ;)

  24. il est bien mis dans ta page mais pas dans le code
    http://www.the-asw.com/files/web...

  25. Est t’il possible d’avoir access à votre code php qui recupere les valeurs entrées dans le tableau??
    Merci d’avance :)

  26. Bonjour,

    bravo pour le code,
    je suis un newbie en js je viens direct du c++.
    mais en faite je voudrais créer mes lignes avec des valeurs issues d’une requete SQL ou d’un select.
    En clair passer des valeurs à la fonction addligne.

  27. bonjour,

    j’ai bcp de mal avec le redimensionnement du tableau.
    j’ai un tableau html pure avec des dimension que j’essaye de reproduire avec le type tableau de ce tutorial mais il ne prend pas en compte les dimensions que je lui indique. Savez pourquoi ?

  28. Bonjour,

    Et tout d’abord félicitation pour ce superbe boulot…
    C’est très pratique pour éviter de surcharger les formulaires avec un nombre défiit de lignes…
    Je ne connaissais pas ce système (je restais plutôt basique dans mes applications) et je dois dire qu’il me sert carrément beaucoup !
    Toutefois, j’ai un petit soucis..
    En effet, dans mes formulaires (HTML puis vérification en PHP), s’il y a des erreurs, je réaffiche la page avec les infos mais, ça me recharge à chaque fois une ligne supplémentaire… !!!
    J’ai essayé différentes choses (dites notamment plus haut), mais rien n’y fait…
    Y-a-t-il une solution ?
    Merci et encore bravo.

  29. Bonjour.
    Ce code est vraiment bien.
    Seul bemol : sous Firefox, le lien de suppression d’une ligne fonctionne mais pas sous IE.
    Une idée serait la bienvenue…
    Merci encore pour ce formidable tuto.

    Cordialement.

  30. Ca m’étonne ça, si tu regardes l’exemple 3 ça fonctionne niquel sous IE 6 et 7… Tu as plus de détails sur ton problème ?

  31. Boujour,

    Comment fait ton pour avoir des noms d’input incrementiel quand on ajoute une ligne ??
    tel que :

    <input name=”rad_1″ type=”radio” value=”" />
    <input name=”rad_2″ type=”radio” value=”" />
    <input name=”rad_3″ type=”radio” value=”" />

    <input name=”rad_n” type=”radio” value=”" />

    Merci

  32. J’ai a peu pres le meme probleme que klesk et ne connaissant pas assez le javascript j’ai du mal a modifier cela pour qu’il y eai une incrementation d’une des colonnes…
    Voir meme d’avoir la possibilité d’intercaler des lignes entre 2 entrée

  33. Bonjour,

    j’aurais aimé savoir comment récuperer avec du javascript les valeurs contenues dans la 3 ème ligne par exemple, afin d’effectuer un calcul par une fonction javascript et ainsi directement afficher le résultat de ce calcul dans la dernière colonne…

    Merci

  34. Bonjour,

    J’utilise aussi les [] pour envoyé des tableaux mais j’ai des problèmes.

    Sous IE tout fonctionne bien envoi et réception.
    Sous Firefox quand je post les données ne passent pas un isset() à la recupération en PHP.

    Code utilisé :

    premier cas (pour sauvegarder des options) :
    <input type=”checkbox” name=”var[]” value=”a” />
    <input type=”checkbox” name=”var[]” value=”b” />
    <input type=”checkbox” name=”var[]” value=”c” />

    deuxième cas (pour uploader) :
    <input type=”file” name=”var[]” />
    <input type=”file” name=”var[]” />
    <input type=”file” name=”var[]” />

    Avez vous une idée ?

    Merci d’avance Nico.

  35. Bonjour,

    Bravo pource code que j’ai examiné à la loupe.
    j’ai récupéré le dtable.js cependant j’ai un problème qui ne sort pas dans l’exemple 3.
    quand j’ajoute une ligne le texte initial ds un textfield par exemple est aussi cloné ce qui n’apparait pas ds l’exemple 3. Pourrai je avoir une explication ou une mise à jour de dtable.js

    Merci bcp

  36. Super,

    Super ton article sur les tableaux dynamiques. En ce qui me concerne, j’ai un souci pour insérer les données dans une table sous mysql. En fait, je n’arrive pas à créer une simple ligne comme : INSERT INTO … SET colname = data, ….
    Une petite aide serait la bienvenue …

    Merci à tous et à toutes.

  37. Après réflexion :

    if (isset($_POST[ok])) {
    unset($_POST[ok]);
    $val = key($_POST);

    for($i=0; $i < count($_POST[$val])-1; $i++) {
    $sdata = ‘INSERT INTO adherents_2 SET ‘;
    foreach($_POST as $k1 => $d1) {
    $sdata .= $k1.”=’”.addslashes($d1[$i]).”‘,”;
    }
    $sql[$i] = rtrim($sdata, ‘,’);
    echo $sql[$i].’ —- <br>’;
    mysql_query($sql[$i]) or die(mysql_error());
    }

    } else { ……… }

    Vous en pensez quoi ?

  38. Quelqu’un saurait comment faire pour récupérer les valeurs des tableaux en javascript, en php c’est facile mais en javascript j’ai du mal.
    Cela me servirait à controler les valeurs qu’il y a dans la zone champ2, malheureusement je récupere que la valeur que de la première ligne

  39. Bonjour!

    Tout d’abord bravo pour ce code.

    Mais j’ai un probleme avec la protection de la premiere ligne. Quand j’appel directement la page qui contient le tableau dynamique, tout va bien.

    En revanche quand j’integre le tableau dans une div d’une autre page php(via AJAX), la premiere ligne n’est pas protéger et donc si elle est supprimée impossible d’en recréer une nouvelle.

    Je bloque la dessus depuis deux jours, alors si quelqu’un a rencontré ce meme probleme merci de m’aider.

    Bye :)

  40. Merci pour ce code. Pourrais tu développer la partie extraction de donnée en php stp ? J’arrive bien à les extraire lorsqu’il s’agit d’un champ input text, mais pas avec des select/option

  41. Très bon tutorial,
    pourais tu me dire comment tu récupéres les données en php stp

    Merci d’avance.
    laurence

  42. jiai utiliser cette interface dans mon application mais mon prb c que seulement la derniere ligne s’enregistre dans ma base Mysql comment peut je faire pour recupérer tous les valeurs merci

  43. j’ai testé le code et sa marche. je voudrais insérer les données saisies dans deux tables différents.Comment faire dans ce cas? merci d’avance

  44. voila un code pour ajouter dans deux tables.J’ai pri un exemple mais tu peu le modifier pour adapter a ton code.num_appro est incrémenté automatiquement dans la table1:

    $InsAppro= “INSERT INTO table1 (Date_Appro ,Commentaire ,Status) VALUES (‘$date_appro’,'$commentaire’,'SAI’)” ;
    if ( mysql_query ($InsAppro))
    { $appro_id = mysql_insert_id(); // mysql_insert_id pour retrouver le dernier numéro auto-incremante inseré

    foreach ($champ11[] as $cle => $champ1[])
    {
    if ($cle!=0)
    {
    $InsDtl= “INSERT INTO table2(Num_Appro, Code_Article, Qte_Appro) VALUES (‘$appro_id’,'$code_article’,'$qte_appros[$cle]‘)” ;
    if (mysql_query ($InsDtl))
    {
    $ok=”<font color=\”#0000FF\”>L’approvisionnement à bien été enregistrée!</font><p>”;
    }
    else
    {
    $error= “<font color=\”#FF0000\”>Echec d’ajout de l’approvisionnement, Veuillez recommencer</font><P>”;
    print (mysql_error());
    }
    }
    }
    }

  45. commenta faire pour qu’en supprimant une ligne du tableau on supprime l’enregistrement aussi dans la base?

  46. Un grand merci pour cette présentation avec des exemples qui permettent effectivement de bien comprendre commet tout cela fonctionne.

    Serait-il possible d’avoir votre php de récupération des données du tableau, car je n’ai pas réussi à faire fonctionner cette partie du programme.

    Merci d’avance

  47. SVP je veux avoir le code de la page dtable.php
    pour savoir comment vous avez pu recuperer les valeurs dynamaiques du tableau , car j’ai essayé la fonction substr($cle,0,X) mais sans resultat
    et merci beaucoup .

  48. Alors après avoir développé mon tableau dynamique à ma sauce (qui fonctionne bien ma foi), j’ai un petit souci de récupération de données. J’incrémente les id et name de mon clone….D’après que les éléments crées par un cloneNode ne sont pas intégrés dans le tableau $_POST…. et là j’ai commencé à chercher sur la toile une autre solution. A ta sauce j’ai mis le name = client[] et je clone ma ligne, je n’obtiens côté php qu’une entrée dans mon tableau $_POST['client']…
    Une idée, une suggestion ? comme les commentaires précédents peux tu me transmettre ton code php ?

  49. Hello,

    Bon à la demande générale j’ai mis un lien vers la source de dtable.php, mais franchement je ne vois pas l’intérêt parce qu’il n’y a vraiment rien de spécial !

    Lorsqu’on nomme plusieurs champs avec “[]“, par exemple name=”test[]“, leurs valeurs sont concaténés dans un tableau, disponible dans $_POST. Tout simplement.

    a+

  50. slt
    je shoute de vous m’aide,ma proble que j’aime de faire un tableaux dyinamique de tele facon que je peut le modifie l’or ce que l’ouvrit comme un site web

  51. sur le langage html

  52. Bonjour
    J’ai le même problème que Roto avec $_POST mais uniquement sous Firefox. Contrairement à IE, Firefox ne transmet pas les INPUT créés dynamiquement avec Javascript. Pouvez vous confirmer ?

  53. bonjour,

    comment suis-je sensé récuper la taille de ce tableau pour le traiter en php?

    je sais cet article date un peu mais c’est le seul que j’ai à peu près compris pour faire un tableau dynamique.

  54. bonjour
    effectivement, pourriez vous nous dire comment faire pour recuperer les valeurs et les inserer dans une base sql..

    en tout cas bravo pour le tableau
    merci..

  55. Salut tout le monde

    Je n’arrive pas a récupérer les sources de l’exemple 4 qui soient fonctionnelles, quelqu’un pourrait placer une archive ?
    Autre point ou je bloque sur la lecture , comment récupérer la valeur de chaque champs en php lorsqu’on envoi le formulaire

    merci pour l’aide et l’explication

  56. Oui il manque une partie pour traiter le tableau array, mais trop complexe à le mettre en place, cela serait intéressant d’avoir une continuété pour traiter le résultat pour l’utiliser ensuite comme bon nous semble (bdd ou fichier)

  57. bonjour et merci pour le code
    comment puis je adapter cela pour cloné 2 ligne d’un tableau en meme temps ???
    merci

  58. c’est bon, ça marche pour moi merci !

Post a comment.