jQuery / Alle Kontrollkästchen auswählen und abwählen
Verwenden Sie .prop("checked", true) zum Auswählen und .prop("checked", false) zum Abwählen einer Menge. Bei einer zentralen Checkbox muss deren Zustand auch nach Änderungen einzelner Einträge berechnet werden. indeterminate zeigt eine Teilauswahl an.
Zielmenge und Gesamtzustände festlegen
.prop() liest und ändert den aktuellen checked-Wert. Das HTML-Attribut über .attr() dient nicht zur Verwaltung aktueller Benutzerentscheidungen. Übergeben Sie boolesche Werte statt Zeichenfolgen.
Ziel sind aktivierte Checkboxen der Klasse item in #items. #all gehört nicht dazu. :enabled schließt deaktivierte Steuerelemente aus, auch bei geerbter Deaktivierung durch fieldset. Verbergen per CSS allein schließt nichts aus.
Die Zentrale ist nur angehakt, wenn mindestens ein Ziel existiert und alle ausgewählt sind. Teilweise bedeutet checked=false und indeterminate=true, keine Auswahl beide false. Bei null Zielen wird die Zentrale deaktiviert; null gleich null bedeutet hier nicht vollständige Auswahl.
Vollständiges Beispiel in einer Datei
Speichern Sie alles als UTF-8 checkbox-demo.html und öffnen Sie die Datei im Browser. Internet lädt die offizielle jQuery-Datei 4.0.0. Kein Server und keine Installation sind nötig. Die Kernfunktionen wurden in Windows Edge mit 3.7.1 und 4.0.0 ausgeführt.
Alpha beginnt ausgewählt, Beta nicht. Locked ist ausgewählt, aber deaktiviert und bleibt außerhalb von Sammeländerung und Zählung. Die Zentrale besitzt kein name und wird nicht als Eintragswert übertragen.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Select all eligible checkboxes</title>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<style>
body { font: 16px/1.6 sans-serif; max-width: 760px; margin: 20px; }
label { display: block; padding: 6px; }
button { font: inherit; margin: 4px; }
fieldset { margin: 12px 0; }
pre { white-space: pre-wrap; overflow-wrap: anywhere; }
</style>
</head>
<body>
<form id="choices">
<label><input type="checkbox" id="all"> Select all available items</label>
<fieldset id="items"><legend>Items</legend></fieldset>
<button type="button" id="add">Add item</button>
<button type="button" id="clear">Remove items</button>
<button type="button" id="reset">Reset example</button>
<button type="submit">Inspect submission</button>
</form>
<pre id="result" aria-live="polite"></pre>
<pre id="submission"></pre>
<script>
$(function () {
const $form = $("#choices"), $all = $("#all");
let next = 1, itemChanges = 0;
function available() { return $("#items input.item:checkbox:enabled"); }
function sync() {
const $items = available(), total = $items.length;
const count = $items.filter(":checked").length;
$all.prop({ checked: total > 0 && count === total,
indeterminate: count > 0 && count < total, disabled: total === 0 });
const values = $items.filter(":checked").map(function () { return this.value; }).get();
$("#result").text(`selected=${count}/${total}\nmaster checked=${$all.prop("checked")}\nmaster mixed=${$all.prop("indeterminate")}\nitem changes=${itemChanges}\nvalues=${values.join(",")}`);
}
function addItem(value, text, checked, disabled) {
const label = document.createElement("label"), input = document.createElement("input");
input.type = "checkbox"; input.name = "item"; input.className = "item";
input.value = value; input.checked = checked; input.disabled = disabled;
label.append(input, document.createTextNode(" " + text));
document.getElementById("items").append(label);
}
$all.on("change.selectAllLesson", function () {
available().prop("checked", this.checked);
sync(); // Setting checked does not emit change on each item.
});
$("#items").on("change.selectAllLesson", "input.item:checkbox", function () {
itemChanges++; sync();
});
$("#add").on("click", function () {
addItem("extra" + next, "Extra " + next, false, false); next++; sync();
});
$("#clear").on("click", function () { $("#items label").remove(); sync(); });
$("#reset").on("click", function () {
$("#items label").remove(); $("#items").prop("disabled", false);
addItem("alpha", "Alpha", true, false);
addItem("beta", "Beta", false, false);
addItem("locked", "Locked (unavailable)", true, true);
next = 1; itemChanges = 0; $("#submission").empty(); sync();
});
$form.on("submit", function (event) {
event.preventDefault();
const params = new URLSearchParams(new FormData(this));
$("#submission").text(params.toString() || "(no successful controls)");
});
$("#reset").trigger("click");
});
</script>
</body>
</html>
Anfangs ist einer von zwei verfügbaren Einträgen ausgewählt. Die Zentrale zeigt den Zwischenzustand.
selected=1/2
master checked=false
master mixed=true
item changes=0
values=alpha
- Select all available items ergibt selected=2/2, master checked=true und master mixed=false. Erneutes Aktivieren ergibt 0/2; Locked bleibt ausgewählt.
- Nur Beta ergibt 1/2 und master mixed=true. Mit Alpha wird die Gesamtauswahl vollständig. Beschriftungen und Leertaste bei Fokus funktionieren ebenfalls.
- Nach Vollauswahl fügt Add item ein nicht ausgewähltes Extra 1 hinzu: 2/3 und teilweise. Wählen Sie es für Vollauswahl.
- Remove items ergibt 0/0 und deaktiviert die Zentrale. Hinzufügen aktiviert sie wieder.
- Mit Alpha und Beta zeigt Inspect submission item=alpha&item=beta. Locked wird ausgeschlossen; ohne Auswahl erscheint (no successful controls).
- Reset example erstellt drei Anfangseinträge neu und leert Zähler und Ausgabe. Es sendet nichts und verwirft Änderungen.
Einzelne und dynamische Änderungen abgleichen
Der zentrale change-Handler weist this.checked allen verfügbaren Einträgen zu und ruft sync() einmal auf. .prop() löst nicht automatisch change bei jedem Kind aus. item changes steigt deshalb bei Einzeländerungen, nicht bei Sammelauswahl.
Delegation am bleibenden #items erfasst später hinzugefügte Checkboxen ohne neue Einzelbindungen. available() fragt jedes Mal das aktuelle DOM ab. Eine anfangs gespeicherte Menge könnte Ergänzungen übersehen oder entfernte Elemente weiterführen.
Hinzufügen und Entfernen rufen sync() ausdrücklich auf. Delegation überwacht keine DOM-Strukturänderungen. Anderer Code, der disabled oder checked setzt, muss dieselbe Synchronisierung aufrufen; automatische Erkennung gibt es hier nicht.
Falls Einzeländerungen auch Preise berechnen, planen Sie diese Arbeit ausdrücklich für Sammeländerungen. .trigger("change") kann gezielt passen, darf aber nicht pro Eintrag unnötige Gesamtberechnungen oder doppelte Anfragen verursachen. Hier wird einmal nach der Sammelzuweisung synchronisiert.
Zwischenzustand, Zurücksetzen und Übertragung
indeterminate ist ein per JavaScript gesetzter Anzeigezustand, kein anfängliches HTML-Attribut und kein zusätzlicher Übertragungswert. Es ist von checked unabhängig. sync() setzt beide Eigenschaften und entfernt alte Zwischenanzeigen. Echte Labels und Checkboxen bewahren die normale Tastaturbedienung.
Inspect submission zeigt FormData an und sendet keine Netzwerkanfrage. Ausgewählte aktive Felder liefern Namen und Werte. Müssen deaktivierte Werte fachlich mitgesendet werden, braucht es bewusste Datenmodellierung und Servervalidierung. Auswahl ersetzt keine serverseitige Berechtigungsprüfung.
Reset example ist eine eigene Neuerstellung. Natives Formular-Reset stellt Standardwerte wieder her; danach muss die Zentrale neu berechnet werden. Nur type="reset" einzusetzen würde dynamische Einträge und Zähler nicht ebenso zurücksetzen.
Ausgewählt werden vorhandene Dokumenteinträge. Noch nicht geladene Seiten einer Server-Paginierung brauchen eigenen Serverzustand. Begrenzen Sie Gruppen getrennt. Bei Filtern muss feststehen, ob alle sichtbaren oder alle aktivierten Gruppeneinträge gemeint sind; Selektoren und Beschriftung müssen dazu passen.




