Die Abfrage von Radiobutton-Gruppen war schon immer etwas aufwendig, weil man nur den Status eines einzelnen Radiobuttons und nicht die ganze Gruppe abfragen kann.
<input type="radio" name="fruits" id="banana" checked="checked" />Banana <input type="radio" name="fruits" id="apple" />Apple <input type="radio" name="fruits" id="cherry" />Cherry
const fruits = document.getElementsByName('fruits'); var selectedFruit = ''; for (var i = 0; i < fruits.length; ++i) { if (fruits[i].checked) { selectedFruit = fruits[i].id; } }
Das sieht sehr archaisch aus. Da muss es doch einen besseren Weg mit den neuen ES6-Features geben. Den gibt es! Seit ES2015 enthält NodeList
die Methode forEach
, das die Sache schon mal einfacher macht:
var fruits = document.getElementsByName('fruits'); let selectedFruit = ''; fruits.forEach((fruit) => { if (fruit.checked) { selectedFruit = fruit.id; } });
Immer noch ziemlich viel Codezeilen. Man kann das Ganze aber viel kompakter, aber auch unleserlicher machen:
[…document.getElementsByName('fruits')].some( (fruit) => (selectedFruit = fruit.id) && fruit.checked );
Hier ist ein wenig Erklärung notwendig, denn wir müssen ganz tief in die Trickkiste greifen.
Als erste wandeln wir mit dem Spread-Operator die NodeList
in ein Array() um, damit wir die coolen neuen Array()
-Methoden nutzen können. Die Array()
-Methode die nutzen ist some
. Diese Methode durchläuft das Array bis die Callback-Methode true
zurück gibt. In unserem Fall verlassen wir den Schleife indem wir auf “fruit.checked
” überprüfen, das true
ist, wenn der Radiobutton aktiv ist.
Der zweite Trick ist es, die Zuweisung der Schleifenvariablen fruit
an die Variable selectedFruit
mit in die Abbruchlogik aufzunehmen. Die Zuweisung ergibt immer true
und beeinflusst somit das Ergebnis der gesamten Anweisung nicht, wenn es mit der &&
Anweisung mit dem Vergleich verbunden wird.
Nebenbei, wir benötigen keine Deklaration der Variablen selectedFruit
in übergeordneten Scope mehr, da wir in der Callback-Funktion keinen neuen Scope eröffnen. Ein neuer Scope erfordert geschwungene Klammern und die werden in diesem Fall nicht benötigt, weil die Callback-Funktion nur eine Anweisung enthält.
Man könnte jetzt pingelig sein und anmerken, dass selectedFruit
nicht ordentlich deklariert sind, aber der Code funktioniert. Also egal!
Edit:
Ich habe diesen Artikel auf dev.to veröffentlicht und Jon Randy hat einen interessanten Kommentar gegeben:
Shorter:
let selectedFruit = […document.getElementsByName('fruits')].find(({checked}) => checked).id
Shorter still:
let selectedFruit = document.querySelector('[name=fruits][checked]')?.id
Leave a Reply