Checkbox in Browser speichern?

1 Antwort

Vom Beitragsersteller als hilfreich ausgezeichnet

Du kannst den Wert in einem Cookie speichern. Im letzten Abschnitt auf dieser Seite (All Together Now) findest du eine Implementation zum Setzen und Holen eines Wertes. Die jeweiligen Funktionen musst du folgend nur noch aufrufen.

Nun brauchst du eigentlich nur noch einen Listener an deine Checkbox hängen. Wenn sie sich ändert, kannst du in einem Callback darauf reagieren und bspw. dein Cookie setzen.

<input id="mycheckbox" type="checkbox">
<script>
  /* your cookie functions ... */

  document.getElementById("mycheckbox").addEventListener("change", function() {
    setCookie("mycheckboxstate", this.checked, /* some duration ... */);
  });
</script>

einKellerkind 
Beitragsersteller
 07.10.2021, 09:48
Besten Dank. Das funzt so, wie ich mir das vorgestellt habe. Aber leider erscheinen zwei Checkboxen. Perfekt wäre es, wenn ich die Möglichkeit hätte, zwei Formatierungen zu implementieren. Beispiel: Checkbox ohne Häkchen rot, Checkbox mit Häkchen grün.

<input type="checkbox" id="foobar">
<script>
(() => {
const checkbox = document.getElementById("foobar");
const wasChecked = window.localStorage.getItem("myFoobarKey");
if (wasChecked === "1") {
checkbox.checked = true;
} else if (wasChecked === "0") {
checkbox.checked = false;
}


checkbox.addEventListener("change", () => {
window.localStorage.setItem("myFoobarKey", checkbox.checked ? "1" : "0");
});
})();
</script>


<div><input type="checkbox" id="CookieCheck" onclick="cookiesCheck()"></div>

ps: wenn ich die Checkbox mehrfach auf einer Seite platzieren möchte, einzeln, ohne das der Zustand einer Kontrollbox auf alle angewandt wird, was muss ich bei der Konfiguration des Snippet beachten?

 

0
regex9  07.10.2021, 11:05
@einKellerkind
Aber leider erscheinen zwei Checkboxen.

Du hast ja auch zwei Checkboxen in deinem Snippet angelegt.

Perfekt wäre es, wenn ich die Möglichkeit hätte, zwei Formatierungen zu implementieren.

Das Element selbst kannst du kaum verändern. Aber du kannst es ausblenden und mit einer anderen Box visuell ersetzen.

<input id="some-checkbox" type="checkbox">
<label for="some-checkbox">Some checkbox</label>

Der erste Schlüsselpunkt ist die Verbindung zum Label-Element. Ein Klick auf dieses würde die Checkbox genauso aktivieren, wie auch ein Klick auf die Checkbox selbst.

Der Rest geschieht mit CSS:

input[type=checkbox] {
  display: none;
}

label::before {
  background-color: red;
  content: '';
  display: inline-block;
  height: 15px;
  margin-right: 5px;
  position: relative;
  width: 15px;
}

input[type=checkbox]:checked + label::before {
  background-color: green;
}

input[type=checkbox]:checked + label::after {
  content: '\2713';
  left: 10px;
  position: absolute;
  top: 5px;
}

Der zweite Schlüsselpunkt ist die Pseudoklasse :checked. Sie verweist auf aktivierte Checkboxen.

wenn ich die Checkbox mehrfach auf einer Seite platzieren möchte, (...) was muss ich bei der Konfiguration des Snippet beachten?

Da eine ID nur einmal pro Dokument an genau ein Element vergeben werden darf, solltest du (vor allem um den Code einfacher / kürzer zu halten) Klassen oder data-Attribute vergeben.

<input data-storage-key="some key" id="some-checkbox" type="checkbox">
<!-- ... -->
<input data-storage-key="some other key" id="some-other-checkbox" type="checkbox">
<!-- etc. --->

Im Skript kannst du dir alle Boxen holen und ihnen via Schleife Event Listener zuweisen.

function saveCheckboxStatus() {
  // save status somewhere ...
}
  
const storableCheckboxes = document.querySelectorAll("input[type=checkbox][data-storage-key]");

for (const storableCheckbox of storableCheckboxes) {
  storableCheckbox.addEventListener("change", saveCheckboxStatus);
}   

Wie schon beim Snippet aus meiner Antwort gibt es bei dieser Lösung keine gegenseitige Beeinflussung von Checkboxen.

Den Wert des data-Attributs kannst du als Key verwenden, unter dem du deine Daten speicherst. Du bekommst ihn innerhalb der saveCheckboxStatus-Funktion so:

const key = this.dataset.storageKey;
1
einKellerkind 
Beitragsersteller
 07.10.2021, 23:58
@regex9

Danke dir :) Wie kann ich die Checkbox ausblenden, die direkt über das Script erzeugt wird?

0
einKellerkind 
Beitragsersteller
 08.10.2021, 00:02
@einKellerkind

Danke dir :) Wenn ich den Input-Tag mit Label hinzufüge, habe ich zwei Checkboxen. Eine Box, die über die CSS-Formatierung angepasst ist, die andere ist nicht änderbar bzw. soll ausgeblendet werden. Wie kann ich das machen?

0
regex9  08.10.2021, 00:15
@einKellerkind

Das kommt darauf an, inwiefern du sie brauchst. Wenn du sie gar nicht brauchst, schreibe sie erst gar nicht in dein Markup. Wenn du sie brauchst, kannst du sie via CSS ausblenden lassen.

#foobar { display: none }
1
einKellerkind 
Beitragsersteller
 08.10.2021, 00:47
@regex9

Okay, danke. Das klappt soweit. Die CSS-Formatierung greift.

 <input type="checkbox" id="foobar">

<script>

(() => {

   const checkbox = document.getElementById("foobar");

   const wasChecked = window.localStorage.getItem("myFoobarKey");

   if (wasChecked === "1") {

       checkbox.checked = true;

   } else if (wasChecked === "0") {

       checkbox.checked = false;

   }

   checkbox.addEventListener("change", () => {

       window.localStorage.setItem("myFoobarKey", checkbox.checked ? "1" : "0");

   });

})();

</script>

   <input id="checkbox123" type="checkbox" /> <label for="checkbox123">Some checkbox</label>

Leider speichert der Zustand der Box nicht mehr richtig ab. Habe ich etwas falsch gemacht?

0
regex9  08.10.2021, 01:04
@einKellerkind

Den Zustand welcher Checkbox möchtest du denn nun speichern? Das Skript fokussiert sich auf die Checkbox mit der ID foobar. Die Checkbox mit der ID checkbox123 wird nicht berücksichtigt.

1
einKellerkind 
Beitragsersteller
 08.10.2021, 01:09
@regex9

Das Problem ist, dass ich die foobar nicht via CSS erreichen kann. Wenn ich aber den Input-Tag mit Label setze, geht es problemlos. Wenn ich die Foobar nicht auf display-none setze, habe ich zwei Boxen.

0
regex9  08.10.2021, 01:14
@einKellerkind

Es ist nun für mich gar nicht mehr verständlich, was du überhaupt erreichen möchtest.

0
einKellerkind 
Beitragsersteller
 08.10.2021, 01:25
@regex9

Entschuldigung. Ich habe mich im Verlauf auch sehr undeutlich ausgedrückt. Ich arbeite mit dem CMS Jimdo und baue gerade ein E-Learning auf. Ich habe auf einer Seite mehrere Videos untereinander implementiert. Meine Nutzer wünschen sich die Lösung, via Checkbox ein Video als "angeschaut" zu markieren. Da ich keinen serverseitigen Zugriff habe, die Idee, den Zustand der Checkbox im Browser-Cookie zu speichern. Das Script funktioniert. Aber es erscheinen permanent zwei Checkboxen. Eine ist über die CSS formatiert, die andere nicht. Beide reagiere jedoch auf Klicken gleichzeitig. Wenn ich den von dir vorgeschlagenen Input-Tag entferne, bleibt eine Checkbox. Aber irgendwie lässt sich diese nicht über meine CSS formatieren. Die Funktion passt, aber an der Gestaltung scheitert es letztlich.

0
regex9  08.10.2021, 02:35
@einKellerkind

Ich vermute, du hast die Lösung (die ersten beiden Snippets) aus diesem Kommentar eingesetzt, aber noch nicht ganz verstanden, was sie tut. Es würde jedenfalls auf das passen, was du beschreibst.

Die obige Lösung zeichnet neben der Checkbox eine zweite Box. Diese zweite Box ist ein Pseudoelement (siehe ::before-Selektor) - keine echte Checkbox. Wenn man sie anhakt (ein zweites Pseudoelement: siehe ::after-Selektor), wird diese Box grün und ist mit einem Häkchen versehen.

Diese zweite Box wird nur gezeichnet, da eine normale Checkbox, wie sie aus dem input-Element generiert wird, äußerlich kaum anpassbar ist. Sie soll also die Standardcheckbox (nur!) visuell ersetzen. Die Standardcheckbox wird mit folgendem Style ausgeblendet, da sie visuell nicht mehr benötigt wird:

input[type=checkbox] {
  display: none;
}

Wenn das bei dir nicht klappt, gibt es sicherlich irgendwo einen Style in deiner Webanwendung, der diesen Zustand nochmals überschreibt. Du könntest statt dem obigen Selektor einen ID-Selektor im CSS formulieren, der eine höhere Priorität hat und vermutlich nicht überschrieben werden würde.

#some-checkbox {
  display: none;
}

Hinter der Raute steht der Name der ID des input-Elements.

Da die gezeichnete Box Bestandteil des label-Elements ist, welches an das ausgeblendete input-Element gebunden wird, wird bei Klick auf die Box auch die ausgeblendete Checkbox aktiviert (oder wieder deaktiviert). Um dieses Verhalten noch weiter zu verstehen, kannst du folgendes einmal testen:

<input id="test">
<label for="test">Click me</label>

Klick auf den Labeltext. Du wirst sehen, dass daraufhin das Eingabefeld aktiviert / fokussiert wird. So, als hättest du gleich direkt auf das Eingabefeld geklickt. Dieses Browserverhalten ist nur möglich, wenn sich das Label mit dem input-Element verbindedt. Dazu muss das for-Attribut entweder auf die ID des input-Elements verweisen oder das input-Element muss innerhalb des label-Tags stehen.

0