11543 sujets

JavaScript, DOM et API Web HTML5

Pages :
Bonjour,

Je suis assez nul en javascript, merci de votre indulgence.

Dans ce ,codepen sur écran de moins de 1200 px chaque input type="radio" est transformé en bouton de soumission.

Mon problème est que le clic transmette non seulement la valeur de l'input (ce qu'il fait avec mon code JS sommaire) mais aussi celle du bouton de soumission : "Ajouter au panier" (afin que le script PHP comprenne ce qui se passe).

Cela si-possible sans alourdir le code html.

Merci d'avance.
Modérateur
Salut,

Où sont les label pour tes boutons radio ?
Pourquoi un matchMedia max width1200px ?
Événement click sur un bouton radio ? Smiley hum Les boutons radio, comme les checkbox ou les select n'utilisent pas cet événement. Ces jours-ci, j'ai vu passer un sujet à ce propos sur le forum.
Bonjour Niuxe,

Le codepen est expérimental, il ne prétend pas respecter les bonnes règles, par exemple le label pour l'input.

Niuxe a écrit :
Pourquoi un matchMedia max width1200px ?


Responsive, la case radio doit se comporter comme un bouton submit sur les petits écrans, j'ai choisi 1200px pour le codepen, peu importe.

Click fonctionne, je peux essayer OnChange.

Tu ne réponds pas à ma question :

Mon problème est que le clic (ou OnChange) transmette non seulement la valeur de l'input (ce qu'il fait avec mon code JS sommaire) mais aussi celle du bouton de soumission : "Ajouter au panier" (afin que le script PHP comprenne ce qui se passe).

As-tu une idée ?

Merci d'avance.
Modérateur
c'est plutôt simple :

<?php 
if(isset($_POST)){
    print_r($_POST);
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<form action="<?= $_SERVER['PHP_SELF']?>" method="post">
    <ul>
        <li><input type="radio" name="super" value="_1"></li>
        <li><input type="radio" name="super" value="_2"></li>
        <li><input type="radio" name="super" value="_3"></li>
    </ul>
    <input type="submit">
</form>
<script>
const bouton_radio = document.querySelectorAll ('input[type=radio]');

for (let i = 0; i < bouton_radio.length; i++){
    bouton_radio[i].addEventListener('change', e =>{
        document.querySelector('form').submit();
    });
}
</script>
</body>
</html>

Bonjour niuxe,

Merci de ton suivi.

Très bien mais il faut faire un changement et ce changement est la question.

<input type="submit" name="choix" value="Ajouter au panier">

Et au click sur un bouton radio il faut que cette variable $_POST['choix'] soit transmise à PHP.
Modifié par boteha_2 (12 Apr 2025 - 17:46)
Modérateur
Bonjour,

heu, je sais pas ce que tu veut faire avec tes boutons radios, mais si leur comportement devient celui d'un submit, cela va être très surprenant pour tes visiteurs et malvenu.
Personnellement, si un site me fait ça, je perds aussitôt toute confiance et vais voir ailleurs car si je coche une option cela n'a rien à voir avec ma volonté de soumettre un formulaire , et si je voulais me ravisé ou que j'avais cliqué au mauvais endroit avec mes gros doigts ? Smiley cligne

Je pense que c'est une mauvaise idée ou bien je n'ai vraiment pas compris ce que tu voulais faire.
cdt
Bonjour gcyrillus,

Oui, je sais, tu as 100 % raison s'il s'agit d'un formulaire.

Là il s'agit d'une expérience sur une page produit avec plusieurs versions du produit.
Je suis loin d'être sûr que ce sera concluant mais le codepen te montre l'effet responsive.

Dans cette discussion j'essaye d'expliquer...

Bon, c'est une expérience, elle m'a permis de découvrir l'attribut USE pour les SVG et a donné à Raphaël l'idée d'un tuto sur le style des images SVG.

La brique manquante est la transmission d'une variable de formulaire par JS, j'ai passé un certain temps à chercher en vain la réponse...
Hello gcyrillus,

Merci de ton suivi.

Ton code est trop compliqué pour moi....

Voilà mon code basique :

const bouton_radio = document.querySelectorAll ('table.compcab input[type=radio]');

for (let i = 0; i < bouton_radio.length; i++)
{	
bouton_radio[i].addEventListener('change', function ()
{
this.form.submit();
}
);
}


J'imagine qu'il faut ajouter quelque part :

var formData = new FormData();
formData.append("choix", "Ajouter au panier");


Mais ensuite envoyer cela en POST je sèche, même après avoir parcouru la documentation sur FormData...
Modérateur
Bonjour,

On va essayer de repartir sur un exemple plus simple.

Dans un premier temps il te faut construire un formulaire sans omettre l'attribut name des éléments.

Dans un second temps, tu pose en un écouteur sur l’événement "submit" du formulaire.

Au moment de soumettre le formulaire,
1. tu crée ton formData , il sera remplie avec les clés/valeur des attributs name et value du formulaire. (tu peut compléter ces clés/valeur via append si tu as d'autres choses a faire et a transmettre avec le formulaire).
2. tu envoi le formulaire avec XMLHttpRequest.

revoici un exemple plus imple sur lequel tu peut commencer :

<form id="form" action=''>
  <input type="text" value="hello" id="hiWorld" name="texte">
  <input type="radio" id="a1" name="rr" value="a">
  <input type="radio" id="a2" name="rr" value="b">
  <input type="radio" id="a3" name="rr" value="c">
  <input type="checkbox" id="ckb1" value="check1" name="boiteAboxe">
  <input type="submit">
</form>


et coté js :
window.onload = function () {
  // le formulaire
  const form = document.querySelector("#form");
  // ecoute du formulaire
  form.addEventListener("submit", function () {
    // on créer notre FormData
    let form_data = new FormData(form);
    // on reste sur la page
    event.preventDefault();
    // Curieux, ici on regarde les clés/valeurs du formulaire stockées dans le FormData
    for (let [name, value] of form_data) {
      console.log(name + " " + value);
    }
    // ici l'envoi
    let xhttp = new XMLHttpRequest();
    let upUrl = form.action;
    xhttp.open("POST", upUrl, true);
    // suite du traitement des réponses sur l'envoi (voir le codepen)
  });
};


codepen : https://codepen.io/gc-nomade/pen/EaxqdRE?editors=1011
Modifié par gcyrillus (13 Apr 2025 - 21:04)
Bonjour gcyrillus,

J'ai dû mal m'exprimer mais ton codepen ne répond pas au problème.

Mon problème est de ne pas avoir de bouton de soumission.
le click sur un bouton radio provoque la soumission du formulaire.
Et transmet en plus de la valeur du radio le couple nom=>valeur d'un bouton de soumission qui n'existe pas.

C'est tordu, expérimental, à mon avis cela ne débouchera pas mais le code ne doit pas être si compliqué...

<input type="radio" id="a1" name="rr" value="a">

Le click doit envoyer en POST rr=>a mais aussi choix=>Ajouter au panier comme si l'on avait cliqué sur un bouton <input type="submit" name="choix" value="Ajouter au manier"> qui n'est pas visible et même n'existe pas.

Est-ce plus clair ?
Modérateur
boteha_2 a écrit :
Bonjour gcyrillus,

J'ai dû mal m'exprimer mais ton codepen ne répond pas au problème.

Mon problème est de ne pas avoir de bouton de soumission.
le click sur un bouton radio provoque la soumission du formulaire.
Et transmet en plus de la valeur du radio le couple nom=&gt;valeur d'un bouton de soumission qui n'existe pas.

C'est tordu, expérimental, à mon avis cela ne débouchera pas mais le code ne doit pas être si compliqué...

&lt;input type="radio" id="a1" name="rr" value="a"&gt;

Le click doit envoyer en POST rr=&gt;a mais aussi choix=&gt;Ajouter au panier comme si l'on avait cliqué sur un bouton &lt;input type="submit" name="choix" value="Ajouter au manier"&gt; qui n'est pas visible et même n'existe pas.

Est-ce plus clair ?


Mon codepen n'est pas ta solution , il te montre seulement comment utiliser le FormData puis soumettre ton formulaire en ajax avec la methode POST.

Si tu veut un champ / valeur correspondant à <input type="submit" name="choix" value="Ajouter au manier"> soit envoyé, il faut donc qu'il soit dans le formulaire que tu soumet , par exemple sous la forme : <input type="hidden" name="choix" value="Ajouter au manier">, ou tu fait un formVar.append('choix','manier'); avant de soumettre le formulaire.

en gros, si tu veut transformer ton radio en un element qui soumet un formulaire au click, tu peut aussi créer sur l'evenement onclick:
1. un formulaire
2. un FormData
Puis,
3. remplir le FormData avec deux clés/valeur (choix=>manier et radioName=>value)
et enfin
4. soumettre le formulaire en javascript.
Modifié par gcyrillus (20 Apr 2025 - 14:44)
Bonjour gcyrillus,

Merci de ton suivi.

Si j'ai bien compris tu me dis que si je veux envoyer un couple nom-valeur en $_POST il faut forcément un INPUT dans le formulaire html.
Je ne peux pas créer ce couple avec javascript sans rien dans le formulaire html ?

J'y reviens sous peu.
Modifié par boteha_2 (24 Apr 2025 - 12:45)
Modérateur
boteha_2 a écrit :
Bonjour gcyrillus,

Merci de ton suivi.

Si j'ai bien compris tu me dis que si je veux envoyer un couple nom-valeur en $_POST il faut forcément un INPUT dans le formulaire html.
Je ne peux pas créer ce couple avec javascript sans rien dans le formulaire html ?

J'y reviens sous peu.

Non, je dis que si tu ne fais pas un FormData.append() , il faut alors qu'il y ait un input, dans le formulaire que tu envois, correspondant à la clé valeur que tu veut traité.
Comme tu te sert de l'évenement onClick sur le radio pour soumettre sa valeur et que ton input submit du coup n'est pas sollicité son name=>value n'est pas transmis.
Il te faut donc momentanément englober ton radio dans un form et lui adjoindre un input caché ou pas avec son name=>value et faire un submit depuis ce formulaire puis détruire le formulaire qui ne sert plus à rien .
Ou alors,
plus simplement créer un formulaire vide et son FormData auquel tu "append" tes 2 clés avec leur valeurs respectives que tu envois avec submit, puis tu détruit ce formulaire qui ne sert plus à rien. Il me semble que j'avais laissé les deux exemples en js dans le codepen

Dans les deux cas, le formulaire créer est à détruire une fois utilisé comme la page n'est pas rechargée vu que tu veut soumettre via js, il va polluer ton HTML.

L'exercice est amusant avec les radios, mais franchement pas le truc à faire à mon avis

Cdt
Bonjour gcyrillus,

gcyrillus a écrit :
L'exercice est amusant avec les radios, mais franchement pas le truc à faire à mon avis.


Tu as raison, c'est expérimental.
J'espère quand même venir à bout du code pendant le week-end.

Cela servira car j'ai une autre idée plus réaliste mais assez proche dont je parlerai plus tard.
Bonsoir,

Comme déjà un peu évoqué dans les réponses précédentes, vouloir soumettre le formulaire directement au clic sur une option est une très très mauvaise idée en termes d'accessibilité et d'utilisabilité. Même si tu permets de revenir en arrière pour corriger un mauvais choix, l'erreur est vite arrivée, et c'est toujours plus simple de prévenir les erreurs plutôt que de les corriger après coup.

Si c'est malgré tout ton choix, et effectivement ça peut être plus rapide pour arriver au bout d'un long questionnaire, dans ce cas, ne laisse aucun doute à l'utilisateur sur le fonctionnement du formulaire, utilise des véritables boutons plutôt que des radios. Au moins avec un vrai bouton, c'est clair, on sait instantanément que le clic va immédiatement déclencher une action.
Bonjour Quentin C,

100 % d'accord avec toi, comme avec gcyrillus.

En l'occurrence il y a une liste de produits dans un tableau, chaque produit occupe une ligne, chaque ligne commence par une case radio.
Cocher la case radio.
Aller chercher le bouton Ajouter au panier en dessous du tableau puis cliquer dessus pour ajouter le produit au panier.

Sur version téléphone, la case radio est remplacée par l'image d'un panier. La case radio devient invisible mais elle fait office de bouton submit.

C'est illustré dans ce codepen.

Une variante peut-être plus intelligente serait de conserver la case radio et de créer une animation.
Quand la case radio est cochée il apparaît (par exemple juste en-dessous de la case qui reste visible) un panier qui est un bouton de soumission.
Là c'est mieux, pas d'ajout au panier suite à click non voulu sur la case, et le bouton de soumission t'est servi là où tu en as besoin.
Le problème est d'avoir un javascript qui crée un bouton de soumission car cela chargerait trop le HTML que d'avoir pour chaque ligne un bouton de soumission en display NONE / INLINE.
Ou pourquoi pas une simple animation CSS qui va chercher le bouton de soumission sous le tableau pour le placer sous la case radio qui est cochée.

J'ai mis ces projets de côté, sans les abandonner.
Modifié par boteha_2 (01 May 2025 - 17:43)
a écrit :
Sur version téléphone, la case radio est remplacée par l'image d'un panier. La case radio devient invisible mais elle fait office de bouton submit.


Pour moi avec mon lecteur d'écran, c'est toujours un bouton radio qui m'est annoncé. Donc je m'attends à ce que le comportement soit celui d'un bouton radio.
Il faudrait tricher avec ARIA en stipulant role="button" pour me donner l'information correcte, mais du coup tu vois bien que ça mène dans une contradiction un peu bizarre.

En fait, ton truc est inutilement bien trop compliqué. Tu n'as absolument pas besoin de créer réellement un quelconque formulaire en HTML pour envoyer ta requête d'ajout au panier en JavaScript. Un simple <button> hors de tout formulaire fera l'affaire. Tu peux construire un FormData à partir de zéro et utiliser l'API fetch.
Pas besoin de tricher avec ARIA, pas besoin de faire de magouille CSS pour cacher le bouton radio et afficher complètement autre chose à la place, et pour info, un <button type="button"> ne doit pas obligatoirement se trouver au sein d'un formulaire.

Très souvent, l'accessibilité va de pair avec la simplicité.


Ah, et petite question au passage, je fais comment si je veux commander deux articles ? Pourquoi ne pas mettre simplement des chekbox pour tout le monde ? Dans ce cas même plus besoin de différencier l'interface entre PC et téléphone.
Modifié par QuentinC (01 May 2025 - 22:33)
QuentinC a écrit :
Ah, et petite question au passage, je fais comment si je veux commander deux articles ? Pourquoi ne pas mettre simplement des chekbox pour tout le monde ?


Tu ajoutes les produits les uns après les autres, tout simplement.
J'ai bien pensé à des checkbox mais cela peut provoquer des erreurs..
Le temps que tu gagnes avec des checkbox tu le perds à vérifier ton panier.

Pour le reste je suis d'accord avec toi.

Reste cette piste :
boteha-2 a écrit :
Ou pourquoi pas une simple animation CSS qui va chercher le bouton de soumission sous le tableau pour le placer sous la case radio qui est cochée.


Il est clair que cela s'adresse aux voyants mais aucun piège dans le code pour l'accessibilité.