web-dev-qa-db-fra.com

Comment compter toutes les cases cochées

Voici mon code:

Il compte en fait les cases cochées et les écrit dans <span class="counter"></span>. Ce code fonctionne sur Firefox, mais pas sur Chrome.

Sur Chrome, le .select_all coche toutes les cases que je veux, mais ne met pas à jour le compteur. En fait, le compteur est mis à jour lorsque je décoche le .select_all, ce qui est bizarre.

FAIT IMPORTANT: Je ne veux pas compter les cases à cocher .Select_all dans mon .counter

jQuery(document).ready(function($){

$(function() {
    $('#general i .counter').text(' ');

    var generallen = $("#general-content input[name='wpmm[]']:checked").length;
    if(generallen>0){$("#general i .counter").text('('+generallen+')');}else{$("#general i .counter").text(' ');}
})

$("#general-content input:checkbox").on("change", function() {
    var len = $("#general-content input[name='wpmm[]']:checked").length;
    if(len>0){$("#general i .counter").text('('+len+')');}else{$("#general i .counter").text(' ');}
});


$(function() {
    $('.select_all').change(function() {
        var checkthis = $(this);
        var checkboxes = $(this).parent().next('ul').find("input[name='wpmm[]']");

        if(checkthis.is(':checked')) {
            checkboxes.attr('checked', true);
        } else {
            checkboxes.attr('checked', false);
        }
    });
});

});

EDIT: Voici un exemple de document du code: http://jsfiddle.net/8PVDy/1/

22
hawkidoki

Vous pouvez utiliser une fonction pour mettre à jour le compteur:

function updateCounter() {
    var len = $("#general-content input[name='wpmm[]']:checked").length;
    if(len>0){$("#general i .counter").text('('+len+')');}else{$("#general i .counter").text(' ');}
}

et appelez cette fonction lorsque l'état d'une case à cocher est modifié (y compris les cases à cocher selectAll)

Voici un jsFiddle mis à jour: http://jsfiddle.net/8PVDy/4/

55
gabitzish
$('input[type="checkbox"]:checked').length
38
nbrooks

vous pouvez le faire de cette façon

$(document).ready(function(){
$('input[type="checkbox"]').click(function(){
    alert($('.test:checked').length);

});
});

HTML que j'ai utilisé

<input type="checkbox" name="test" class="test" value=""/>  
<input type="checkbox" name="test" class="test" value=""/>  
<input type="checkbox" name="test" class="test" value=""/>  
<input type="checkbox" name="checkAll" class="checkAll" value=""/>

J'espère que cela t'aides

10
Roger

Pour mettre à jour l'état vérifié, utilisez la fonction jQuery.prop ()

Code:

$(function(){
    $('#general i .counter').text(' ');

    var fnUpdateCount = function() {
        var generallen = $("#general-content input[name='wpmm[]']:checked").length;
        console.log(generallen,$("#general i .counter") )
        if (generallen > 0) {
            $("#general i .counter").text('(' + generallen + ')');
        } else {
            $("#general i .counter").text(' ');
        }
    };

    $("#general-content input:checkbox").on("change", function() {
                fnUpdateCount();
            });

    $('.select_all').change(function() {
                var checkthis = $(this);
                var checkboxes = $("#general-content input:checkbox");

                if (checkthis.is(':checked')) {
                    checkboxes.prop('checked', true);
                } else {
                    checkboxes.prop('checked', false);
                }
                fnUpdateCount();
            });
});

Démo: Fiddle

2
Arun P Johny

Modification du gestionnaire de sélection pour déclencher la fonction onchange pour les cases à cocher de sous-catégorie comme celle-ci

$(function() {
    $('.select_all').change(function() {
        var checkthis = $(this);
        var checkboxes = $(this).parent().next('ul').find("input[name='wpmm[]']");

        if(checkthis.is(':checked')) {
            checkboxes.attr('checked', true);
        } else {
            checkboxes.attr('checked', false);
        }
        // make sure to trigger the onchange behaviour for the checkboxes
        $("#general-content input:checkbox").change();
    });
})

Je semble me souvenir qu'il existe une meilleure façon de les déclencher, mais je ne les trouve pas

0
Ledhund

Ce que j'ai trouvé manquant dans toutes les réponses ci-dessus est une explication sur la façon d'écouter les clics de manière efficace car la question est étroitement associée à l'événement onChange. Une autre chose est que la question ne précise pas si le code doit être uniquement dans Jquery. Je pense que l'ajout de la solution Vanilla JS devrait être une bonne idée.

Voici la liste HTML des cases à cocher que je vais compter. J'ai abordé la question de manière un peu plus générique, pour faciliter son application dans différentes conditions. Je prévois de compter les cases à cocher globalement et par section.

<div class="wrapper">
  <section class="list list-1">
    <label for="id-11"><input type="checkbox" id="id-11"></label>
    <label for="id-12"><input type="checkbox" id="id-12"></label>
    <label for="id-13"><input type="checkbox" id="id-13"></label>
    <label for="id-14"><input type="checkbox" id="id-14"></label>
    <label for="id-15"><input type="checkbox" id="id-15"></label>
    <label for="id-16"><input type="checkbox" id="id-16"></label>
    <label for="id-17"><input type="checkbox" id="id-17"></label>
    <label for="id-18"><input type="checkbox" id="id-18"></label>
    <label for="id-19"><input type="checkbox" id="id-19"></label>
    <label for="id-110"><input type="checkbox" id="id-110"></label>
    <span class="list-score">Section 1: <span class="number">0</span></span>
  </section>

  <section class="list list-2">
    <label for="id-21"><input type="checkbox" id="id-21"></label>
    <label for="id-22"><input type="checkbox" id="id-22"></label>
    <label for="id-23"><input type="checkbox" id="id-23"></label>
    <label for="id-24"><input type="checkbox" id="id-24"></label>
    <label for="id-25"><input type="checkbox" id="id-25"></label>
    <label for="id-26"><input type="checkbox" id="id-26"></label>
    <label for="id-27"><input type="checkbox" id="id-27"></label>
    <label for="id-28"><input type="checkbox" id="id-28"></label>
    <label for="id-29"><input type="checkbox" id="id-29"></label>
    <label for="id-210"><input type="checkbox" id="id-210"></label>
    <span class="list-score">Section 2: <span class="number">0</span></span>
  </section>

  <section class="list list-3">
    <label for="id-31"><input type="checkbox" id="id-31"></label>
    <label for="id-32"><input type="checkbox" id="id-32"></label>
    <label for="id-33"><input type="checkbox" id="id-33"></label>
    <label for="id-34"><input type="checkbox" id="id-34"></label>
    <label for="id-35"><input type="checkbox" id="id-35"></label>
    <label for="id-36"><input type="checkbox" id="id-36"></label>
    <label for="id-37"><input type="checkbox" id="id-37"></label>
    <label for="id-38"><input type="checkbox" id="id-38"></label>
    <label for="id-39"><input type="checkbox" id="id-39"></label>
    <label for="id-310"><input type="checkbox" id="id-310"></label>
    <span class="list-score">Section 3: <span class="number">0</span></span>
  </section>

  <span class="total-score">Total: <span class="number">0</span></span>
</div>


et voici le balisage JS, qui écoute tous les clics à l'intérieur du .wrapper div et compte les entrées sélectionnées dans le contexte de .wrapper et chaque .list section.

const total = document.querySelector('.total-score .number')

document.querySelector('.wrapper').addEventListener('change', function(event) { // First we apply the ONLY one listener to do the listening for us - we don't need listener on each checkbox
  const numberAll = this.querySelectorAll('input[type="checkbox"]:checked').length // We count all selected inputs in side the main wrapper. 
  total.innerHTML = numberAll // We update the total counter

  const list = event.target.closest('.list') // We look and cache the closest section, wrapping the clicked checkbox element
  const numberList = list.querySelectorAll('input[type="checkbox"]:checked').length // Once found, we start to count the number of selected checboxes under the section
  list.querySelector('.list-score .number').innerHTML = numberList // We update the sectiona relevant counter
})

Voici l'exemple en direct dans le violon JS: https://jsfiddle.net/mkbctrlll/yak4oqj9/159/

Dans Vanilla JS, vous devez savoir que l'application de l'écouteur change à chaque case à cocher est une solution beaucoup plus lente. Au lieu de cela, vous devez utiliser la soi-disant délégation d'événements et appliquer l'écouteur à l'élément d'habillage ou même à l'ensemble du document.

Ici, vous pouvez le vérifier par vous-même, à quel point l'écoute est-elle plus lente à changer pour chaque entrée de votre liste:

https://jsperf.com/change-listener-on-each-vs-event-delegation/1

Le code de l'option plus lente (juste pour comparer):

document.querySelector('.wrapper').addEventListener('change', function() {
    const numberAll = this.querySelectorAll('input[type="checkbox"]:checked').length
    total.innerHTML = numberAll
  })

document.querySelectorAll('.list').forEach((list) => {
  list.addEventListener('change', function() {
    const numberAll = this.querySelectorAll('input[type="checkbox"]:checked').length
    this.querySelector('.list-score .number').innerHTML = numberAll
  })
})

et ma solution dans jQuery:

$('.wrapper').change(function() {
  const numberAll = $(this).find('input[type="checkbox"]:checked').length
  total.innerHTML = numberAll

  const $list = $(event.target).closest('.list')
  const numberList = $list.find('input[type="checkbox"]:checked').length
  $($list.find('.list-score .number')).html(numberList)
})

P.S. J'ai également essayé d'ajouter la solution jQuery à la référence, mais ses performances semblaient fausses, j'ai donc décidé de m'en passer.

0
mkbctrl

Essaye ça.

$('.select_all').change(function() {
var num = $(this).find("input[name='wpmm[]']:checked").length;
$("#general .counter").html(num);
});
0
KBN