Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Contrôle formulaire en Javascript avant contrôle en PHP

16 réponses
Avatar
Sam Lion
Bonjour à tous,
Un bout de code pour expliquer mon problème.
Soit un formulaire tout bête suivant :

---
<form name="ma_liste" action="" method="post">
<p>Quantité 1 : <input type="text" name="quantite[]" size="10" /></p>
<p>Quantité 2 : <input type="text" name="quantite[]" size="10" /></p>
[suite = submit etc.]
</form>
---
Il peut y avoir de une à des dizaines de lignes de quantité.

Pour le contrôler, je dois faire la somme des quantités
- En php, pas de problème : quantite[] me renvoie un tableau, je fais la
somme des quantités.
- En javascript avant envoi, a priori pas compliqué non plus :

---
function somme_quantite()
{

var nb_lignes = document.ma_liste.elements["quantite[]"].length;

for(i=0;i<nb_lignes;i++)
{
[Je fais la somme et divers traitements]
}

}
---

Mais c'est là que mon problème surgit : Quand il n'y a qu'une seule ligne
dans le formulaire, le javascript ne considère pas quantite[] comme un
tableau, et "nb_lignes" n'est donc pas défini, ni "
document.ma_liste.elements["quantite[]"][i].value " dans la boucle
Y-a-t-il un moyen simple pour contourner ce problème ?

Merci d'avance,

Sam.

10 réponses

1 2
Avatar
Bol
<form name="ma_liste" action="" method="post">
<p>Quantité 1 : <input type="text" name="quantite[]" size="10" /></p>
<p>Quantité 2 : <input type="text" name="quantite[]" size="10" /></p>
[suite = submit etc.]
</form>

var nb_lignes = document.ma_liste.elements["quantite[]"].length;

Mais c'est là que mon problème surgit : Quand il n'y a qu'une seule ligne
dans le formulaire, le javascript ne considère pas quantite[] comme un
tableau, et "nb_lignes" n'est donc pas défini, ni "
document.ma_liste.elements["quantite[]"][i].value " dans la boucle
Y-a-t-il un moyen simple pour contourner ce problème ?



Pour le JS "quantite[]" n'est jamais un tableau, uniquement pour PHP
pour le JS c'est elements le tableau avec des inputs ayant le même
nom "quantite[]"

Tu peux gerer les index en dur

for( $i = 0 ; $i < $machin ; $i++ )
echo '<input type="text" name="quantite[',$i,']" size="10" />';

puis en JS

document.ma_liste.elements["quantite["+i+"]"];

A+
Bol
Avatar
Y.D.
Le 22/11/2010 10:50, Sam Lion a écrit :
Mais c'est là que mon problème surgit : Quand il n'y a qu'une seule ligne dans le formulaire, le javascript ne considère pas quantite[] comme un tableau, et "nb_lignes" n'est donc pas défini, ni " document.ma_liste.elements["quantite[]"][i].value " dans la boucle
function somme_quantite()
{[...]



Je suggère de créer un tableau à un seul élément. Par exemple :

function somme_quantite()
{
var lignes = document.ma_liste.elements["quantite[]"];
if(!lignes.length) lignes = new Array(lignes);
var nb_lignes = lignes.length;
for(i=0;i<nb_lignes;i++)
{[Fais la somme et divers traitements sur lignes[i]]}
}

--
Y.D.
Avatar
Pascal
Le 22/11/2010 10:50, Sam Lion a écrit :
Bonjour à tous,



Bonjour à toi,

<form name="ma_liste" action="" method="post">
<p>Quantité 1 : <input type="text" name="quantite[]" size="10" /></p>
<p>Quantité 2 : <input type="text" name="quantite[]" size="10" /></p>
[suite = submit etc.]
</form>



Pas courant que des "input" de type "text" portent le même nom.
Sûr qu'il n'y aura pas de contrôle à faire en tenant compte de leur
position, ou quoi que ce soit qui oblige à les identifier séparément ?

Mais c'est là que mon problème surgit : Quand il n'y a qu'une seule
ligne dans le formulaire, le javascript ne considère pas quantite[]
comme un tableau, et "nb_lignes" n'est donc pas défini, ni "
document.ma_liste.elements["quantite[]"][i].value " dans la boucle
Y-a-t-il un moyen simple pour contourner ce problème ?



Les deux réponses que tu as déjà reçues sont valables, à part quelques
détails que je vais me permettre de corriger (voir mes retours de
commentaire sur ces réponses).
Je ne vois pas d'autres solutions, immédiatement.

Merci d'avance,


De rien.

--
Cordialement,
Pascal
Avatar
Pascal
Bonjour,

Le 22/11/2010 11:43, Bol a écrit :
Pour le JS "quantite[]" n'est jamais un tableau, uniquement pour PHP
pour le JS c'est elements le tableau avec des inputs ayant le même
nom "quantite[]"



Oh que si ! C'est également un tableau pour JS.

Heureusement, d'ailleurs, sinon comment traiter les "input" de type
"radio" ?

La preuve, c'est qu'il retourne bien la valeur attendue pour sa
propriété "length".

Tu peux gerer les index en dur



C'est ce que je ferais aussi, ça me parait plus sûr.


--
Cordialement,
Pascal
Avatar
Sam Lion
Les deux réponses que tu as déjà reçues sont valables, à part quelques
détails que je vais me permettre de corriger (voir mes retours de
commentaire sur ces réponses).
Je ne vois pas d'autres solutions, immédiatement.

Merci d'avance,


De rien.

--
Cordialement,
Pascal



Merci Bol, Y.D. et Pascal pour ces réponses rapides,
J'ai testé les 2 solutions et les 2 fonctionnent (avec un peu d'adaptation
pour coller à mes besoins)
Curieux que je n'ai pas trouvé directement une solution sur le net, car
cette question doit se poser souvent...m'ai j'ai peut être mal cherché !
Bonne fin de journée,
Sam.
Avatar
Pascal
Bonjour,

Le 22/11/2010 12:49, Y.D. a écrit :
function somme_quantite()
{
var lignes = document.ma_liste.elements["quantite[]"];
if(!lignes.length) lignes = new Array(lignes);



Là, pas d'accord, enfin pas tout à fait, quoi.

D'abord, la propriété "length" n'a pas de sens pour un objet de type
HTMLInputElement. Elle est indéfinie et doit donc être testée comme tel.

Ensuite, passer cet objet au constructeur "Array" ne me parait pas
judicieux. Autant utiliser la syntaxe littérale, toujours plus sure.

Enfin, utiliser la même variable pour désigner une liste ou un élément
unique, c'est limite, y compris pour un langage hautement dynamique.

Donc, en résumé :

if (lignes.length == undefined) {
var quantites = [lignes];
} else {
var quantites = lignes;
}
// ou opérateur ternaire :
// var quantites = (lignes.length == undefined) ? [lignes] : lignes
var nbQtes = quantites.length;
for (i=0; i < nbQtes; i++) {
// traitement sur quantites[i]
}


--
Cordialement,
Pascal
Avatar
Sam Lion
Donc, en résumé :

if (lignes.length == undefined) {
var quantites = [lignes];
} else {
var quantites = lignes;
}



C'est ce que j'ai fait quand je parlais d'adaptation.
Plus exactement je l'ai fait à l'envers :

var lignes = document.ma_liste.elements["ttc[]"].value;
if(typeof lignes =="string")

...Etc.

Sam
Avatar
Pascal
Le 22/11/2010 16:32, Sam Lion a écrit :
var lignes = document.ma_liste.elements["ttc[]"].value;
if(typeof lignes =="string")



Pardon d'être tatillon, mais si "lignes" est un tableau, il ne possèdera
pas de propriété "value", n'est-ce pas ?

--
Cordialement,
Pascal
Avatar
Sam Lion
"Pascal" a écrit dans le message de groupe
de discussion : ice3bn$tle$
Le 22/11/2010 16:32, Sam Lion a écrit :
var lignes = document.ma_liste.elements["ttc[]"].value;
if(typeof lignes =="string")



Pardon d'être tatillon, mais si "lignes" est un tableau, il ne possèdera
pas de propriété "value", n'est-ce pas ?

--
Cordialement,
Pascal



Oui et non (à mon avis de non spécialiste de javascript), si c'est un
tableau la propriété est "undefined", donc typeof lignes ne me renvoie pas
"string" et je sais donc que j'ai plusieurs lignes...
Ce n'est pas exactement l'inverse que de faire "lignes.length == undefined"
pour vous ?
Sam
Avatar
Y.D.
Le 22/11/2010 16:19, Pascal a écrit :
Le 22/11/2010 12:49, Y.D. a écrit :
function somme_quantite()
{
var lignes = document.ma_liste.elements["quantite[]"];
if(!lignes.length) lignes = new Array(lignes);



Là, pas d'accord, enfin pas tout à fait, quoi.

D'abord, la propriété "length" n'a pas de sens pour un objet de type
HTMLInputElement. Elle est indéfinie et doit donc être testée comme tel.



Ah ! Et que vaut !undefined ?
Si c'est une question de style, plutôt que tester undefined je préférerai
if (!("length" in lines))

Ensuite, passer cet objet au constructeur "Array" ne me parait pas judicieux.
Autant utiliser la syntaxe littérale, toujours plus sure.



En quoi est-ce plus sûr ? Quant aux perfs, ça dépend des navigateurs voir
<http://jsperf.com/literal-vs-constructor-array>.
On peut aussi écrire
lignes = Array(lignes);
c'est tout aussi correct.

Enfin, utiliser la même variable pour désigner une liste ou un élément unique,
c'est limite, y compris pour un langage hautement dynamique.



Ça, c'est votre problème pas celui du javascript qui s'y retrouve tout à fait et
qui impose dans votre code un else et une affectation inutiles (ou l'utilisation
de l'opérateur ternaire).

--
Y.D.
1 2