Construire une table en JavaScript

Résolu/Fermé
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 - Modifié le 11 mars 2022 à 10:41
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 - 12 mars 2022 à 17:51
Bonjour à tous,

J'ai une page de ma web-application qui affiche les données d'une facture en provenance d'une base de
données et les présente sous forme d'une construction Javascript à base de <div>.
(le Javascript c'est parce que cette page permet de modifier la facture à la volée avt de la renvoyer
dans la bdd via un formulaire)

Tout fonctionne bien avec les div, sauf que pour des raisons de présentation et d'uniformisation avec les
autres pages récap des factures je voudrais présenter le contenu de la facture sous la forme d'une <table>...

Et c'est là que je suis en galère depuis en moment car j'ai beau tourner les lignes de codes dans tous les sens
le tableau se construit au mieux sous la forme d'une seule colonne !!!

Voici mon code pour mieux comprendre :
<table>
    <thead>
        <tr>
            <th class="th-prestations">DÉSIGNATIONS</th
            <th class="th-pu">PU</th>
            <th>QUANTITÉS</th>
            <th class="th-total">TOTAL</th>
        </tr>
    </thead>
    <tbody id="detail_contrat">
    </tbody>
</table>


La partie PHP n'est pas présente ici car elle ne pose aucun problème, d’ailleurs l'affichage en div se passe bien



function contrat(){
    var tableau_contrat = chaine_contrat.value.split('|');
    var nb_lignes = tableau_contrat.length;
    document.getElementById("detail_contrat").innerHTML = "";
    for (ligne = 0; ligne < nb_lignes; ligne++) {
        if (tableau_contrat[ligne] != "") {
        var ligne_contrat = tableau_contrat[ligne].split(';');
        document.getElementById("detail_contrat").innerHTML += "<tr>";
        // Affichage de la DÉSIGNATION de la prestation :
        document.getElementById("detail_contrat").innerHTML += "<td id='col1'>" + ligne_contrat[1] + "</td>";
        // Affichage du PRIX de la prestation :
        document.getElementById("detail_contrat").innerHTML += "<td id='col2'>" + ligne_contrat[2] + "</td>";
        // Affichage de la QUANTITÉ de la prestation :
        document.getElementById("detail_contrat").innerHTML += "<td id='col3'>" + ligne_contrat[3] + "</td>";
        document.getElementById("detail_contrat").innerHTML += "</tr>";
        //document.getElementById("detail_contrat").innerHTML += "<td id='col4'><input type='button' class = 'btn_annulation' value = '✘' title ='Supprimer la prestation' onclick='suppr(\"" + tableau_contrat[ligne] + "\");'/></td>";
        }
    }
}




Merci d'avance pour votre aide !

Configuration: Linux / Chrome 99.0.4844.51

9 réponses

jordane45 Messages postés 38145 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 25 avril 2024 4 650
11 mars 2022 à 11:12
Bonjour,

Remplace le code de ta fonction par ça et montres nous ce que ça donne ainsi que ce qui est affiché dans la console de ton navigateur

function contrat(){
  var tableau_contrat = chaine_contrat.value.split('|');
  var nb_lignes = tableau_contrat.length;
  var detail_contrat = document.getElementById("detail_contrat");
  var HTML = "";
    
  detail_contrat.innerHTML = "";
  for (ligne = 0; ligne < nb_lignes; ligne++) {
    if (tableau_contrat[ligne] != "") {
      var ligne_contrat = tableau_contrat[ligne].split(';');
      HTML += "<tr>";
      // Affichage de la DÉSIGNATION de la prestation :
      HTML += "<td id='col1'>" + ligne_contrat[1] + "</td>";
      // Affichage du PRIX de la prestation :
      HTML += "<td id='col2'>" + ligne_contrat[2] + "</td>";
      // Affichage de la QUANTITÉ de la prestation :
      HTML += "<td id='col3'>" + ligne_contrat[3] + "</td>";
      //HTML += "<td id='col4'><input type='button' class = 'btn_annulation' value = '✘' title ='Supprimer la prestation' onclick='suppr(\"" + tableau_contrat[ligne] + "\");'/></td>";
      HTML += "</tr>";
    }
    console.log('HTML',HTML);
    detail_contrat.innerHTML = HTML;
  }
}

1
Pitet Messages postés 2826 Date d'inscription lundi 11 février 2013 Statut Membre Dernière intervention 21 juillet 2022 524
Modifié le 12 mars 2022 à 11:00
Bonjour,

Tu ne peux pas utiliser innerHTML pour ajouter des extraits incomplet de code html. Le code html passé à innerHTML doit être complet et valide.

Par exemple, dans ta boucle, lorsque tu ajoutes la balise ouvrante <tr> via
document.getElementById("detail_contrat").innerHTML += "<tr>";

le navigateur analyse la valeur comme l'ajout d'une balise tr complète, il va donc automatiquement ajouter la balise fermante à la suite de la balise ouvrante, donc <tr></tr> : ton résultat sera donc sur une seule colonne.
En utilisant une variable intermédiaire comme suggéré par jordane45, le code html passé à innerHTML en une seule fois est alors correctement analysé par le navigateur puisque celui-ci est complet.

Au lieu d'utiliser innerHTML, tu pourrais utiliser les fonctions js dédiées à la création et l'ajout d'élément HTML tel que createElement(), appendChild(), etc.
Tu pourras ainsi utiliser createTextNode() pour l'échappement des caractères.

Attention aux attributs id de tes colonnes (id="col1", id="col2", etc.), les identifiants HTML doivent être uniques or tu vas avoir plusieurs fois le même identifiant si ton tableau contient plusieurs lignes. Tu pourrais éventuellement ajouter le numéro du contrat pour rendre les identifiants uniques.

function contrat(){
  var tableau_contrat = chaine_contrat.value.split('|');
  var nb_lignes = tableau_contrat.length;
  document.getElementById("detail_contrat").innerHTML = "";

  for (ligne = 0; ligne < nb_lignes; ligne++) {
    if (tableau_contrat[ligne] != "") {
      var ligne_contrat = tableau_contrat[ligne].split(';');

      var col1 = document.createElement('td');
      col1.setAttribute('id', 'contrat' + ligne + '-col1');
      col1.appendChild(document.createTextNode(ligne_contrat[1]));

      var col2 = document.createElement('td');
      col2.setAttribute('id', 'contrat' + ligne + '-col2');
      col2.appendChild(document.createTextNode(ligne_contrat[2]));

      var col3 = document.createElement('td');
      col3.setAttribute('id', 'contrat' + ligne + '-col3');
      col3.appendChild(document.createTextNode(ligne_contrat[3]));

      var tr = document.createElement('tr');
      tr.appendChild(col1);
      tr.appendChild(col2);
      tr.appendChild(col3);

      document.getElementById("detail_contrat").appendChild(tr);
    }
  }
}
1
jordane45 Messages postés 38145 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 25 avril 2024 4 650
12 mars 2022 à 17:48
Bonjour
Je me permets juste une petite remarque

Les caractères spéciaux ont été neutralisés (?) à l'enregistrement dans la bdd par htmlspecialchars)
Je vais essayer de les échapper avant d'arriver au JavaScript, directement dans le traitement post requête PHP

Alors non... La fonction htmlspecialchars ne doit pas être utilisée pour protéger les données à mettre en base mais uniquement au moment de les restituer pour l'affichage.
Pour protéger les données lors de l'insertion dans une base de données, désormais il existe les requêtes préparées..
On stocke toujours les données brutes dans la base... Le faire autrement et une mauvaise pratique de débutants...

Pour ce qui est des échappées les quotes en javascript, des des codes sont facilement trouvable pour le faire. Une rapide recherche avec les mots clés js addslashes. Devrait suffire à trouver votre bonheur.
1
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
11 mars 2022 à 11:25
C'est super !!! Mais pourquoi ma méthode qui s'affichait bien en <div> ne fonctionnait plus en <tr> <td> ?



0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
11 mars 2022 à 11:27
Pourquoi utilises-tu une var HTML = ""; alors que .innerHTML += "xxx" est supposé faire le boulot ?
0
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
11 mars 2022 à 11:39
D'autre part, en faisant des tests au hasard je suis tombé sur un enregistrement qui a fait tout foirer :
Celui là : Jardin', 3 chambres, salle à manger, accès jardin

Je pense que c'est parce qu'il contient une apostrophe, erreur de saisie de l'utilisateur !
Existe t'il un moyen d’échapper ce genre de caractère pour éviter les crashs ?
0
Plus simple est de les interdire en testant dans le form d'envoi(en premier lieu et avec vérif derrière sur serveur).
Sinon pour échapper un caractère JavaScript c'est le symbole antislash qui est utilisé ou bien utiliser une notation ASCII(ou autre)/

console.log("Salut c\'est échappé")
1
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
Modifié le 11 mars 2022 à 14:14
Merci pour ton aide toto,

c'est ennuyeux de les interdire car l'utilisateur peut être amené dans le formulaire d'envoi à saisir un commentaire contenant un ' (ou en créant une désignation TABLE D'HÔTES par exemple)

il faut que je trouve le moyen de les échapper à la lecture de la $chaîne mais mes compétences en javascript sont trop limitées...

(Les caractères spéciaux ont été neutralisés (?) à l'enregistrement dans la bdd par htmlspecialchars)
Je vais essayer de les échapper avant d'arriver au JavaScript, directement dans le traitement post requête PHP à moins que le remplacement de type VARCHAR en TXT dans la bdd puisse changer qq chose...
0
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
12 mars 2022 à 17:25
Alors là, cette réponse est vraiment un cours complet, merci Pitet pour ton temps !
Merci à vous trois pour m'avoir permis de faire avancer mon travail !
0
emrh Messages postés 427 Date d'inscription mardi 9 décembre 2014 Statut Membre Dernière intervention 9 avril 2024 20
12 mars 2022 à 17:51
Je fais bien mes requêtes avec prepare et execute et je pensais que htmlspecialchars était une sécurité supplémentaire...
Je te remercie pour cette précision !
0