11521 sujets

JavaScript, DOM et API Web HTML5

Modérateur
Bonjour,

Je modifie le style des cases à cocher en les masquant et en stylant le label.

HTML (simplifié) :
<label>
  <input type="checkbox">Premier choix
</label>
<label>
  <input type="checkbox">Premier choix
</label>
<label>
  <input type="checkbox">Premier choix
</label>


CSS:

label.checkbox, label.checkbox-checked {
    display: inline-block;
    vertical-align: middle;
    cursor: pointer;
    padding-left: 34px;
    margin: 0.5rem 1.5rem 0.5rem 0;
    line-height: 26px;
}

label.checkbox {
    background: url(images/checkbox.png) no-repeat left center;    
}

label.checkbox-checked {
    background: url(images/checkbox-checked.png) no-repeat left center;    
}


jQuery :
/* Adding classes to labels for styling */
jQuery ("label").has("input[type=checkbox]").addClass("checkbox");
jQuery ("label").has("input[type=checkbox]:checked").addClass("checkbox-checked");

/* Behaviour when clicking on checkbox labels */
jQuery("label.checkbox").on("click", function() {
  jQuery(this).addClass("checkbox-checked");
  jQuery(this).removeClass("checkbox");
})
jQuery("label.checkbox-checked").on("click", function() {
  jQuery(this).addClass("checkbox");
  jQuery(this).removeClass("checkbox-checked");
})


J'arrive à cocher (changer le style) lors du clic sur un label non sélectionné (class="checkbox" devient class="checkbox-checked"), mais lorsque je clique une deuxième fois sur le label, la class d'est pas modifiée (elle devrait passer à "checkbox" à nouveau).

Une idée ?
Merci d'avance.
Hello,

Il faut utiliser la délégation pour attacher des événements sur un élément dynamique.

Par exemple :
<form>
    <label>
        <input type="checkbox">Premier choix</input>
    </label>
    <label>
        <input type="checkbox" checked>Premier choix</input>
    </label>
    <label>
        <input type="checkbox">Premier choixlabel</input>
    </label>
</form>

/* Adding classes to labels for styling */
jQuery("label").has("input[type=checkbox]").addClass("checkbox");
jQuery("label").has("input[type=checkbox]:checked").addClass("checkbox-checked");

/* Behaviour when clicking on checkbox labels */
jQuery("form").on("click", "label.checkbox", function () {
    jQuery(this).addClass("checkbox-checked").removeClass("checkbox");
});
jQuery("form").on("click", "label.checkbox-checked", function () {
    jQuery(this).addClass("checkbox").removeClass("checkbox-checked");
});
Modérateur
Merci pour la proposition, mais ça ne fonctionne toujours pas.
J'ai repris ton code pour le jQuery :

/* Behaviour when clicking on checkbox labels */
    jQuery("form").on("click", "label.checkbox", function() {
       jQuery(this).addClass("checkbox-checked").removeClass("checkbox");
    })
    jQuery("form").on("click", "label.checkbox-checked", function() {
        jQuery(this).addClass("checkbox").removeClass("checkbox-checked");
    })


Pas d'erreur dans la console. C'est pas une affaire d'éléments pointé ? Je veux dire par là que jQuery(this) est un objet, et c'est ce qui perturbe le bon fonctionnement du script (je ne sais pas trop comment expliquer ça...).

J'ai fait un peu pareil pour des boutons radios (sans délégation), mais dans ce cas, ça fonctionne (il faut dire que ce n'est pas le même comportement...) :

/* Adding classes to labels for styling */
    jQuery ("label").has("input[type=radio]").addClass("radio");
    jQuery ("label").has("input[type=radio]:checked").addClass("radio-checked");
    /* Behaviour when clicking on radio labels */
    jQuery("label.radio").on("click", function() {
        jQuery(this).removeClass("radio");
        jQuery(this).addClass("radio-checked");
        /* uncheck the other radio buttons */
        jQuery(this).siblings().removeClass("radio-checked");
        jQuery(this).siblings().addClass("radio");
    })

Modifié par jojaba (11 Sep 2015 - 10:36)
Modérateur
Trouvé !

J'ai vérifié l'état de la checkbox au lieu de celui de la classe du label et je traite les deux cas dans le même évènement.
Ça donne ça :

/* Behaviour when clicking on checkbox labels */
    jQuery("form").on("click", "label.checkbox, label.checkbox-checked", function() {
        if(jQuery(this).find("input[type=checkbox]:checked").length > 0) {
            jQuery(this).addClass("checkbox").removeClass("checkbox-checked");
        } else {
            jQuery(this).addClass("checkbox-checked").removeClass("checkbox");          
        }
    });


Je n'arrive pas à comprendre pourquoi ça ne fonctionnait pas avant... Tu as une idée ?

Smiley edit
C'est bizarre, après le chargement de la page, il faut que je m'y prennes à plusieurs reprises pour cocher/décocher. Mais après un certain temps, ça fonctionne bien. Peut-être dû au chargement de l'image de fond...
[/edit]
Modifié par jojaba (11 Sep 2015 - 11:12)
Modérateur
Super, merci beaucoup !!!
Pour ceux qui reviendront ici, voici la solution qui fonctionne (Je vous donne tout le jQuery pour boutons radios et cases à cocher) :

/* Adding classes to labels for styling */
    jQuery ("label").has("input[type=radio]").addClass("radio");
    jQuery ("label").has("input[type=checkbox]").addClass("checkbox");
    jQuery ("label").has("input[type=radio]:checked").addClass("radio-checked");
    jQuery ("label").has("input[type=checkbox]:checked").addClass("checkbox-checked");
    /* Behaviour when clicking on radio labels */
    jQuery("label.radio").on("click", function() {
        jQuery(this).addClass("radio-checked").removeClass("radio");
        /* uncheck the other radio buttons */
        jQuery(this).siblings().addClass("radio").removeClass("radio-checked");
    });
    /* Behaviour when clicking on checkbox labels */
    jQuery("label input[type=checkbox]").on("change", function() {
        if(!jQuery(this).prop("checked")) {
            jQuery(this).parent("label").addClass("checkbox").removeClass("checkbox-checked");
        } else {
            jQuery(this).parent("label").addClass("checkbox-checked").removeClass("checkbox");
        }
    });


Pour le html et la css, voyez dans le premier message de ce sujet.
Merci Oken Smiley smile