[RESOLU] Decocher bouton radio

Eléphant du PHP | 194 Messages

10 avr. 2023, 08:56

Bonjour,

Je refais un petit site perso ou je donne le choix de choisir un avatar, mon problème est que je voudrai pouvoir désélectionner en re-cliquant sur l'avatar voici mon code :

Code : Tout sélectionner

<!-- Début avatars --> <!-- Bouton déclencheur pour le collapsible avec l'icône SVG --> <button type="button" class="form-control mb-3" data-bs-toggle="collapse" data-bs-target="#monCollapse" aria-expanded="false"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-person-bounding-box" viewBox="0 0 16 16"> <path d="M1.5 1a.5.5 0 0 0-.5.5v3a.5.5 0 0 1-1 0v-3A1.5 1.5 0 0 1 1.5 0h3a.5.5 0 0 1 0 1h-3zM11 .5a.5.5 0 0 1 .5-.5h3A1.5 1.5 0 0 1 16 1.5v3a.5.5 0 0 1-1 0v-3a.5.5 0 0 0-.5-.5h-3a.5.5 0 0 1-.5-.5zM.5 11a.5.5 0 0 1 .5.5v3a.5.5 0 0 0 .5.5h3a.5.5 0 0 1 0 1h-3A1.5 1.5 0 0 1 0 14.5v-3a.5.5 0 0 1 .5-.5zm15 0a.5.5 0 0 1 .5.5v3a1.5 1.5 0 0 1-1.5 1.5h-3a.5.5 0 0 1 0-1h3a.5.5 0 0 0 .5-.5v-3a.5.5 0 0 1 .5-.5z"/> <path d="M3 14s-1 0-1-1 1-4 6-4 6 3 6 4-1 1-1 1H3zm8-9a3 3 0 1 1-6 0 3 3 0 0 1 6 0z"/> </svg> Choix d'avatars (option) </button> <!-- Élément collapsible --> <div id="monCollapse" class="collapse"> <div class="card card-body"> <label class="avatar-label"> <?php // Vérifier si des avatars ont été récupérés depuis la table if (!empty($results)) { $counter = 0; // Compteur pour les images foreach($results as $row) { // Assurez-vous que $row est un objet stdClass if (is_object($row)) { // Accéder aux propriétés de l'objet $avatarUrl = $row->url; $avatarId = $row->id; // Vérifier le compteur pour ouvrir/fermer les divs de ligne if ($counter % 3 == 0) { echo '<div class="row">'; } ?> <div class="col-4"> <label class="avatar-label"> <input type="radio" class="avatar-input" name="avatar" value="<?php echo $avatarId; ?>"> <img src="<?php echo $avatarUrl; ?>" alt="Avatar <?php echo $avatarId; ?>"> </label> </div> <?php // Vérifier le compteur pour ouvrir/fermer les divs de ligne if (($counter + 1) % 3 == 0) { echo '</div>'; } $counter++; } } // Vérifier si la dernière ligne est incomplète et fermer la div de ligne correspondante if ($counter % 3 != 0) { echo '</div>'; } } else { echo "Aucun avatar trouvé."; } ?> </div> <!-- Fin avatars -->
et voici mon css :

Code : Tout sélectionner

/* Debut CSS Avatar */ .avatars-container { display: flex; flex-wrap: wrap; justify-content: center; background-color: transparent; /* Ajouter cette ligne pour rendre le fond transparent */ } .avatar-label { display: block; position: relative; cursor: pointer; } .avatar-label input[type="radio"] { position: absolute; top: 0; left: 0; opacity: 0; cursor: pointer; } .avatar-label img { width: 100%; height: auto; border: 2px solid transparent; transition: border-color 0.3s ease; border-radius: 50%; background-color: transparent; } .avatar-label img:hover { border-color: #333; } .avatar-label input[type="radio"]:checked + img { border-color: #00ff00; outline: 2px solid #00ff00; } /* Fin CSS Avatar */
En regardant plusieurs tuto je ne parviens pas a faire le JS qui faut :

Code : Tout sélectionner

// Récupérer tous les éléments d'avatar avec la classe .avatar-label var avatarLabels = document.querySelectorAll('.avatar-label'); // Ajouter un écouteur d'événement clic sur chaque élément d'avatar avatarLabels.forEach(function(label) { label.addEventListener('click', function() { // Récupérer l'élément d'input radio associé à l'avatar var radioInput = this.querySelector('.avatar-input'); // Vérifier si l'élément d'input radio est déjà coché if (radioInput.checked) { // Désélectionner l'avatar en décochant l'élément d'input radio radioInput.checked = false; } else { // Sinon, cocher l'élément d'input radio et décocher les autres avatarLabels.forEach(function(otherLabel) { otherLabel.querySelector('.avatar-input').checked = false; }); radioInput.checked = true; } }); });
Merci par avance pour votre aide.
@+Filou

Avatar du membre
Mammouth du PHP | 1564 Messages

10 avr. 2023, 13:45

Dans ton code JS :

"// Sinon, cocher l'élément d'input radio et décocher les autres"

=> inutile, un radio désélectionne automatiquement tous les autres quand on clic sur un radio qui à le même name.

Test sans la partie else du JS.

Code : Tout sélectionner

this.querySelector('.avatar-input');
???

"this" suffira car tu écoute actuellement sur un élément, pas besoin de pointer vers quelque chose, tu est déjà sur quelque chose :)

ceci devrait faire l'affaire :

Code : Tout sélectionner

... label.addEventListener('click', function(elm) { var radioInput = elm; ...
Ou directement :

Code : Tout sélectionner

... label.addEventListener('click', function(radioInput) { ...
Ou en version fléchée :

Code : Tout sélectionner

... label.addEventListener('click', (radioInput) => { ...
Par contre fais un forEach sur les input, pas les label.

ynx
Mammouth du PHP | 586 Messages

10 avr. 2023, 18:13

Bonjour,

Par défaut les input radio ne peuvent pas être décochés. Sans javascript avec le comportement par défaut, une solution simple serait d'ajouter un radio "Pas d'avatar" ou un avatar par défaut que l'utilisateur devra cocher.

Si tu veux vraiment que l'utilisateur puisse décocher l'avatar en cliquant dessus, il semble plus simple d'utiliser des checkbox avec du javascript à la place des radio. Puisque les checkbox ne fonctionnent pas par groupe, il faut un peu de javascript pour avoir un seul avatar sélectionné.
Un exemple avec des checkbox : https://jsfiddle.net/qc739btx/

Eléphant du PHP | 194 Messages

10 avr. 2023, 20:01

Merci,
C'est juste ce que je veux.

@+ Filou