Skip to content

Basic Form (Joi Validation)

A login form with email and password fields validated using a Joi schema. Errors are displayed inline beneath each field. On successful submission, the form data is shown as JSON.

What this example covers:

  • Creating a form with Alpine.Form() and a Joi schema
  • Registering fields with x-register
  • Displaying field errors with getFieldState()
  • Handling submission with form.submit()
  • Resetting the form with form.reset()

Live Demo

JavaScript

Create the form with a Joi schema and pass joiValidator as the validator. The submitFunction receives the validated data on successful submission.

js
Alpine.data('basicForm', () => ({
    result: '',
    showResult: false,
    form: Alpine.Form(
        {},
        {
            schema: {
                email: joi.string().email({ tlds: false }).required().messages({
                    'string.email': 'Please enter a valid email',
                    'any.required': 'Email is required',
                }),
                password: joi.string().min(6).required().messages({
                    'string.min': 'Password must be at least 6 characters',
                    'any.required': 'Password is required',
                }),
            },
            config: {
                validator: joiValidator,
            },
        },
    ),
    submitFunction(data) {
        this.showResult = true;
        this.result = JSON.stringify(Alpine.raw(data), null, 2);
    },
}));

HTML

Each input is registered to the form using x-register:form. The directive value (:form) references the form object, and the expression (form.field('email')) identifies the field name. Error messages are shown conditionally using x-show and x-text bound to getFieldState().

html
<div x-data="basicForm">
    <form @submit.prevent="form.submit(submitFunction)">
        <div class="field-group">
            <label>Email</label>
            <input x-register:form="form.field('email')" type="email" placeholder="Enter email" />
            <span
                class="field-error"
                x-show="!form.getFieldState('email').isValid"
                x-text="form.getFieldState('email').error"
            ></span>
        </div>
        <div class="field-group">
            <label>Password</label>
            <input
                x-register:form="form.field('password')"
                type="password"
                placeholder="Enter password"
            />
            <span
                class="field-error"
                x-show="!form.getFieldState('password').isValid"
                x-text="form.getFieldState('password').error"
            ></span>
        </div>
        <div class="btn-group">
            <button type="submit">Save</button>
            <button type="button" @click="form.reset(); showResult = false;">Reset</button>
        </div>
    </form>
    <pre x-show="showResult" x-text="result"></pre>
</div>

Released under the MIT License.