Ku, być może smutkowi niekórych, dziś będziemy się zajmować checkbox'ami znanymi z formularzy HTML. Niestety nie żywymi ptaszkami. Cel do osiągnięcia jest następujący: dla grupy checkbox'ów mamy zablokować możliwość ich kliknięcia powyżej wybranej liczby. Np. mając 10 ptaszków chcemy umożliwić zaznaczenie tylko trzech.
Niech kod HTML będzie taki:
<body>
<form>
<fieldset data-max-checked="2">
<input type="checkbox"/>
<input type="checkbox"/>
<input type="checkbox"/>
</fieldset>
<fieldset data-max-checked="5">
<input type="checkbox"/>
<input type="checkbox"/>
<input type="checkbox"/>
<input type="checkbox"/>
<input type="checkbox"/>
<input type="checkbox"/>
<input type="checkbox"/>
<input type="checkbox"/>
</fieldset>
</form>
</body>
a JavaScript taki:
document.querySelectorAll('fieldset[data-max-checked]').forEach(function(fieldset){
var maxChecked = parseInt(fieldset.getAttribute('data-max-checked'));
fieldset.querySelectorAll('input[type="checkbox"]').forEach(function(checkbox){
checkbox.addEventListener('click',function(){
var checked = fieldset.querySelectorAll('input[type="checkbox"]:checked').length;
if(checked > maxChecked){
this.checked = false;
}
fieldset.querySelectorAll('input[type="checkbox"]:not(:checked)').forEach(function(el){
el.disabled = checked == maxChecked;
});
});
});
});
Jak to działa?
Korzystamy z elementu FIELDSET, który służy właśnie do grupowania elementów formularza. Sam co prawda ich w magiczny sposób nie grupuje, robimy to sami. Grupowane elementy zazwyczaj są powiązane ze sobą w ramach kontekstu. Do FIELDSET dodajemy atrybut max-data-checked, który będzie przechowywał informację o maksymalnej możliwej do kliknięcia checkboxów, w ramach tegoż.
Iterujemy więc po każdym FIELDSET zawierającym ten atrybut, pobieramy wartość max-data-checked i zapamiętujemy ją. W ramach każdego FIELDSET przechadzamy się po jego checkbox'ach. Każdy checkbox dostaje możliwość nasłuchiwania na zdarzenie click (addEventListener).
W listenerze sprawdzamy ilość klikniętych checkboxów - będzie to ilość uwzględniająca klikany aktualnie ptaszek. Jeśli przekroczyliśmy maksymalną ilość, to odznaczamy ten właśnie kliknięty.
Następnie w pętli dla każdego niezaznaczonego checkbox'a ustawiamy atrybut disabled na podstawie warunku checked == maxChecked, czyli disabled przyjmuje wartość true, jeśli osiągnęliśmy maksymalną ilość zaznaczonych.
Pamiętaj o tym, aby kontrolować ilość przesyłanych checkboxów po stronie serwera. A jako że ptaszki mogą być czasem nieużywane, nic nie stoi na przeszkodzie, abyś zablokował wybrane również w momencie generowania HTML.
Przydatne linki:
Tag FIELDSET
Scopana metoda, czyli dlaczego selektor > oraz + nie zawsze działa.
"Hello dollar", czyli po co mi jQuery?