bind FeatureThe bind feature keeps two values in sync (two-way). Use it for form inputs and
shared state.
For one-way derived values, see live.
For reacting to changes with side effects, see when.
bind <expression> to <expression>
bind <expression> and <expression>
bind <expression> with <expression>
The keywords to, and, and with are interchangeable.
Keeps two values in sync. Changes to either side propagate to the other.
Toggle a class based on a checkbox:
<input type="checkbox" id="dark-toggle" />
<body _="bind .dark to #dark-toggle's checked">
Keep an attribute in sync with a nearby input:
<input type="text" id="title-input" />
<h1 _="bind @data-title to #title-input's value">
Sync two inputs together:
<input type="range" id="slider" />
<input type="number" _="bind my value to #slider's value" />
When binding a boolean value to an attribute, standard attributes use
presence/absence. ARIA attributes use "true"/"false" strings:
<div _="bind @data-active to #toggle's checked">
<div _="bind @aria-hidden to $isHidden">
When either side of a bind resolves to a DOM element (via me, #id, or a
query), the bound property is detected automatically:
| Element | Detected property |
|---|---|
<input type="text"> |
value |
<input type="number">, <input type="range"> |
valueAsNumber (preserves number type) |
<input type="checkbox"> |
checked |
<input type="radio"> |
radio group value (see below) |
<textarea> |
value |
<select> |
value |
<* contenteditable> |
textContent |
Custom elements with a value property |
value |
<!-- auto-detects 'value' on the input -->
<input type="text" _="bind $name to me" />
<!-- auto-detects 'checked' on the checkbox -->
<input type="checkbox" _="bind $darkMode to me" />
<!-- bind to an element by id — auto-detects 'value' -->
<div _="bind $search to #search-input" />
<!-- both sides auto-detect -->
<input type="number" _="bind me to #slider" />
<!-- explicit property still works -->
<div _="bind $dark to #toggle's checked" />
Radio buttons are grouped by name attribute. The variable holds the value of the
selected radio. Each radio in the group has its own bind:
<input type="radio" name="size" value="small" _="bind $size to me" />
<input type="radio" name="size" value="medium" _="bind $size to me" />
<input type="radio" name="size" value="large" _="bind $size to me" />
Clicking a radio sets $size to that radio's value attribute. Setting $size
programmatically checks the matching radio and unchecks the others.
When both sides have values on init, the left side wins:
<!-- The input's current value drives the variable on init -->
<input type="text" value="Bob" _="bind me to $name" />
<!-- The variable drives the input on init -->
<input type="text" _="bind $name to me" />
If either side is undefined or null, the other side wins regardless of position.
Two-way binding prevents infinite loops with same-value deduplication: if setting a value to what it already equals, the reverse effect does not fire.