Description: The x-model directive in AlpineJS provides a powerful and convenient way to create a seamless, reactive, two-way synchronization between form input elements and your component's data properties. This means that when the user interacts with a form field (e.g., types in a text input, checks a box), the corresponding data property in your Alpine component is automatically updated. Conversely, if the data property changes programmatically, the form input element will reflect that change.
x-model is the core directive for two-way data binding. It's used on form elements like <input>, <select>, and <textarea>.
Binds the input's value to an Alpine data property. Any change to the input updates the property, and any change to the property updates the input's value.
<input type="text" x-model="message">
<textarea x-model="description"></textarea>
In your Alpine component data:
message: 'Hello World',
description: 'Some initial text.'
Binds the input's checked state to a boolean Alpine data property. If the checkbox has a value attribute, and the x-model property is an array, Alpine will add/remove the checkbox's value from the array based on its checked state.
<!-- Boolean binding -->
<input type="checkbox" x-model="isAdmin"> Is Admin
<!-- Array binding (for multiple selections) -->
<input type="checkbox" x-model="selectedColors" value="red"> Red
<input type="checkbox" x-model="selectedColors" value="green"> Green
<input type="checkbox" x-model="selectedColors" value="blue"> Blue
In your Alpine component data:
isAdmin: false,
selectedColors: ['green'] // Green will be initially checked
Binds the checked state of a group of radio buttons to a single Alpine data property. The property will hold the value of the selected radio button.
<input type="radio" x-model="paymentMethod" value="credit_card"> Credit Card
<input type="radio" x-model="paymentMethod" value="paypal"> PayPal
In your Alpine component data:
paymentMethod: 'paypal' // PayPal will be initially selected
Binds the selected option's value to an Alpine data property. For <select multiple>, it binds to an array of selected option values.
<select x-model="chosenCountry">
<option value="us">United States</option>
<option value="ca">Canada</option>
</select>
In your Alpine component data:
chosenCountry: 'ca' // Canada will be initially selected
Modifiers: x-model can be enhanced with modifiers to alter its behavior:
.lazy: By default, x-model syncs data on every input event. With .lazy, it syncs only after change events (e.g., when the input loses focus or Enter is pressed for text inputs).
<input type="text" x-model.lazy="searchTerm">
.number: Automatically casts the input's string value to a JavaScript number. If the value cannot be converted to a number, it will remain the original string.
<input type="number" x-model.number="quantity">
.debounce: Waits for a specified duration after the last keystroke before updating the model. This is useful for performance-intensive tasks or API calls triggered by input changes.
<!-- Default debounce: 250ms -->
<input type="text" x-model.debounce="searchQuery">
<!-- Custom debounce: 500ms -->
<input type="text" x-model.debounce.500ms="searchQueryDelayed">
.trim: Automatically trims whitespace from the input value before syncing.
<input type="text" x-model.trim="username">
x-model data:
If an input element has an HTML value attribute (e.g., <input type="text" value="initial" x-model="myVar">) and x-model is also set, Alpine's x-model will typically take precedence for initializing the component's data property. However, to avoid confusion and ensure clarity, it's best practice to define the initial state solely within your x-data object. Let the Alpine data be the single source of truth for the initial state, and x-model will then correctly set the input's initial display value.
Bad: <input type="text" value="From HTML" x-model="name"> with name: '' in x-data.
Good: <input type="text" x-model="name"> with name: 'From Alpine Data' in x-data.
x-model on non-form elements:
x-model is specifically designed for form elements like <input>, <select>, and <textarea>. Attempting to use x-model on elements like <div> or <p> will not achieve two-way data binding. For displaying data in non-form elements (one-way binding), use directives like x-text (for text content) or x-bind (for attributes).
.number for numerical inputs:
HTML input values are always strings, even for <input type="number">. If you bind x-model to such an input and expect the corresponding data property to be a number, you might be surprised to find it's a string (e.g., "123" instead of 123). This can lead to unexpected behavior in JavaScript, especially with arithmetic operations (e.g., "1" + 1 results in "11"). Always use the .number modifier (x-model.number="myNumericProperty") to ensure the value is automatically cast to a number type in your Alpine data.
Search Term:
Feedback (Debounced):
Age (Type: ):
Subscribed:
User Type:
Selected Fruit: