Install the Package
composer require vkm-apps/x-form
npm install @alpinejs/intersect @alpinejs/collapse
npm run dev
Verify alpinejs and livewire are installed in your project.
Publish Configuration & Assets
php artisan vendor:publish --provider="VkmApps\XForm\XFormServiceProvider" --tag=xform-config
php artisan vendor:publish --provider="VkmApps\XForm\XFormServiceProvider" --tag=xform-assets
This generates:
config/x-form.php (customize form behavior)public/vendor/xform (CSS/JS).Basic Blade Component Usage
Add the Livewire directive to your Blade layout (e.g., resources/views/layouts/app.blade.php):
@livewireScripts
@stack('scripts')
Use a pre-built component in a view (e.g., resources/views/forms/contact.blade.php):
<x-form.text
name="email"
label="Email Address"
:value="old('email')"
required
/>
First Livewire Form Integration Create a Livewire component to handle form submission:
php artisan make:livewire ContactForm
Update app/Http/Livewire/ContactForm.php:
public function submit()
{
$validated = $this->validate([
'email' => 'required|email',
]);
// Process data...
}
Bind the form to the Livewire component in Blade:
<livewire:contact-form />
Test the Form Run the development server:
php artisan serve
Navigate to your form view and submit to verify validation/error handling.
<x-form.*> tags for common inputs (e.g., text, email, select, checkbox, editor).
<x-form.text name="username" label="Username" required />
<x-form.checkbox name="terms" label="Agree to terms" />
<x-form.dynamic-array name="questions">
<x-slot name="item">
<x-form.text name="question" label="Question" />
</x-slot>
</x-form.dynamic-array>
// Livewire component
public $email;
protected $rules = ['email' => 'required|email'];
public function submit()
{
$this->validate();
// Save logic...
}
<x-form.text name="email" :value="$email" />
<x-form.text name="email" :error="$errors->first('email')" />
$rules or AlpineJS:
// AlpineJS (for client-side validation)
x-data="{ rules: { email: 'required|email' } }"
<x-form.file name="avatar" label="Profile Picture" />
<x-form.editor name="description" />
x-show or Livewire logic:
<x-form.text name="phone" x-show="showPhone" />
x-data="{ showPhone: @entangle('show_phone') }"
config/x-form.php:
'default_align' => 'horizontal', // 'horizontal' | 'vertical'
'editor_options' => [
'plugins' => ['youtube'],
],
FormRequest:
// Livewire component
use App\Http\Requests\StoreUserRequest;
public function mount(StoreUserRequest $request)
{
$this->rules = $request->rules();
}
resources/css/app.css:
.x-form-input {
@apply border-gray-300 rounded-md;
}
.x-form-error {
@apply text-red-500 text-sm;
}
$emit/$listen for real-time updates:
// Livewire component
public function addField()
{
$this->fields[] = '';
$this->emit('fieldAdded');
}
<div x-data="{ count: 0 }" x-on:fieldAdded="count++">
<!-- Dynamic fields -->
</div>
$currentStep and AlpineJS for step transitions:
<template x-for="step in steps" :key="step.id">
<div x-show="currentStep === @entangle('currentStep').step.id">
<!-- Step content -->
</div>
</template>
Livewire::test():
public function test_form_submission()
{
Livewire::test('contact-form')
->set('email', 'test@example.com')
->call('submit')
->assertSee('Success!');
}
$this->visit('/contact')
->fill('email', 'test@example.com')
->press('Submit')
->assertSee('Success!');
Livewire vs. AlpineJS State Conflicts
@entangle to bind AlpineJS to Livewire properties:
<input x-model="@entangle('email')" />
Alpine.js: Unable to parse expression errors.File Upload Stuck States
public function submit()
{
$this->validate();
$this->reset('avatar'); // Reset file input
}
<x-form.file name="avatar" wire:model="avatar" />
Editor Initialization Failures
x-form.editor) may fail if AlpineJS loads after Livewire.@push('scripts')
@alpinejs
@endpush
CSS Class Overrides
!important sparingly or increase specificity:
.x-form-container .custom-class {
@apply your-styles !important;
}
Dynamic Arrays and Livewire Keys
wire:key on dynamic items:
<div wire:key="field-{{ $index }}">
<x-form.text name="fields.{{ $index }}" />
</div>
AlpineJS Namespace Collisions
x-data or x-model bindings if AlpineJS is loaded multiple times.<div x-data="{ /* isolated scope */ }">
<!-- Form components -->
</div>
Livewire Logs
Enable Livewire’s debug mode in .env:
LIVEWIRE_LOG_LEVEL=debug
Check logs for hydration errors or property updates.
AlpineJS DevTools Use the Alpine.js DevTools browser extension to inspect reactive state.
Blade Debugging Dump variables to
How can I help you explore Laravel packages today?