alpidate
Version:
A model-based validation plugin for Alpine.js, inspired by Vuelidate.
1 lines • 6.73 kB
Markdown
# alpidate
**A lightweight validation plugin for Alpine.js inspired by Vuelidate.**
****
**[Alpidate on npm](https://www.npmjs.com/package/alpidate)**
## Demo
Try the live demo here: [Alpidate Live Demo](https://h7arash.github.io/alpidate/)
## Installation
### Via npm (Recommended for Module Bundlers)
You can install `alpidate` via npm:
```sh
npm install alpidate
```
Then import and register:
```javascript
import Alpine from 'alpinejs';
import alpidate from 'alpidate';
Alpine.plugin(alpidate);
Alpine.start();
```
### Via CDN (For Quick Prototyping or Static Sites)
You can load alpidate directly from a CDN like unpkg:
```html
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/alpidate/dist/alpidate.cdn.js"></script>
<script>
document.addEventListener('alpine:init', () => {
Alpine.plugin(alpidate)
})
</script>
```
Note: Ensure Alpine.js is loaded before alpidate. This uses the global **alpidate** export.
## Usage
### Setting Up Validation in a Component
Define validation rules inside the `validations` property and initialize validation in `init()`:
```js
Alpine.data('app', () => ({
init() {
// default: validation state stored on $v
this.$validation(this); // -> creates this.$v
}
// Validation rules
validations: {
'first_name': ['required', 'min:3'],
'last_name': ['required', 'min:3'],
'delivery_note': ['requiredIf:express_delivery,true', 'max:100'],
'email': ['required', 'email'],
'address': ['required', 'array'],
'address.*.name': ['required', 'min:2'],
'address.*.address': ['required', 'min:5'],
'address.*.phone': ['regex:^\\d{10}$']
},
// Form data
first_name: '',
last_name: '',
email: '',
express_delivery: false,
delivery_note : '',
address: [
{ name: '', address: '', phone: '' },
{ name: '', address: '', phone: '' }
]
}));
```
### Nested components / isolated validation state
If you use nested `x-data` components and need each component to keep its own validation state (instead of sharing the default `$v`), pass a custom key when initializing. This creates a separate validation tree under that key and prevents collisions/overwrites with parent components. All validation-related properties (e.g., state, `$invalid`, `$touch`, `validate()`) will be stored under the custom key, not the default `$v`:
```js
// inside a nested component's init()
this.$validation(this, '$v2'); // -> creates this.$v2 (isolated)
```
## Supported Validation Rules
| Rule | Description |
|------------|--------------------------------------------------------------------------- |
| required | Ensures the field is not empty. |
| requiredIf | Ensures the field is required only if a specified condition is met, based on the value of another field. The condition is defined as `requiredIf:field,expectedValue`, where the field must match the expected value for the validation to apply. |
| numeric | The field must contain only numbers. |
| email | Validates an email format. |
| regex | Allows custom validation rules using regular expressions. |
| min:value | Specifies the minimum length or value. |
| max:value | Specifies the maximum length or value. |
| array | Ensures the field is an array. |
**Nested models and array items are supported**, for example:
```js
// Nested model
'form.firstName': ['required', 'min:3']
// Array item validation using wildcard '*'
'address.*.name': ['required', 'min:2']
'address.*.phone': ['regex:^\\d{10}$']
```
## Accessing Validation State
All validation state is stored under the specified key (defaults to `$v`). Each model inside the validation state contains:
- **Rule results**: e.g., `required`, `min`, `regex`, etc. Each key shows whether that specific rule passed (`false`) or failed (`true`).
- **$invalid**: Boolean indicating if **any of the assigned rules failed** for that model.
For array fields, use `each` to access per-item validation:
```js
// Access validation for first item in the address array
this.$v.address.each[0].name.$invalid // true or false
this.$v.address.each[1].phone.regex // true or false
```
### Special properties : ###
- `$v.$touch` – Controls when validation messages appear. It remains false until you manually trigger validation with :
```js
this.$v.validate();
```
- `$v.$invalid` – Boolean indicating whether any rule in the entire form fails. Whenever a model changes, its validation state updates automatically. Use $touch to delay showing errors until, for example, form submission.
### For isolated / nested components:
If you initialized validation with a custom key (e.g., `this.$validation(this, '$v2')`), the validation tree and special props live under that key:
```js
// init inside nested component
this.$validation(this, '$v2'); // creates this.$v2
// run full validation
this.$v2.validate();
// or validate a single model
this.$v2.validate('selectedAddress');
```
### Displaying Validation Errors in Template
Use the validation key to conditionally display validation errors in your template:
```html
<span x-show="$v.first_name.$invalid && $v.$touch">
<small x-show="$v.first_name.required" class="text-red">First Name is required</small>
<small x-show="!$v.first_name.required && $v.first_name.min" class="text-red">Minimum 3 characters</small>
</span>
<template x-for="(addr, idx) in address" :key="idx">
<div>
<input x-model="addr.name" placeholder="Name">
<span x-show="$v.address.each[idx].name.$invalid && $v.$touch">
<small x-show="$v.address.each[idx].name.required" class="text-red">Address is required</small>
<small x-show="!$v.address.each[idx].name.required && $v.address.each[idx].name.min" class="text-red">Minimum 2 characters</small>
</span>
</div>
</template>
```
For custom keys (e.g., $v2), replace $v with $v2 in the template:
```html
<span x-show="$v2.first_name.$invalid && $v2.$touch">...</span>
```
### Understanding the Validation State
- Each model inside the validation state has an `$invalid` property indicating if all assigned validation rules pass.
- `$touch` helps control when validation messages appear (e.g., after form submission).
- Array items are available via `arrayField.each` under the validation key.
## License
MIT License