Custom

# Introduction

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.

# Usage

To integrate a form into a Livewire component, you need to:

  1. Define the form structure using the Form class and its Element components,
  2. Create the form data property in your Livewire component,
  3. Handle the form submission using a method in your Livewire component.
admin
Create customer


 
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()]);
    }
}

# Validation

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.

admin
Create customer


 
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()]);
    }
}

# Reusable forms

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'),

        ];
    }
}

# Usage

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]);
    }
}

# Customization

# Pre-filling form data

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();
}

# Inline elements

By default, form elements are displayed vertically. You can display them inline by using the inline method.

admin
Create customer


 
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()]);
    }
}

# Label

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');

# Attributes

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');

# Elements

Zinq Form Builder uses Zinq components to define form elements. You can use all available customizations and features of Zinq components in your forms.

# Checkbox

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

Divider element is used to separate form elements visually.

 
use Mattbit\Zinq\Form\Element\Divider;

Divider::make('divider');

# Email

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');

# Radio

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');

# Password

Wrapper around Input component with password type.

 
use Mattbit\Zinq\Form\Element\Password;

Password::make('password')
    ->rules('required')
    ->placeholder('Enter password');

# Select

Wrapper around Select component.

 
use Mattbit\Zinq\Form\Element\Select;

Select::make('type')
    ->options([
        'individual' => 'Individual',
        'company' => 'Company',
    ])
    ->rules('required')
    ->label('Customer type');

# Text

Wrapper around Input component.

 
use Mattbit\Zinq\Form\Element\Text;

Text::make('name')
    ->rules('required')
    ->label('Full name')
    ->placeholder('Enter full name');

# Textarea

Wrapper around Textarea component.

 
use Mattbit\Zinq\Form\Element\Textarea;

Textarea::make('description')
    ->rules('required')
    ->label('Description')
    ->placeholder('Enter description');

# Toggle

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.