IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Ajout/duplication de ligne à un tableau


Sujet :

JavaScript

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 44
    Par défaut Ajout/duplication de ligne à un tableau
    Bonjour,

    J'aurais besoin d'un peu d'aide pour une fonctionnalité que je découvre et que je souhaiterais pousser un peu plus loin, l'ajout/duplication de ligne dans un tableau.
    Histoire de mettre un peu de challenge, je précise que je souhaite que cela fonctionne sous IE8

    A l'heure actuelle, mon test "simpliste" fonctionne bien et consiste à dupliquer une ligne déjà existante dans le tableau initial :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    <html>
    <head>
    <title>Tableau dynamique</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
     
    <script type="text/javascript" language="JavaScript">
    function dupliquerLigne(wId, wNum){
    /*wId: identifiant du tableau*/
    /*wNum: N° de la ligne à dupliquer*/
    var wTable=document.getElementById(wId);
    wTable.insertRow(-1);
    for(var wI=0;wI<wTable.rows[wNum].cells.length;wI++){
    wTable.rows[wTable.rows.length-1].insertCell(-1);
    wTable.rows[wTable.rows.length-1].cells[wI].innerHTML=wTable.rows[wNum].cells[wI].innerHTML;
    }
    }
    </script>
    </head>
    <body>
    <p>
    <button type="button" onclick="dupliquerLigne('table1', 0)">Dupliquer la ligne 1</button>
    <button type="button" onclick="dupliquerLigne('table1', 1)">Dupliquer la ligne 2</button>
    <button type="button" onclick="dupliquerLigne('table1', 2)">Dupliquer la ligne 3</button>
    </p>
    <table id="table1" border="1" cellspacing="0" cellpadding="0">
    <tr>
    	<td>&nbsp;<input type="text" value="Ma valeur A1" size="32" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="Ma valeur A2" size="32" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="Ma valeur A3" size="32" maxlength="64"></td>
    </tr><tr>
    	<td>&nbsp;<input type="text" value="Ma valeur B1" size="32" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="Ma valeur B2" size="32" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="Ma valeur B3" size="32" maxlength="64"></td>
    </tr><tr>
    	<td>&nbsp;<input type="text" value="Ma valeur C1" size="32" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="Ma valeur C2" size="32" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="Ma valeur C3" size="32" maxlength="64"></td>
    </tr>
    </table>
     
    </body>
    </html>
    Je souhaiterais dans un premier temps :
    - placer les boutons "dupliquerLigne" à la fin de chaque ligne (avec un 4e <TD> sur chaque ligne) : ce bouton doit permettre de dupliquer la ligne sur laquelle il est (la ligne étant toujours ajoutée à la fin)
    - En option, placer un second bouton "nouvelleLigne", qui dupliquerait la ligne mais viderait le contenu des champs <input> (la ligne étant également ajoutée à la fin)
    - Que ces boutons permettent de dupliquer le style CLASS="..." des <TR> et <TD> et le NOWRAP

    Dans un second temps :
    - garder ces boutons d'ajout et duplication, mais faire en sorte qu'ils arrivent à gérer l'incrémentation les NAME et ID, qui sont identiques mais de format peu sympathique (la ligne s'ajoutant à la fin, il faut donc récupérer l'ID de la dernière ligne...)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <TR>
    	<TD><INPUT ... NAME="_1_1_29_1_40_1" ID="_1_1_29_1_40_1" ...></TD>
    	<TD><INPUT ... NAME="_1_1_29_1_41_1" ID="_1_1_29_1_41_1" ...></TD>
    	<TD><INPUT ... NAME="_1_1_29_1_42_1" ID="_1_1_29_1_42_1" ...></TD>
    </TR>
    <TR>
    	<TD><INPUT ... NAME="_1_1_29_2_40_1" ID="_1_1_29_2_40_1" ...></TD>
    	<TD><INPUT ... NAME="_1_1_29_2_41_1" ID="_1_1_29_2_41_1" ...></TD>
    	<TD><INPUT ... NAME="_1_1_29_2_42_1" ID="_1_1_29_2_42_1" ...></TD>
    </TR>
    <TR>
    	<TD><INPUT ... NAME="_1_1_29_3_40_1" ID="_1_1_29_3_40_1" ...></TD>
    	<TD><INPUT ... NAME="_1_1_29_3_41_1" ID="_1_1_29_3_41_1" ...></TD>
    	<TD><INPUT ... NAME="_1_1_29_3_42_1" ID="_1_1_29_3_42_1" ...></TD>
    </TR>
    J'ai beau essayer de faire ça étape par étape, je suis un peu dépassé. Je pense que je suis obligé de mettre un ID au <TR>, mais je ne parviens pas à l'exploiter.
    Je suis ouvert à revoir complètement ma fonction JS initiale si c'est nécessaire

    Merci pour votre aide,

    Guillaume

  2. #2
    Membre éclairé Avatar de Billy KiT
    Inscrit en
    Mars 2011
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Mars 2011
    Messages : 66
    Par défaut
    Bonjour,

    il faut de toute façon utiliser les fonctions du DOM.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function clone(line) {
    	newLine = line.cloneNode(true);
    	line.parentNode.appendChild(newLine);
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <table id="table1" border="1" cellspacing="0" cellpadding="0">
    <tr>
    	<td>&nbsp;<input type="text" value="Ma valeur A1" size="32" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="Ma valeur A2" size="32" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="Ma valeur A3" size="32" maxlength="64"></td>
    	<td><input type="button" onclick="clone(this.parentNode.parentNode) "/></td>
    </tr><tr>
    	<td>&nbsp;<input type="text" value="Ma valeur B1" size="32" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="Ma valeur B2" size="32" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="Ma valeur B3" size="32" maxlength="64"></td>
    	<td><input type="button" onclick="clone(this.parentNode.parentNode) "/></td>
    </tr><tr>
    	<td>&nbsp;<input type="text" value="Ma valeur C1" size="32" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="Ma valeur C2" size="32" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="Ma valeur C3" size="32" maxlength="64"></td>
    	<td><input type="button" onclick="clone(this.parentNode.parentNode) "/></td>
    </tr>
    </table>
    par exemple, ça ça marche
    BK

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 44
    Par défaut
    Bonjour,

    Merci pour cette réponse, et cette élégante fonction "clone"
    (Il y a un petit souci sur les champs select, mais ce n'est vraiment pas majeur...)

    Je suis parvenu à faire une fonction similaire qui vide au passage les champs texte et textarea, et j'ai donc bien mes deux boutons, qui conservent tous les deux le style des lignes et cellules.
    En revanche, je ne parviens pas à incrémenter l'ID des nouvelles lignes : je ne parviens en fait pas à récupérer le nombre total de lignes dans ma table, en comptant bien sûr celles qui ont été créées dynamiquement...(d'ailleurs, après avoir avoir ajouté des lignes, elles n'apparaissent pas dans le code source ?)
    Voici où j'en suis :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    <html>
    <head>
    <title>Tableau dynamique</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <style type="text/css">
     
    table { border:thin solid #A2968A; border-collapse:collapse; text-align:center; }
    td { border:thin dotted #A2968A; padding:5px; text-align:center; height: 50px; }
    tr.trSpe { border:thin dotted #A2968A; padding:5px; text-align:center; height: 50px; background-color:#aeaeae; }
    td.tdSpe { border:thin dotted #A2968A; padding:5px; text-align:center; height: 50px; background-color:#aeaeae; }
     
    </style>
    <script type="text/javascript" language="JavaScript">
    function clone(line) {
    	newLine = line.cloneNode(true); //l'option selected des listes déroulantes n'est pas conservée lors du clonage
    	line.parentNode.appendChild(newLine);
    }
    function cloneEtVide(line) {
    	newLine = line.cloneNode(true);
    		var nbDeLignes = document.getElementById('table1').getElementsByTagName('TR').length; //j'essaie de savoir combien il y a de lignes...
    		newLine.ID = nbDeLignes+1; alert(newLine.id); //et d'attribuer l'id "nbDeLignes+1" à ma nouvelle ligne
    	var mesInput = newLine.getElementsByTagName('INPUT');
    	var mesTextarea = newLine.getElementsByTagName('textarea');
    	var mesSelect = newLine.getElementsByTagName('select');
    	for (i=0 ; i<= mesInput.length-1 ; i++) { if (mesInput[i].type == 'text') mesInput[i].value=""; }
    	for (i=0 ; i<= mesTextarea.length-1 ; i++) { mesTextarea[i].innerHTML = ""; }
    	for (i=0 ; i<= mesSelect.length-1 ; i++) { mesSelect[i].selectedIndex = 0; }
    	line.parentNode.appendChild(newLine);
    }
    </script>
    </head>
    <body>
     
    <table id="table1" border="1" cellspacing="0" cellpadding="0">
    <tr id="1" class="trSpe">
    	<td>&nbsp;<input type="text" value="input text A1" size="16" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="input text A1 bis" size="16" maxlength="64"></td>
    	<td>&nbsp;<TEXTAREA WRAP="soft" ROWS="2" COLS="16">textarea A2</TEXTAREA></td>
    	<td>&nbsp;<select><OPTION value="">--<OPTION value="option 1">A3-1<OPTION value="option 2">A3-1<OPTION value="option 3">A3-1</select></td>
    	<td><input type="button" value="Dupliquer" onclick="clone(this.parentNode.parentNode) "/></td>
    	<td><input type="button" value="Nouvelle ligne" onclick="cloneEtVide(this.parentNode.parentNode) "/></td>
    </tr>
    <tr id="2">
    	<td class="tdSpe" NOWRAP>&nbsp;<input type="text" value="input text B1" size="16" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="input text B1 bis" size="16" maxlength="64"></td>
    	<td class="tdSpe" NOWRAP>&nbsp;<TEXTAREA WRAP="soft" ROWS="2" COLS="16">textarea B2</TEXTAREA></td>
    	<td class="tdSpe" NOWRAP>&nbsp;<select><OPTION value="">--<OPTION value="option 1">B3-1<OPTION value="option 2">B3-1<OPTION value="option 3">B3-1</select></td>
    	<td><input type="button" value="Dupliquer" onclick="clone(this.parentNode.parentNode) "/></td>
    	<td><input type="button" value="Nouvelle ligne" onclick="cloneEtVide(this.parentNode.parentNode) "/></td>
    </tr>
    <tr id="3">
    	<td>&nbsp;<input type="text" value="input text C1" size="16" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="input text C1 bis" size="16" maxlength="64"></td>
    	<td>&nbsp;<TEXTAREA WRAP="soft" ROWS="2" COLS="16">textarea C2</TEXTAREA></td>
    	<td>&nbsp;<select><OPTION value="">--<OPTION value="option 1">C3-1<OPTION value="option 2">C3-1<OPTION value="option 3">C3-1</select></td>
    	<td><input type="button" value="Dupliquer" onclick="clone(this.parentNode.parentNode) "/></td>
    	<td><input type="button" value="Nouvelle ligne" onclick="cloneEtVide(this.parentNode.parentNode) "/></td>
    </tr>
    </table>
     
    </table>
    </body>
    </html>
    Je cherche toujours à incrémenter l'id lors de l'ajout d'une ligne, même si le véritable but est en fait de remplacer toutes les chaines "_1_1_29_[N]_xx_yy" de la ligne copiée (NAME, ID, etc., que je ne mets pas -encore- dans mes exemples) en "_1_1_29_[NbDeLignesExistantes+1]_xx_yy" dans la nouvelle ligne.

    En espérant que quelqu'un a une bonne idée pour faire tout ça.
    Encore merci pour votre aide en tout cas !

  4. #4
    Rédacteur

    Avatar de Bovino
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2008
    Messages
    23 647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2008
    Messages : 23 647
    Billets dans le blog
    20
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    function clone(line) {
    	var newLine = line.cloneNode(true); //l'option selected des listes déroulantes n'est pas conservée lors du clonage
    	line.parentNode.appendChild(newLine);
    	// Indice de la nouvelle ligne (attention, commence à 0)
    	alert(newLine.rowIndex);
    	// Nombre total de lignes
    	alert(newLine.parentNode.rows.length);
    }
    Pas de question technique par MP !
    Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
    Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
    Mon livre sur jQuery
    Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum

  5. #5
    Membre éclairé Avatar de Billy KiT
    Inscrit en
    Mars 2011
    Messages
    66
    Détails du profil
    Informations forums :
    Inscription : Mars 2011
    Messages : 66
    Par défaut
    Citation Envoyé par Douzout Voir le message
    d'ailleurs, après avoir avoir ajouté des lignes, elles n'apparaissent pas dans le code source ?
    ça c'est normal pour du dynamique

    Attention, javascript est sensible à la casse, id est en minuscule
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    function clone(line) {
    	newLine = line.cloneNode(true);
    	line.parentNode.appendChild(newLine);
    	newLine.id = "ligne"+newLine.parentNode.rows.length; // pour id="ligne4" puis "ligne5", etc
    }
    BK

  6. #6
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 198
    Par défaut
    Bonjour,
    j'aurais quand même une question :
    à quoi te servent les ID/NAME sur tes INPUTs ????

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 44
    Par défaut
    Bonjour,

    Merci pour ces réponses !

    @NoSmoking : ils servent au moment de la soumission du formulaire. Sans rentrer dans les détails, c'est un progiciel qui récupère les données

    Pour mon petit tableau test, j'ai également fait une petite fonction de suppression de ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
    <html>
    <head>
    <title>Tableau dynamique</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <style type="text/css">
     
    table { border:thin solid #A2968A; border-collapse:collapse; text-align:center; }
    td { border:thin dotted #A2968A; padding:5px; text-align:center; height: 50px; }
    tr.trSpe { border:thin dotted #A2968A; padding:5px; text-align:center; height: 50px; background-color:#aeaeae; }
    td.tdSpe { border:thin dotted #A2968A; padding:5px; text-align:center; height: 50px; background-color:#aeaeae; }
     
    </style>
    <script type="text/javascript" language="JavaScript">
    function clone(line, index) {
    	newLine = line.cloneNode(true); //l'option selected des listes déroulantes n'est pas conservée lors du clonage
    	line.parentNode.appendChild(newLine);
    }
    function cloneEtVide(line, index) {
    	newLine = line.cloneNode(true);
    	alert(line.rowIndex);
    	alert("Il y avait "+line.parentNode.rows.length+" lignes");
    	alert("J'ajoute donc une "+(line.parentNode.rows.length + 1)+"e ligne");
    	var mesInput = newLine.getElementsByTagName('INPUT');
    	var mesTextarea = newLine.getElementsByTagName('textarea');
    	var mesSelect = newLine.getElementsByTagName('select');
    	for (i=0 ; i<= mesInput.length-1 ; i++) { if (mesInput[i].type == 'text') mesInput[i].value=""; }
    	for (i=0 ; i<= mesTextarea.length-1 ; i++) { mesTextarea[i].innerHTML = ""; }
    	for (i=0 ; i<= mesSelect.length-1 ; i++) { mesSelect[i].selectedIndex = 0; }
    	line.parentNode.appendChild(newLine);
    	alert(newLine.rowIndex);
     
    }
    function supprLigne(line) {
    	line.parentNode.removeChild(line);
    }
    </script>
    </head>
    <body>
     
    <table id="table1" border="1" cellspacing="0" cellpadding="0">
    <tr id="1" class="trSpe">
    	<td>&nbsp;<input type="text" value="input text A1" name="_1_1_2_1_3_1" size="16" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="input text A1 bis" name="_1_1_2_1_4_1" size="16" maxlength="64"></td>
    	<td>&nbsp;<TEXTAREA WRAP="soft" name="_1_1_2_1_5_1" ROWS="2" COLS="16">textarea A2</TEXTAREA></td>
    	<td>&nbsp;<select name="_1_1_2_1_6_1"><OPTION value="">--<OPTION value="option 1">A3-1<OPTION value="option 2">A3-1<OPTION value="option 3">A3-1</select></td>
    	<td><input type="button" value="Copie" onclick="clone(this.parentNode.parentNode, '_1_1_2');"/></td>
    	<td><input type="button" value="New" onclick="cloneEtVide(this.parentNode.parentNode, '_1_1_2');"/></td>
    	<td><input type="button" value="Suppr." onclick="supprLigne(this.parentNode.parentNode);" /></td>
    </tr>
    <tr id="2">
    	<td class="tdSpe" NOWRAP>&nbsp;<input type="text" value="input text B1" name="_1_1_2_2_3_1" size="16" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="input text B1 bis" name="_1_1_2_2_4_1" size="16" maxlength="64"></td>
    	<td class="tdSpe" NOWRAP>&nbsp;<TEXTAREA WRAP="soft" name="_1_1_2_2_5_1" ROWS="2" COLS="16">textarea B2</TEXTAREA></td>
    	<td class="tdSpe" NOWRAP>&nbsp;<select name="_1_1_2_2_6_1"><OPTION value="">--<OPTION value="option 1">B3-1<OPTION value="option 2">B3-1<OPTION value="option 3">B3-1</select></td>
    	<td><input type="button" value="Copie" onclick="clone(this.parentNode.parentNode, '_1_1_2');"/></td>
    	<td><input type="button" value="New" onclick="cloneEtVide(this.parentNode.parentNode, '_1_1_2');"/></td>
    	<td><input type="button" value="Suppr." onclick="supprLigne(this.parentNode.parentNode);" /></td>
    </tr>
    <tr id="3">
    	<td>&nbsp;<input type="text" value="input text C1" name="_1_1_2_3_3_1" size="16" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="input text C1 bis" name="_1_1_2_3_4_1" size="16" maxlength="64"></td>
    	<td>&nbsp;<TEXTAREA WRAP="soft" name="_1_1_2_3_5_1" ROWS="2" COLS="16">textarea C2</TEXTAREA></td>
    	<td>&nbsp;<select name="_1_1_2_3_6_1"><OPTION value="">--<OPTION value="option 1">C3-1<OPTION value="option 2">C3-1<OPTION value="option 3">C3-1</select></td>
    	<td><input type="button" value="Copie" onclick="clone(this.parentNode.parentNode, '_1_1_2');"/></td>
    	<td><input type="button" value="New" onclick="cloneEtVide(this.parentNode.parentNode, '_1_1_2');"/></td>
    	<td><input type="button" value="Suppr." onclick="supprLigne(this.parentNode.parentNode);" /></td>
    </tr>
    </table>
     
    </table>
    </body>
    </html>


    J'ai ajouté un "index" en paramètre de mes fonctions. Je souhaite remplacer, dans ma ligne créée, toutes les occurrences (sans se soucier de savoir si c'est name, id, ou autre) de la chaine :
    "index" + "_" + numero de la ligne sur laquelle on a cliqué sur le bouton (rowIndex)
    par
    "index" + "_" + ((nombre total de lignes "rows.length") + 1)

    Je crois que c'est une question d'expression régulière, mais je n'y connais pas grand chose (pas encore, en tout cas ). Comment puis-je faire cela ?

    Et 2 petites autres questions (les dernières ? ^^) :
    - comment faire en sorte que le bouton supprimer n'apparaisse pas s'il ne reste qu'une ligne ?
    - comment faire en sorte qu'on ne puisse plus ajouter de lignes au delà de 15 ?

    Encore un grand merci pour votre aide !

  8. #8
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 198
    Par défaut
    @NoSmoking : ils servent au moment de la soumission du formulaire. Sans rentrer dans les détails, c'est un progiciel qui récupère les données
    ma question n'était pas aussi anodine que cela, tu va donc droit dans le mur avec ce type de gestion et ce d'autant que tu rajoutes une fonction de suppression de ligne donc bonjour les doublons!

    Une solution élégante est de donner des NAME sous forme de tableau, qui seront récupéré, coté serveur sous forme de tableau.
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        <td>&nbsp;<input name="val1[]" type="text" value="" size="32" maxlength="64"></td>
        <td>&nbsp;<input name="val2[]" type="text" value="" size="32" maxlength="64"></td>
    Concernant la création, j'aurais eu plutôt tendance à passer par le clonage, là on est tous d'accord, mais le clonage d'une TR en display:none, pas la TR mais le TBODY qui la contient.

    un exemple de test:
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    <!DOCTYPE html>
    <html lang="fr">
    <head>
    <meta charset="UTF-8">
    <title>Tableau dynamique</title>
    <script type="text/javascript">
    function addLigne( obj){
      var oClone, oRow, oTable = document.getElementById('table1');
      if( typeof(obj)!== 'object'){
        oRow = document.getElementById('new');
      }
      else{
        oRow = obj.parentNode.parentNode;
      }
      oClone = oRow.cloneNode( true);
      oTable.tBodies[1].appendChild( oClone);
    }
    </script>
    </head>
    <body>
    <table id="table1">
    <tbody style="display:none">
      <tr id="new" data-description="la ligne de référence">
        <td>&nbsp;<input name="val1[]" type="text" value="" size="32" maxlength="64"></td>
        <td>&nbsp;<input name="val2[]" type="text" value="" size="32" maxlength="64"></td>
        <td>&nbsp;<input name="val3[]" type="text" value="" size="32" maxlength="64"></td>
        <td><button onclick="addLigne(this);">Copy</button></td>
        <td><button onclick="addLigne();">New</button></td>
      </tr>
    </tbody>
    <tbody>
      <tr>
        <td>&nbsp;<input name="val1[]" type="text" value="Ma valeur A1" size="32" maxlength="64"></td>
        <td>&nbsp;<input name="val2[]" type="text" value="Ma valeur A2" size="32" maxlength="64"></td>
        <td>&nbsp;<input name="val3[]" type="text" value="Ma valeur A3" size="32" maxlength="64"></td>
        <td><button onclick="addLigne(this);">Copy</button></td>
        <td><button onclick="addLigne();">New</button></td>
      </tr>
    </tbody>
    </table>
    <script type="text/javascript">
    addLigne();
    </script>
    </body>
    </html>

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 44
    Par défaut
    Bonjour,

    Merci pour ces conseils !
    Concernant la méthode de clonage et la duplication d'un TBODY de référence plutôt qu'un TR, cela ne me pose pas de problème, et si c'est plus "propre", je suis preneur

    Concernant la gestion des NAME et ID, je n'avais effectivement pas pensé à la gestion de ces identifiants lors de la suppression de lignes...
    Est-ce que leur gestion à l'aide de tableau permettrait de gérer cela ?
    Qu'entends-tu par "récupéré, côté serveur, sous forme de tableau" ? Je ne peux malheureusement pas modifié le comportement côté serveur, et je suppose donc qu'il faut qu'il continue de recevoir des identifiants de type '_1_1_2_1_3_1' pour "lui faire croire" que c'est lui qui a créé les lignes...

    Merci pour ce temps et cette aide.
    Guillaume

  10. #10
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    17 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 17 198
    Par défaut
    Qu'entends-tu par "récupéré, côté serveur,
    - pas un spécialiste du langage mais il y à ce post sur DVP http://www.developpez.net/forums/d11...x/#post6412105

    - pour le reste tu peux toujours réaffecter les ID/NAME avant la soumission ou à l'ajout/suppression d'une ligne en parcourant tous les éléments.

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 44
    Par défaut
    Bonjour,

    (j'ai malheureusement du abandonner mon problème quelques temps...)

    J'ai tenté la fonction suivante, que je compte rendre bien sûr rendre plus dynamique à terme avec le paramètre index, et j'ai fait des tests sur la première ligne avec cette fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    function clone(line, index) {
    	newLine = line.cloneNode(true); //l'option selected des listes déroulantes n'est pas conservée lors du clonage
    	var oldHtml = newLine.innerHTML;
    	var reg = new RegExp ("_1_1_2_1", "g");
    	var newHtml = oldHtml.replace(reg, "_1_1_2_4");
    	alert(newHtml);
    	//newLine.innerHTML = newHtml;
    	line.parentNode.appendChild(newLine);
    }
    Apparemment ma variable newHtml contient bien tout le innerHTML original mais en ayant remplacé _1_1_2_1 par _1_1_2_4 partout, mais si je décommente la ligne newLine.innerHTML = newHTML; pour lui donner ce nouveau innerHTML, la ligne ajoutée apparait vide (1 px de haut, donc...), et je ne comprends pas pourquoi...

    Voici le code complet de ma page :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
     
    <html>
    <head>
    <title>Tableau dynamique</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <style type="text/css">
     
    table { border:thin solid #A2968A; border-collapse:collapse; text-align:center; }
    td { border:thin dotted #A2968A; padding:5px; text-align:center; height: 50px; }
    tr.trSpe { border:thin dotted #A2968A; padding:5px; text-align:center; height: 50px; background-color:#aeaeae; }
    td.tdSpe { border:thin dotted #A2968A; padding:5px; text-align:center; height: 50px; background-color:#aeaeae; }
     
    </style>
    <script type="text/javascript" language="JavaScript">
    function clone(line, index) {
    	newLine = line.cloneNode(true); //l'option selected des listes déroulantes n'est pas conservée lors du clonage
    	var oldHtml = newLine.innerHTML;
    	var reg = new RegExp ("_1_1_2_1", "g");
    	var newHtml = oldHtml.replace(reg, "_1_1_2_4");
    	alert(newHtml);
    	newLine.innerHTML = newHtml;
    	line.parentNode.appendChild(newLine);
    }
    function cloneEtVide(line, index) {
    	newLine = line.cloneNode(true);
    	alert(line.rowIndex);
    	alert("Il y avait "+line.parentNode.rows.length+" lignes");
    	alert("J'ajoute donc une "+(line.parentNode.rows.length + 1)+"e ligne");
    	var mesInput = newLine.getElementsByTagName('INPUT');
    	var mesTextarea = newLine.getElementsByTagName('textarea');
    	var mesSelect = newLine.getElementsByTagName('select');
    	for (i=0 ; i<= mesInput.length-1 ; i++) { if (mesInput[i].type == 'text') mesInput[i].value=""; }
    	for (i=0 ; i<= mesTextarea.length-1 ; i++) { mesTextarea[i].innerHTML = ""; }
    	for (i=0 ; i<= mesSelect.length-1 ; i++) { mesSelect[i].selectedIndex = 0; }
    	line.parentNode.appendChild(newLine);
    	alert(newLine.rowIndex);
     
    }
    function supprLigne(line) {
    	line.parentNode.removeChild(line);
    }
    </script>
    </head>
    <body>
     
    <table id="table1" border="1" cellspacing="0" cellpadding="0">
    <tr id="1" class="trSpe">
    	<td>&nbsp;<input type="text" value="input text A1" name="_1_1_2_1_3_1" size="16" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="_1_1_2_1_4_1" name="_1_1_2_1_4_1" size="16" maxlength="64"></td>
    	<td>&nbsp;<TEXTAREA WRAP="soft" name="_1_1_2_1_5_1" ROWS="2" COLS="16">textarea A2</TEXTAREA></td>
    	<td>&nbsp;<select name="_1_1_2_1_6_1"><OPTION value="">--<OPTION value="option 1">A3-1<OPTION value="option 2">A3-1<OPTION value="option 3">A3-1</select></td>
    	<td>
    		<input type="button" value="Copie" onclick="clone(this.parentNode.parentNode, '_1_1_2_1');">
    		<input type="button" value="New" onclick="cloneEtVide(this.parentNode.parentNode, '_1_1_2_1');">
    		<input type="button" value="Suppr." onclick="supprLigne(this.parentNode.parentNode);">
    	</td>
    </tr>
    <tr id="2">
    	<td class="tdSpe" NOWRAP>&nbsp;<input type="text" value="input text B1" name="_1_1_2_2_3_1" size="16" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="_1_1_2_2_4_1" name="_1_1_2_2_4_1" size="16" maxlength="64"></td>
    	<td class="tdSpe" NOWRAP>&nbsp;<TEXTAREA WRAP="soft" name="_1_1_2_2_5_1" ROWS="2" COLS="16">textarea B2</TEXTAREA></td>
    	<td class="tdSpe" NOWRAP>&nbsp;<select name="_1_1_2_2_6_1"><OPTION value="">--<OPTION value="option 1">B3-1<OPTION value="option 2">B3-1<OPTION value="option 3">B3-1</select></td>
    	<td>
    		<input type="button" value="Copie" onclick="clone(this.parentNode.parentNode, '_1_1_2_2');">
    		<input type="button" value="New" onclick="cloneEtVide(this.parentNode.parentNode, '_1_1_2_2');">
    		<input type="button" value="Suppr." onclick="supprLigne(this.parentNode.parentNode);">
    	</td>
    </tr>
    <tr id="3">
    	<td>&nbsp;<input type="text" value="input text C1" name="_1_1_2_3_3_1" size="16" maxlength="64"></td>
    	<td>&nbsp;<input type="text" value="_1_1_2_3_4_1" name="_1_1_2_3_4_1" size="16" maxlength="64"></td>
    	<td>&nbsp;<TEXTAREA WRAP="soft" name="_1_1_2_3_5_1" ROWS="2" COLS="16">textarea C2</TEXTAREA></td>
    	<td>&nbsp;<select name="_1_1_2_3_6_1"><OPTION value="">--<OPTION value="option 1">C3-1<OPTION value="option 2">C3-1<OPTION value="option 3">C3-1</select></td>
    	<td>
    		<input type="button" value="Copie" onclick="clone(this.parentNode.parentNode, '_1_1_2_3');">
    		<input type="button" value="New" onclick="cloneEtVide(this.parentNode.parentNode, '_1_1_2_3');">
    		<input type="button" value="Suppr." onclick="supprLigne(this.parentNode.parentNode);">
    	</td>
    </tr>
    </table>
     
    </table>
    </body>
    </html>

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2005
    Messages
    44
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2005
    Messages : 44
    Par défaut
    Il fallait s'en douter, le problème vient d'IE...

    J'ai trouvé la cause sur cette discussion
    "The property (innerHTML) is read/write for all objects except the following, for which it is read-only: COL, COLGROUP, FRAMESET, HEAD, HTML, STYLE, TABLE, TBODY, TFOOT, THEAD, TITLE, TR."

    Et ma newLine est bien une ligne TR...
    Les TD étant épargnées, j'ai mis cette boucle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	var tds = newLine.getElementsByTagName('td');
    	for(var i=0; i<tds.length; i++) {
    		tds[i].innerHTML = tds[i].innerHTML.replace(reg, '_1_1_2_4');
    	}
    J'ai "plus qu'à" gérer correctement tout les identifiants lors des ajouts (ça devrait aller), et surtout la suppression de lignes, pour laquelle je suis preneur de toute inspiration de boucle JS

  13. #13
    Expert confirmé
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 660
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 660
    Par défaut
    bonsoir,

    peut-être que le code posté dans ce sujet pourra t'aider :
    http://www.developpez.net/forums/d33...u/#post2057900

Discussions similaires

  1. Ajout d'une ligne à un tableau comprennant un calendrier
    Par tavarlindar dans le forum Général JavaScript
    Réponses: 22
    Dernier message: 01/09/2008, 18h18
  2. Ajouter 1 ligne à un tableau avec rowspan & colspan
    Par softflower dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 22/11/2006, 22h35
  3. [Tableaux] Ajout dynamique de lignes à un tableau
    Par loreleï85 dans le forum Langage
    Réponses: 6
    Dernier message: 22/06/2006, 17h14
  4. Ajouter une ligne à un tableau
    Par Oluha dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 16/02/2005, 15h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo