J'ai appris Javascript à une (lointaine) époque mais sans avoir pratiqué, j'ai plus que beaucoup perdu mes connaissance à ce sujet...
Après avoir étudié une multitude de vos postes me voici avec un soucis pour lequel je ne trouve pas de solution depuis quelque jour et qui me bloque quelque peu.
Mon sujet concerne une page d'auto contrôle qui servira dans l'atelier pour les différents opérateur.
J'ai une page en php qui est alimenté via Mysql qui me permet d'afficher les différents points qui doivent être contrôlé.
Suivant le poste il peut y avoir un seul poste comme 5 voir 6 postes.
Dans ma page php, j'ai intégré un formulaire qui contient, entre autre, des boutons radio (OK, NOK et N/A) ainsi qu'un textarea afin de pouvoir commenter quand la réponse choisie est NOK ou N/A.
Ce que je souhaite, c'est que quand on sélection OK, la textarea soit masqué et que quand on sélectionne NOK OU N/A alors la textarea s'affiche et qu'elle soit alors obligatoirement complétée. Chose qui fonctionne, avec du script, quand je n'ai qu'un poste à contrôler mais quand il y a plus de poste à contrôler, le 1er poste fonctionne correctement mais pas les suivant (la textare reste visible)
Voilà, je vous ai exposé mon soucis, maintenant je vous donne les différents code que j'ai mis en place.
un id doit être unique sur la page. Or ton php fait une boucle, donc tous tes inputs hidden ont le même id. Il faut que tu modifies ça côté php. Idem pour la div d'id "com_frm".
Pas d'aide concernant le code par MP, le forum est là pour ça :)
Hmmm. À quoi ressemble le HTML généré ? Si l'id est toujours com_frm-$valeur[0] ça ne change rien à l'affaire…
Si tu peux nous montrer, non plus la page entière car ça ferait beaucoup, mais le résultat de deux tours de boucle par exemple, ça aiderait à comprendre.
Pas d'aide concernant le code par MP, le forum est là pour ça :)
Si ton JavaScript contient exactement maVariable-$valeur[0] dans ce que tu peux y voir depuis le navigateur, cela ne fonctionnera pas comme tu t'y attends, parce que JavaScript (effectué côté client avec le HTML généré) n'a pas connaissance des données de PHP (effectué côté serveur, donc génère le HTML).
Plutôt qu'une boucle pour assigner des écouteurs d'événement à des éléments très précis, tu peux boucler sur les éléments ayant une classe CSS commune, et dans l'événement, deux possibilités : soit "remonter" dans l'arbre depuis l'élément cliqué pour trouver l'élément .
<!-- HTML — j'ai enlevé les `echo "` en début de ligne et `";` en fin -->
<input type='radio' name='type[$valeur[0]][val]' value='OK' required id='ok$valeur[0]' class="ok" />
<label for='ok$valeur[0]'>OK</label>
<!-- … -->
<div id='com_frm$valeur[0]' class="com_frm">
<label for='type[$valeur[0]][com]'>Commentaire:</label><br />
<textarea name='type[$valeur[0]][com]' required id='type[$valeur[0]][com]' class='com' rows='5' cols='30'></textarea>
</div>
<!-- JavaScript -->
document.querySelectorAll('[type="radio"]').forEach(e => {
const tableRow = e.target.closest('tr');
if (e.value === 'OK') {
tableRow.querySelector('.com_frm').style.display = 'none';
tableRow.querySelector('.com_frm textarea').required = false;
}
else {
tableRow.querySelector('.com_frm').style.display = 'block';
tableRow.querySelector('.com_frm textarea').required = true;
}
});
J'ai remplacé setAttribute() parce que je me souviens avoir eu joué avec entre autres pour required, et certains navigateurs me permettaient de faire deux opérations seulement, puis plus rien (genre enlever puis remettre, plus moyen d'enlever à nouveau, ou mettre et enlever, et pareil, plus moyen de remettre). Ce qu'il faut savoir, c'est que les attributs HTML sont en majeure partie là pour permettre de déterminer les valeurs initiales des propriétés correspondantes, et celles-ci sont correctement modifiables.
N'hésite pas à poser des questions sur ce que j'ai proposé si nécessaire.
Alors mon JavaScript ne remplace pas l'entier du tien, mais les lignes 8 à 23 selon le message ci-dessus au moment de ce message
Par contre, je ne sais pas pourquoi j'avais imaginé "un vrai tableau", et du coup, effectivement, cela ne fonctionnera pas
Est-ce que l'idée d'un <div class="itemRow">autour de tous les <div id="frm"> "pour un tour de boucle"/une itération du foreach serait envisageable ? Avec cela, on pourrait effectuer quelques adaptations.
Puisqu'on en parle, dans ce que tu as fourni, l'ID frm est encore répliqué pour chaque <div> autour des "groupes" label-champ. Tu ne sembles pas l'utiliser avec ce que tu montres, mais si cela venait à se faire, il pourrait y avoir à nouveau des surprises.
l'ID frm me sert uniquement pour le fichier css et la mise en forme de la page.
Pour ma part, je suis ouvert à chaque proposition que me pourrait me permettre de me défaire de ce soucis.. je suis tout à l'écoute de toutes suggestion.
- Edité par ArnaudMonteil1 16 avril 2025 à 16:22:45
Alors si cet ID répété ne semble pas poser de problème pour le CSS, je conseillerais de vérifier que c'est bien le cas avec tous les navigateurs.
Pour ce qui est du script que j'ai proposé, il suffirait donc d'ajouter ce que j'ai mentionné comme <div class="itemRow"> pour englober tout ce qu'il y a dans une boucle, et remplacer dans ma précédente proposition JavaScript .closest('tr') par .closest('div.itemRow'). Attention au fait que j'ai aussi précisé que ce code remplaçait une partie seulement.
Aussi, s'il devait y avoir d'autres cases à cocher dans la page, on devra ajouter une petite adaptation.
N'oublie pas de poser des questions sur ce que tu ne comprendrais pas.
Le textarea pour les commentaire est toujours visible à l'arrivé sur la page, et que je clique sur n'importe quel bouton radio, le commentaire est toujours visible et obligatoire...
Du coup, ais je mis <div class="itemRow"> au bon endroit ?
Aurais-tu une autre idée ?
Merci par avance
- Edité par ArnaudMonteil1 il y a environ 23 heures
Le textarea pour les commentaire est toujours visible à l'arrivé sur la page
Pourquoi ne pas le masquer avec du PHP/dans le HTML ? Au moins pour l'état initial.
Est-ce que, dans ce que tu vois avec ton navigateur et notamment du fait du console.log, tu as maVariable-GABARIT ou exactement maVariable-$valeur[0] ? Dans ce dernier cas, c'est logique que le textarea ne soit pas masqué, parce que :
querySelector('com_frm$valeur[0]') n'existe pas, du fait que $valeur[0] n'est pas une variable PHP dans le code ;
malgré le point 1 : un sélecteur commençant par une lettre ASCII correspond à une balise HTML. Or, tu cherches à sélectionner un élément avec un ID, qui demande un # devant ;
outre d'autres soucis liés au fonctionnement de PHP, cela ne masquera qu'une seule zone de texte, pas toutes.
Peut-être que l'entier du code nous serait utile ; en l'état, je vais juste supposer que tu ne nous montres que quelques parties d'un même fichier PHP, et que du coup dans le code JavaScript montré (oui, oui), il faudrait encadrer chaque $valeur[0] (et assimilés) par <?= … ?>.
Mais comme dit en 3, ce n'est pas forcément la solution : une classe sur chacune de ces zones de texte, mais uniquement sur celles qui permettent le commentaire (vu qu'il y en a pour le nom aussi), serait clairement plus pratique. Et du coup, document.querySelector('.laClasse').forEach(e => { e.style.display = 'none'; }) pourrait faire l'affaire.
ArnaudMonteil1 a écrit:
Du coup, ais je mis <div class="itemRow"> au bon endroit ?
Oui, mais petite coquille dans la fermeture : il y a un </div< au lieu d'un </div>. Cela risque de poser problème pour les lignes après la première.
Et si j'avais mis un véritable écouteur d'événement, on aurait mieux
Il faut "un niveau supplémentaire" après mon forEach — attention, il a aussi été adapté.
Pas d'aide concernant le code par MP, le forum est là pour ça :)
Pas d'aide concernant le code par MP, le forum est là pour ça :)