@ramstack/alpinegear-bound 

@ramstack/alpinegear-bound is a plugin for Alpine.js that provides the x-bound directive.
This directive allows for two-way binding between input elements and their associated data properties. It works similarly to the binding provided by Svelte and also supports synchronizing values between two Alpine.js data properties.
> [!Note] > This package is part of the @ramstack/alpinegear-main bundle. > If you are using the main bundle, you don't need to install this package separately.
Installation
$3 To include the CDN version of this plugin, add the following
tag before the core
alpine.js file:
``html
`
$3 Alternatively, you can install the plugin via npm
:
`
bash npm install --save @ramstack/alpinegear-bound`
Then initialize it in your bundle:
`
js import Alpine from "alpinejs"; import bound from "@ramstack/alpinegear-bound";Alpine.plugin(bound); Alpine.start();
`
Usage The syntax for binding properties is
x-bound:property="dataprop"
.Let's take the following example:
`
html`
š Live demo | Alpine.js x-bound: Basic usage In this example, we bind the
name
property to the value
property of the element. Since x-bound
provides two-way binding, any changes to name
will be reflected in the element, as will occur when the button
is clicked.
$3 The x-bound
directive also supports shorthand syntax: &
.So the previous example could be written as follows:
`
html`
If the element's property name matches the bound data property, you can simplify this further:
`
html`
In this example, the repetition of the
value
in x-bound:value="value"
is redundant, so we can simply shorten it to . Since we can use &
instead of x-bound
, the example can be written as follows:
`
html`
More examples:
`
html ...
`
š Live demo | Alpine.js x-bound: Shorthand Syntax
$3 For
elements with type="number"
and type="range"
, values are automatically coerced into numbers. If the value is empty or invalid, the bound property will be set to null
.
`
html`
š Live demo | Alpine.js x-bound: Bind Numeric Inputs
$3 For
elements with type="file"
, the binding is applied to the files
property, resulting in a FileList object being assigned, containing the list of selected files.
`
html`
š Live demo | Alpine.js x-bound: Bind Files
$3 To bind the value of a
element, use the value property:`html Select... Apple Banana Orange Grape Mango
Fruit:
` š Live demo | Alpine.js x-bound: Binding select For a
element, the data property is an array containing the values of the selected options.
`html Cat Goldfish Parrot Spider Pets:
` š Live demo | Alpine.js x-bound: Multiple select
$3 The directive also allows binding to the
open property of elements:
`html Details Something small enough to escape casual notice.
Open / Close
` š Live demo | Alpine.js x-bound: Binding details
$3 You can bind the
naturalWidth and naturalHeight properties of an image after it loads:
`html` š Live demo | Alpine.js x-bound: Binding image sizes > [!TIP] > If you prefer using
kebab-case for multi-word properties like naturalWidth, you can write it as natural-width. It will be automatically normalized internally: > `html > > `> [!NOTE] > As HTML attributes are case-insensitive, corresponding properties can be written as follows: >
`html > > ` > [!NOTE] > The
naturalWidth and naturalHeight properties are read-only and reflect the original image dimensions, available after the image has loaded.
$3 You can bind the
videoWidth and videoHeight properties of a video after it loads:
`html ` š Live demo | Alpine.js x-bound: Binding video sizes
$3 For
contenteditable elements, you can bind the following properties: - innerHTML - innerText - textContent
`html
` š Live demo | Alpine.js x-bound: Contenteditable bindings
$3 You can bind to the following properties to get the width and height of block-level elements, measured with a
ResizeObserver. The values will update whenever the element's size changes:- clientHeight - clientWidth - offsetHeight - offsetWidth
`html
` š Live demo | Alpine.js x-bound: Binding element dimensions > [!NOTE] > These properties are read-only.
> [!IMPORTANT] > Elements with
display: inline don't have an explicit width or height (unless they are intrinsically sized, like or ). Therefore, a ResizeObserver cannot track their size. If you need to observe their size, change their display style to something like inline-block. > > Also keep in mind that CSS transforms do not trigger ResizeObserver updates.
$3 The group of elements that should function together can utilize the group bound property.
`html` š Live demo | Alpine.js x-bound: Binding group inputs
$3 The x-bound directive supports binding the indeterminate property of elements, allowing you to control the checkbox's indeterminate state (a state where the checkbox is neither checked nor unchecked, typically represented visually with a dash or similar indicator).
`html` š Live demo | Alpine.js x-bound: Binding indeterminate This is useful for scenarios like selecting a subset of items in a list, such as in a table header checkbox:
`html` š Live demo | Alpine.js x-bound: Binding indeterminate (table) In this example, the
indeterminate property of the checkbox is bound to the isPartialSelected data property. When isPartialSelected is true, the checkbox will be in the indeterminate state.> [!NOTE] > The
indeterminate binding is one-way. Changes to the indeterminate property in the DOM (e.g., via user interaction or programmatically) do not update the bound data property.
$3 The directive also supports synchronizing values between two data properties.
`html` š Live demo | Alpine.js x-bound: Binding data properties In this example, we bind the outer
number property to the inner count property. Since number is initially set to 5, the count property is also set to 5 when the binding occurs.By default, the binding is two-way, so changes in
count are reflected in number and vice versa.But what if we want changes to propagate in one direction only? For this case, the
x-bound directive provides three modifiers to control data flow:> [!TIP] > -
inout: Binding works in both directions. This means that changes in one property are automatically reflected in the other and vice versa. This modifier is used by default. > > Example: If we have the property &count="number", then changing the value of count will also change the value of number, and vice versa. > > - in: Binding works in one direction only ā from the source property to the target property. This means that changes in the source property are passed to the target property, but changes in the target property do not affect the source property. > > Example: If we have &count.in="number", then changes in number will be passed to count, but changes in count will not be reflected in number. > > - out: Binding works in one direction only ā from the target property to the source property. This means that changes in the target property are passed to the source property, but changes in the source property do not affect the target property. > > Example: If we have &count.out="number", then changes in count will be passed to number, but changes in number will not be reflected in count.> [!NOTE] > The default behavior (
inout) can also be achieved using the x-model and x-modelable` directives.
Source code You can find the source code for this plugin on GitHub:https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/bound
Related packages This package is part of AlpineGear ā a collection of utilities and directives for Alpine.js .You can find the full list of related packages and their documentation here: https://github.com/rameel/ramstack.alpinegear.js
Contributions Bug reports and contributions are welcome.
License This package is released as open source under the MIT License . See the LICENSE file for more details.