The Zinq Form Builder simplifies creating dynamic and reusable forms in Livewire components. Here's a step-by-step explanation of how to define a form using Zinq Form Builder.
To integrate a form into a Livewire component, you need to:
use Mattbit\Zinq\Form\Element;
use Mattbit\Zinq\Form\Form;
...
return Form::make()
->setStructure([
Element\Toggle::make('active'),
Element\Divider::make('divider'),
Element\Text::make('name'),
Element\Select::make('type')
->options([
'individual' => 'Individual',
'company' => 'Company',
]),
]);
use Livewire\Component;
use Mattbit\Zinq\Form\Element;
use Mattbit\Zinq\Form\Form;
class CreateCustomer extends Component
{
public array $data = [];
private function form(): Form
{
return Form::make()
->setStructure([
Element\Toggle::make('active'),
Element\Divider::make('divider'),
Element\Text::make('name'),
Element\Select::make('type')
->options([
'individual' => 'Individual',
'company' => 'Company',
]),
]);
}
public function save(): void
{
// The $this->data property contains the form data
}
public function render(): string
{
return view('livewire.create-customer', ['form' => $this->form()]);
}
}
The Zinq Form Builder provides a simple way to validate form data. You can define validation rules for each form element using the rules
method.
use Mattbit\Zinq\Form\Element;
use Mattbit\Zinq\Form\Form;
...
return Form::make()
->setStructure([
Element\Text::make('name')
->rules('required|string|min:3|max:255'),
Element\Email::make('email')
->rules('required|email'),
Element\Divider::make('divider'),
Element\Radio::make('preferred_contact')
->options([
'email' => 'Email',
'phone' => 'Phone',
])
->rules('required|string|in:email,phone'),
]);
use Livewire\Component;
use Mattbit\Zinq\Form\Element;
use Mattbit\Zinq\Form\Form;
class CreateCustomer extends Component
{
public array $data = [];
private function form(): Form
{
return Form::make()
->setStructure([
Element\Toggle::make('active')
->rules('boolean'),
Element\Divider::make('divider'),
Element\Text::make('name')
->rules(),
Element\Select::make('type')
->options([
'individual' => 'Individual',
'company' => 'Company',
]),
]);
}
public function save(): void
{
$validated = $this->form()->validate($this->data);
// The $validated array contains the validated form data...
// ...and you can save it to the database
Customer::create($validated);
}
public function render(): View
{
return view('livewire.create-customer', ['form' => $this->form()]);
}
}
If you want to create a form that can be reused across multiple components, such as a user registration form, a product creation form, or a feedback form, we recommend creating a dedicated Form class. This approach ensures consistency, maintainability, and easy reuse throughout your application.
namespace App\Forms;
use Mattbit\Zinq\Form\AbstractForm;
use Mattbit\Zinq\Form\Element;
class CustomerForm extends AbstractForm
{
public function structure(): array
{
return [
Element\Text::make('name')
->rules('required|string|min:3|max:255'),
Element\Email::make('email')
->rules('required|email'),
Element\Divider::make('divider'),
Element\Radio::make('preferred_contact')
->options([
'email' => 'Email',
'phone' => 'Phone',
])
->rules('required|string|in:email,phone'),
];
}
}
Now you can simply inject the Customer
form into your Livewire component and render it in the view.
use App\Forms\CustomerForm;
use Livewire\Component;
class CreateCustomer extends Component
{
public array $data = [];
public function save(CustomerForm $form): void
{
$validated = $this->form()->validate($this->data);
// Save the validated data to the database
}
public function render(CustomerForm $form): View
{
return view('livewire.create-customer', ['form' => $form]);
}
}
You can pre-fill form data by setting the initial values in the $data
property of your Livewire component.
public array $data = [
'name' => 'John Doe', // You can manually set the initial value
];
public function mount(Customer $customer): void
{
// Or you can set the initial values dynamically in the mount method
$this->data = $customer->toArray();
}
By default, form elements are displayed vertically. You can display them inline by using the inline
method.
use Mattbit\Zinq\Form\Element;
use Mattbit\Zinq\Form\Form;
...
return Form::make()
...
->inline() // make the form inline
...
->setStructure([
...
]);
use Livewire\Component;
use Mattbit\Zinq\Form\Element;
use Mattbit\Zinq\Form\Form;
class CreateCustomer extends Component
{
public array $data = [];
private function form(): Form
{
return Form::make()
->inline()
->setStructure([
Element\Toggle::make('active')
->label('') // remove the label next to the toggle
->attribute('label', 'Is active'),
Element\Divider::make('divider'),
Element\Text::make('name'),
Element\Select::make('type')
->options([
'individual' => 'Individual',
'company' => 'Company',
]),
]);
}
public function save(): void
{
Zinq::toastSuccess('Customer has been created');
}
public function render(): string
{
return view('livewire.create-customer', ['form' => $this->form()]);
}
}
Form builder automatically generates labels for form elements based on the element's name. You can customize the label by using the label
method.
use Mattbit\Zinq\Form\Element\Text;
Text::make('name')
->label('Full name');
You can set any HTML attribute by using the attribute
method.
use Mattbit\Zinq\Form\Element\Text;
Text::make('name')
->attribute('type', 'number')
->attribute('maxlength', '2');
Zinq Form Builder uses Zinq components to define form elements. You can use all available customizations and features of Zinq components in your forms.
Wrapper around Checkbox component.
use Mattbit\Zinq\Form\Element\Checkbox;
Checkbox::make('active')
->label('Is user active?')
->attribute('label', 'Active')
->rules('accepted')
For checkboxes, the attribute
with the key label
is used to set the label text next to the checkbox.
Divider element is used to separate form elements visually.
use Mattbit\Zinq\Form\Element\Divider;
Divider::make('divider');
Wrapper around Input component with email type.
use Mattbit\Zinq\Form\Element\Email;
Email::make('email')
->rules('required|email')
->label('Email address')
->placeholder('Enter email address');
Wrapper around Radio component.
use Mattbit\Zinq\Form\Element\Radio;
Radio::make('rating')
->attribute('inline', true)
->options([
'good' => 'Good',
'bad' => 'Bad',
'neutral' => 'Neutral',
])
->rules('required');
For your convenience, you can use the optionsFromEnum
method to generate options from an enum class.
Radio::make('rating')
->optionsFromEnum(RatingEnum::class)
->rules('required');
Wrapper around Input component with password type.
use Mattbit\Zinq\Form\Element\Password;
Password::make('password')
->rules('required')
->placeholder('Enter password');
Wrapper around Select component.
use Mattbit\Zinq\Form\Element\Select;
Select::make('type')
->options([
'individual' => 'Individual',
'company' => 'Company',
])
->rules('required')
->label('Customer type');
Wrapper around Input component.
use Mattbit\Zinq\Form\Element\Text;
Text::make('name')
->rules('required')
->label('Full name')
->placeholder('Enter full name');
Wrapper around Textarea component.
use Mattbit\Zinq\Form\Element\Textarea;
Textarea::make('description')
->rules('required')
->label('Description')
->placeholder('Enter description');
Wrapper around Toggle component.
use Mattbit\Zinq\Form\Element\Toggle;
Toggle::make('active')
->label('Is user active?')
->attribute('label', 'Active')
->rules('boolean');
For toggles, the attribute
with the key label
is used to set the label text next to the toggle.