S SvelteKurs
M5 · Bindings & Formulare

Gruppen- & Element-Bindings

Radio-Gruppen, Mehrfach-Checkboxen, Selects und direkte DOM-Referenzen — die Bindings jenseits des einfachen Textfelds.

bind:group für Radio-Buttons

Radio-Buttons gehören zusammen: Von einer Gruppe darf immer nur einer aktiv sein. In HTML regelt man das über gleiche name-Attribute — in Svelte über bind:group, das alle Radios an dieselbe Variable koppelt. Der value des angeklickten Radios landet im State.

svelte
<script>
  let plan = $state('free');
</script>

<!-- Alle Radios teilen dieselbe Variable via bind:group -->
<label><input type="radio" bind:group={plan} value="free" /> Free</label>
<label><input type="radio" bind:group={plan} value="pro" /> Pro</label>
<label><input type="radio" bind:group={plan} value="team" /> Team</label>

<p>Gewählt: {plan}</p>

bind:group für Mehrfach-Checkboxen

Dasselbe bind:group erkennt an Checkboxen einen anderen Fall: Mehrere Häkchen dürfen gleichzeitig gesetzt sein. Darum ist die gebundene Variable hier ein Array, das alle angehakten values enthält.

svelte
<script>
  // Bei mehreren Checkboxen ist die Bindung ein Array
  let extras = $state([]);
</script>

<label><input type="checkbox" bind:group={extras} value="ssl" /> SSL</label>
<label><input type="checkbox" bind:group={extras} value="backup" /> Backups</label>
<label><input type="checkbox" bind:group={extras} value="cdn" /> CDN</label>

<p>Aktiv: {extras.join(', ')}</p>

ℹ️ Ein Rune, zwei Verhalten

bind:group an Radios ergibt einen Einzelwert, an Checkboxen ein Array. Svelte leitet das aus dem type des Elements ab — du musst nichts umschalten.

<select> und select multiple

Ein <select> bindest du mit dem vertrauten bind:value. Mit dem Attribut multiple wird aus dem Einzelwert wieder ein Array — ganz analog zu den Checkbox-Gruppen.

svelte
<script>
  let land = $state('de');
  let sprachen = $state([]);
</script>

<!-- Einzelauswahl -->
<select bind:value={land}>
  <option value="de">Deutschland</option>
  <option value="at">Österreich</option>
  <option value="ch">Schweiz</option>
</select>

<!-- Mehrfachauswahl -> Array (Strg/Cmd bzw. Shift zum Mehrfachwählen) -->
<select multiple bind:value={sprachen}>
  <option value="de">Deutsch</option>
  <option value="en">Englisch</option>
  <option value="fr">Französisch</option>
</select>

Live: Konfigurator

Alle vier Binding-Arten in einem echten Formular — die Zusammenfassung unten ist live:

▶ Tarif-Konfigurator · Interaktiv
Plan (Radio-Gruppe)
Extras (Checkbox-Gruppe → Array)

Deine Auswahl:

  • Plan: pro
  • Extras: ssl
  • Land: de
  • Sprachen: de

bind:this — die DOM-Referenz

Manchmal brauchst du das echte DOM-Element selbst — etwa um den Fokus zu setzen, zu scrollen oder eine Canvas-API aufzurufen. bind:this schreibt die Referenz auf das Element in eine Variable, sobald es im DOM steht.

svelte
<script>
  let sucheEl = $state();

  function fokussieren() {
    sucheEl?.focus();   // direkter Zugriff aufs echte DOM-Element
  }
</script>

<input bind:this={sucheEl} placeholder="Suche…" />
<button onclick={fokussieren}>Fokus setzen</button>

⚠️ Erst nach dem Mounten verfügbar

Vor dem ersten Rendern ist die Variable undefined. Greife also nur in Event-Handlern oder in einem $effect darauf zu — daher der Optional-Chaining-Aufruf sucheEl?.focus().

▶ Fokus per bind:this · Interaktiv

Der Button ruft sucheEl.focus() direkt auf dem echten Input-Element auf.

Dimension-Bindings (readonly)

Bindings wie bind:clientWidth, bind:clientHeight, bind:offsetWidth und bind:offsetHeight sind schreibgeschützt: Svelte hält sie über einen ResizeObserver aktuell, du liest den Wert nur. Praktisch für responsives Verhalten ohne Media-Queries.

svelte
<script>
  let breite = $state(0);
  let hoehe = $state(0);
</script>

<!-- readonly: Svelte schreibt hinein, du liest nur -->
<div bind:clientWidth={breite} bind:clientHeight={hoehe}>
  Ich bin {breite}px breit und {hoehe}px hoch.
</div>
▶ Live-Breite messen · Interaktiv
Diese Box ist aktuell 0px breit. Zieh sie unten rechts an der Ecke schmaler oder breiter — der Wert folgt.

Rails-Vergleich: Helper vs. Bindings

🛤️ collection_radio_buttons & select

Rails-Helper wie collection_radio_buttons, collection_check_boxes und select erzeugen das passende HTML mit korrekten name-Attributen. Das Ergebnis kennst du aber erst nach dem Submit in params — und alles kommt als String zurück (Checkbox-Gruppen als Array von Strings).

Svelte-Bindings arbeiten dagegen direkt gegen deinen State im Browser: plan ist sofort gesetzt, extras ist ein echtes JavaScript-Array. Kein name-Fummeln, kein Roundtrip.

Rails erb
# Rails: Helfer erzeugen den passenden HTML-Namen + Wert
<%= form.collection_radio_buttons :plan_id, Plan.all, :id, :name %>
<%= form.collection_check_boxes :extra_ids, Extra.all, :id, :name %>
<%= form.select :land, options_for_select(LAENDER, @user.land) %>
<%= form.select :sprachen, SPRACHEN, {}, multiple: true %>

# Ergebnis liegt erst nach dem Submit in params:
#   params[:user][:plan_id]        => "2"        (String!)
#   params[:user][:extra_ids]      => ["1", "3"] (Array of Strings)
#   params[:user][:sprachen]       => ["de", "en"]

Zusammenfassung

💡 Das Wichtigste

  • bind:group an Radios → Einzelwert, an Checkboxen → Array.
  • <select bind:value> bindet Einzelauswahl; mit multiple ein Array.
  • bind:this liefert das echte DOM-Element (erst nach dem Mounten, also ?.).
  • Dimension-Bindings (clientWidth etc.) sind readonly und bleiben automatisch aktuell.

🎯 Probier es selbst

Baue eine Preis-Anzeige in den Konfigurator ein: Berechne mit einem $derived einen Gesamtpreis aus plan und der Anzahl der extras, und zeige ihn live unter der Auswahl an. Erweitere außerdem den Fokus-Button so, dass er das Feld nach dem Fokussieren auch leert.