Balayer un tableau en javascript

Résolu
orionis1 Messages postés 40 Date d'inscription mardi 20 novembre 2007 Statut Membre Dernière intervention 7 juillet 2010 - 20 nov. 2007 à 08:43
 fouratinourhen - 24 mai 2011 à 16:06
bonjour à tous,
Débutant en javasacript, je me heurte au problème suivant :
Je développe une page html (couplée à du php) de saisie de bon de commande.
J'ai trouvé ici http://www.the-asw.com/post/2005/09/18/50-une-interface-de-formulaire-a-base-de-tableaux-dynamiques
un exemple de tableau dynamique permettant la gestion de ligne. Jusque là, tout fonctionne correctement.

J'aimerais à présent, à chaque ajout de ligne, vérifier préalablement que l'utilisateur a bien saisi une valeur dans toutes les zones. Comment faire pour balayer les 5 cellules de chaque ligne (un simple test d'existence des données suffirait)?

Voici les fonctions JS permettant la gestion dynamique du tableau des lignes de commande :
/* 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);
    }

/* ajoute une ligne */
function addLigne(link)
    {
    // 0. tester la saisie sur toutes les zones.

    // 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);
   
    if ( document.all )
        newTr.style.display = "block"; // pour IE
    else
        newTr.style.display = "table-row"; // pour Gecko   
    }

/* 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'));
    }

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);
            }
        }
    }

Et le code html correspondant :
   
        ----

            Part Number,
            Description,
            Prix unitaire HT,
            Qt&eacute;,
            Total,
            Action,
       
   
   
   
        ----

            ,
            ,
            ,
            ,
            ,
            Supp,
       
   
   
    <tfoot>
        ----

            Ajouter une ligne |
            TOTAL |
            tot |
            |
       
       
    </tfoot>   

45 réponses

cs_bultez Messages postés 13615 Date d'inscription jeudi 13 février 2003 Statut Membre Dernière intervention 15 octobre 2013 30
20 nov. 2007 à 10:02
Bonjour,

    >>J'aimerais à présent, à chaque ajout de ligne, vérifier préalablement
que
    >>l'utilisateur a bien saisi une valeur dans toutes les zones.
          euh... quand on ajoute une ligne, ces champs de saisie sont vides
          ou alors on veut contrôler la ligne précédente ?
                et dans ce cas, quid de la dernière ?

    >>Comment faire pour balayer les 5 cellules de chaque ligne
       rowIndex c'est le n° de ligne
       document.name du formulaire['champ1[]'][index de la ligne].value  c'est le contenu
               du 1er champ de la ligne voulue

>>un simple test d'existence des données suffirait?
    pour contrôler ?    à priori non...
    une quantité, se doit d'être numérique, par exemple

encore une remarque : tel que c'est fait on se retrouve avec des champs
    multiples qui ont le même ID... ce qui est interdit.





<hr />                Cordialement            Bul        
3
cs_bultez Messages postés 13615 Date d'inscription jeudi 13 février 2003 Statut Membre Dernière intervention 15 octobre 2013 30
20 nov. 2007 à 10:04
ou alors, on contrôle toutes les lignes avant l'envoi ?
<hr />                Cordialement            Bul        
3
Anthed Messages postés 152 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 17 janvier 2014 3
20 nov. 2007 à 11:22
Dans ta fonction qui ajoute une ligne, il suffit d'affecter à chaque input de chaque cellule un nom unique :
input.id = "champ_" + i + "_" + j;
où i  et j peuvent désigner respectivement le numéro d'ordre de la ligne et de la cellule concernées.

A toi de voir si tu conserves le système de clonage de lignes de ta fonction addLigne ou si tu crées une véritable nouvelle ligne (tu peux garder ton clonage et modifier les id après).
3
Anthed Messages postés 152 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 17 janvier 2014 3
20 nov. 2007 à 11:35
Il faut ajouter l'attribut id à ton tableau :
<table class='dTable' bgcolor="white" border="4" id="ton_tableau">

class et id sont deux notions indépendantes, elles coexistent sans problème.

A+.
3

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

Posez votre question
Anthed Messages postés 152 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 17 janvier 2014 3
20 nov. 2007 à 13:56
Pour chaque cellule, tu peux tenter quelquechose du style :
cell = ... // ta cellule récupérée précédemment
var input;
if (cell.children != null) {
for (var k = 0; k < cell.children.length; k++) {
input = cell.children[k]; if (input !null && input.tagName "INPUT") {
// input trouvé : tu peux lui affecter son id
input.id = ...
   }
}
}

Pour des histoires de compatibilité de code pour tous les navigateurs, je te laisse vérifier si childNodes est plus aproprié que children ...
3
Anthed Messages postés 152 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 17 janvier 2014 3
20 nov. 2007 à 15:03
Si ton tableau est inclus dans un formulaire, un form.submit() dudit formulaire devrait amplement suffire (l'attribut "action" de ce formulaire étant valorisé avec l'URL désirée).
3
Anthed Messages postés 152 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 17 janvier 2014 3
20 nov. 2007 à 16:08
Je te conseille, pour savoir réellement ce qui est construit et ce qui est envoyé, d'utiliser les plugins de FireFox pour vérifier le contenu DOM de ta page (Firebug) et les champs envoyés dans ta requête (Tamper Data).
A+.
3
Anthed Messages postés 152 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 17 janvier 2014 3
20 nov. 2007 à 16:10
N'oublie pas de vérifier la présence et l'unicité des noms de tes inputs ...
3
Anthed Messages postés 152 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 17 janvier 2014 3
21 nov. 2007 à 14:51
Hello,

Une solution un peu sauvage mais qui devrait marcher consiste effectivement à construire "manuellement" l'url avec tous les paramètres qui t'intéressent.

var form = document.forms["le_nom_de_ton_formulaire"];

function getParams() {
var i;
var param = "";
var element;
var name;
var value;
for (i = 0; i < form.elements.length; i++) {
element = form.elements[i];
name = element.name;
if (name != "") {
value = element.value;
if (value != "") {
if (param != "") {
param += "&";
}
param += name + "=" + value;
}
}
}
return param;
}

getParams() retourne alors une chaîne du style : "name1=value1&name2=value2&...&nameN=valueN'
que tu n'as plus qu'à concaténer à ton url de départ.

Voila :)
A+.
3
Anthed Messages postés 152 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 17 janvier 2014 3
21 nov. 2007 à 15:59
Pour ce qui concerne la récupération des valeurs, il vaut mieux travailler sur les names que sur les ids.

Ensuite, pour faire plus clair et plus propre, modifie l'attribut onclick de ton input :
onclick="submitForm();"
où submitForm() doit ressembler à peu près à ça :

function submitForm() {
if (confirm('Creation du bon de commande?')) {
var form = document.forms["le_nom_de_ton_formulaire"];
form.action = "ton_url?" + getParams();
form.submit();
}
}

A+.
3
Anthed Messages postés 152 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 17 janvier 2014 3
21 nov. 2007 à 16:01
Différence entre name et id :

- name est le nom envoyé lorsque tu soumets ton formulaire et que tu devrais récupérer automatiquement au niveau de ton serveur sans à avoir à ajouter name=value à ton url (problème en cours "d'élucidation" ...)

- id est l'identifiant que l'on peut associer à n'importe quel élément HTML pour le manipuler dynamiquement via document.getElementById() par exemple.
3
Anthed Messages postés 152 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 17 janvier 2014 3
22 nov. 2007 à 16:30
N'aurais-tu pas oublié les lignes ...
table.rows retourne un tableau de ligne
Pour chaque ligne, table.rows[i].cells retourne un tableau contenant les cellules de la ligne en question

Encore un conseil pour débugguer : pour être sûr de ton élément :
alert(element.innerHTML)    (quand c'est possible, ça dépend du type)
alert(element.tagName)      (très utile : le type de l'élément -> '<TR>' dans ton cas au lieu de '<TD>')

A+.
3
Anthed Messages postés 152 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 17 janvier 2014 3
26 nov. 2007 à 15:14
Ce n'est pas plutôt dans une des TD de la ligne que tu peux récupérer ton montant (plutôt que dans le contenu de la ligne en entier) ?
3
Anthed Messages postés 152 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 17 janvier 2014 3
26 nov. 2007 à 15:29
Voui !
Seulement, après :
var ligne=getParent(td,'TR');

il faut parcourir les cellules à la recherche de celle qui contient ton montant, à moins que tu ne connaisses son indice. Par exemple, si tu sais que c'est la troisième :
var cell = ligne.cells[2];

Une fois la cellule trouvée, si elle contient un input (en première position)
var amount = cell.firstChild.value;

S'il ne s'agit pas forcément du premier élément de ta cellule, un petit parcours des éléments avec test de l'attribut tagName de chacun d'entre eux jusqu'à obtenir 'INPUT' devrait fonctionner.
A+.
3
Anthed Messages postés 152 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 17 janvier 2014 3
4 déc. 2007 à 12:43
boncd est le nom de ton formulaire ? Si oui, inclut-il ton élément tot_port_1 ?
Sinon, comme d'hab, vérification à tatons :
alert(document.boncde);

puis :
alert(document.boncde.tot_port_1);

avec tagName and co ...
3
Anthed Messages postés 152 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 17 janvier 2014 3
20 nov. 2007 à 09:37
Hello,

Pour parcourir ton tableau :
var table = document.getElementById("ton_tableau");
var row;
var cell;
var element;
for (var i = 0; i < table.rows.length; i++) {
row = table.rows[i];
for (var j = 0; j < row.cells.length; j++) {
cell = row.cells[j];
// ex1 : cellule contenant directement du texte.
alert("Contenu de la cellule [" + i + ";" + j + "] : " + cell.innerHTML);
// ex2 : cellule contenant un champ de saisie.
element = cell.firstChild; if (element !null && element.tagName "INPUT") {
alert("Contenu du champ dans la cellule : " + element.value);
}
}
}

A toi d'adapter les tests dans la 2ème boucle 'for' pour récupérer ce qui t'intéresse en fonction de la cellule concernée.

Remarques :

1. les crochets dans tes noms d'inputs ne sont pas forcément conseillés : champ2[]

2. tu peux remplacer :

[# Supp]

par :

Supp
1
orionis1 Messages postés 40 Date d'inscription mardi 20 novembre 2007 Statut Membre Dernière intervention 7 juillet 2010
20 nov. 2007 à 09:52
Merci anthed pour ta réponse rapide.
Juste une remarque : actuellement, le tableau en question est déclaré avec une classe (class dTable), utilisée dans la fonction dTableInit().

Comment définir alors la variable table dans ta proposition? A ma connaissance, on ne peut pas déclarer à la fois une classe et un Id?
0
orionis1 Messages postés 40 Date d'inscription mardi 20 novembre 2007 Statut Membre Dernière intervention 7 juillet 2010
20 nov. 2007 à 10:13
>euh... quand on ajoute une ligne, ces champs de saisie sont vides ou alors on veut contrôler la ligne précédente ?

On contrôle la ligne précédente, dans mon idée.

>et dans ce cas, quid de la dernière ?

Heu, je ne sais pas...

>
ou alors, on contrôle toutes les lignes avant l'envoi ?

Oui, ça reste une solution peut-être plus imple à programme dans la page php (du moins, je sais faire).
Reste à savoir comment mémoriser les X cellules des Y lignes ajoutées?
0
orionis1 Messages postés 40 Date d'inscription mardi 20 novembre 2007 Statut Membre Dernière intervention 7 juillet 2010
20 nov. 2007 à 11:29
OK, merci Anthed, mais je ne parviens toujours pas à récupérer l'objet tableau avec la ligne :
var table = document.getElementById("ton_tableau");
0
orionis1 Messages postés 40 Date d'inscription mardi 20 novembre 2007 Statut Membre Dernière intervention 7 juillet 2010
20 nov. 2007 à 11:37
d'accord, c'était mon souci!
je teste et te tiens au courant.
merci
0
Rejoignez-nous