Alpine CSP x-model
Currently Hyvä CSP is unreleased
This is a documentation preview.
Please watch the #update-notifications channel in Slack to be notified when it is available.
The x-model
directive can't be used with Alpine CSP, as updating the bound property is done by creating and evaluating a JS expression.
Luckily, the workaround is rather simple. The details depend on the input type.
For inputs with user-specified values
Any elements where the user can enter the value, that is the input types text
, email
, date
, and so on.
Instead of x-model
, we use two bindings: :value="prop"
and @input="setProp"
.
Example text
input
<script>
window.addEventListener('alpine:init', () => {
Alpine.data('initExample', () => ({
prop: '',
setProp() {
this.prop = this.$event.target.value;
}
}))
}, {once: true})
</script>
<form x-data="initExample">
<input type="text" :value="prop" @input="setProp">
</form>
Textarea inputs
The textarea
is very similar to the above, except that the value is set as the element content and not an attribute:
Radio buttons and Checkboxes
For checkbox, radio and select inputs use @change
instead of @input
, and instead of :value
use :checked="isChecked"
.
Example checkbox
example
<script>
window.addEventListener('alpine:init', () => {
Alpine.data('initExample', () => ({
prop: [],
updateSelection() {
const checkbox = this.$event.target;
if (checkbox.checked && ! this.prop.includes(checkbox.value)) {
this.prop.push(checkbox.value);
}
if (! checkbox.checked && this.prop.includes(checkbox.value)) {
this.prop.splice(this.prop.indexOf(checkbox.value), 1);
}
},
isChecked() {
return this.prop.includes(this.$el.value);
}
}))
}, {once: true})
</script>
<form x-data="initExample">
<input type="checkbox" name="example[]" value="1" @change="updateSelection" :checked="isChecked">
<input type="checkbox" name="example[]" value="2" @change="updateSelection" :checked="isChecked">
</form>
Select and multiple select inputs
Select and multiple select inputs work similarly to checkboxes, but the selected
property on the option has to be bound instead of checked
<script>
window.addEventListener('alpine:init', () => {
Alpine.data('initExample', () => ({
prop: '',
updateSelection() {
this.prop = this.$el.value;
},
isSelected() {
return this.prop === this.item.id;
}
}))
}, {once: true})
</script>
<form x-data="initExample">
<select name="example" @change="updateSelection">
<template x-for="item in items">
<option value="item.id" :selected="isSelected" x-text="item.label"></option>
</template>
</select>
</form>
x-model
modifiers
To enforce the input to be a number, the utility method hyva.safeParseNumber
is available - which uses the same code as the .number
modifier in Alpine.
At the time of writing there are no utility methods for the other x-model
modifiers .lazy
, .boolean
, .debounce
, .throttle
and .fill
.