Validate
The @validate attribute adds client-side form validation using the browser’s native Constraint Validation API. Validation rules come from HTML attributes like required, minlength, type="email".
import Attractive from "attractivejs";
import { validate } from "attractivejs/validate";
Attractive.activate({ extendWith: [validate] });
@validate attribute
Add @validate to any <form> to enable validation. The form submit is blocked until all inputs are valid.
<form @validate>
<input type="email" required />
<input minlength="3" required />
<button>Submit</button>
</form>
Validation runs on change and on submit. Errors clear as the user types.
Styling
Use the :user-invalid CSS pseudo-class to style invalid inputs. It applies automatically after the user has interacted with the field.
input:user-invalid,
select:user-invalid,
textarea:user-invalid {
border-color: red;
}
Error messages appear as <span class="error-label"> elements inserted after the invalid input.
span.error-label {
color: red;
font-size: 0.85em;
display: block;
}
Custom validation messages
Override the browser’s default messages with data-validate-messages. A JSON object mapping ValidityState keys to custom strings.
Lookup order per input:
- Input’s own
data-validate-messages - Form’s
data-validate-messages - Browser default (
input.validationMessage)
<form @validate data-validate-messages='{"valueMissing":"This field is required","tooShort":"Too short"}'>
<input type="email" required name="email" data-validate-messages='{"typeMismatch":"Not a valid email"}' />
<input type="url" required name="website" data-validate-messages='{"typeMismatch":"Not a valid URL"}' />
<input name="name" minlength="3" required />
<button>Submit</button>
</form>
Supported keys (match the browser’s ValidityState property names):
| ValidityState key | Trigger |
|---|---|
valueMissing |
required |
tooShort |
minlength |
tooLong |
maxlength |
typeMismatch |
type="email", type="url"
|
patternMismatch |
pattern |
rangeUnderflow |
min |
rangeOverflow |
max |
stepMismatch |
step |
badInput |
Invalid browser-parsed value |
Integration with Attract
When used together, @validate and @attract compose naturally through shared DOM events.
<form @validate @attract action="/messages" method="post">
<input name="body" required />
<button>Submit</button>
</form>
@attract intercepts the submit and sends the request. If the server returns { errors: { body: "Cannot be empty" } }, @attract sets the error via setCustomValidity and calls reportValidity. @validate catches the invalid event and renders a styled <span class="error-label">, the same way it renders client-side validation errors. The result is identical regardless of whether the error came from the browser or the server.