Vícekrokový formulář v Laravelu s Filament Forms

Jak v Laravelu postavím vícekrokový poptávkový formulář přes Filament Wizard — kroky, živá validace, podmíněná pole a uložení s notifikací.
Publikováno 14.07.2026

Vícekrokový formulář v Laravelu s Filament Forms

Publikováno

· Autor: · Pod kapotou · 2 min čtení

Obsah článku

Dlouhý formulář o dvaceti polích lidi odradí. Rozdělím ho do několika kroků a průchodnost poptávky vyskočí — u řemeslných služeb je to rozdíl mezi vyplněným a zavřeným oknem. V Laravelu na to používám Filament a jeho komponentu Wizard. Ukážu, jak takový formulář poskládám.

Kostra wizardu

Wizard je jen kontejner na kroky (Step). Každý krok má vlastní schéma polí a Filament mezi kroky sám validuje — dál se člověk neposune, dokud aktuální krok nesedí.

use Filament\Schemas\Components\Wizard;
use Filament\Schemas\Components\Wizard\Step;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;

Wizard::make([
    Step::make('Nemovitost')
        ->schema([
            Select::make('property_type')
                ->label('Typ nemovitosti')
                ->options(PropertyType::class)
                ->required()
                ->live(),
        ]),
    Step::make('Rozsah')
        ->schema([
            TextInput::make('chimney_count')
                ->label('Počet komínů')
                ->numeric()
                ->minValue(1)
                ->required(),
        ]),
    Step::make('Kontakt')
        ->schema([
            TextInput::make('email')->email()->required(),
            TextInput::make('phone')->tel()->required(),
        ]),
])

Podmíněná pole podle předchozího kroku

Klíčová věc u poptávek — ptát se jen na to, co dává smysl. Přes Get si přečtu hodnotu z dřívějšího pole a pole zobrazím jen tehdy, když má smysl. Proto je property_type označený jako ->live(): Filament po jeho změně překreslí schéma.

use Filament\Schemas\Components\Utilities\Get;

TextInput::make('company_name')
    ->label('Název firmy')
    ->required()
    ->visible(fn (Get $get): bool => $get('property_type') === 'business'),

Uživatel firemního objektu dostane pole na IČO, běžný člověk ne. Formulář zůstává krátký a přesto sesbírá kvalifikovaný lead.

Uložení a notifikace

Po posledním kroku data z celého wizardu spadnou do jednoho pole. Uložím model, odešlu e-mail a dám vědět notifikací — všechno v jedné akci.

use Filament\Notifications\Notification;

public function submit(): void
{
    $data = $this->form->getState();

    $inquiry = Inquiry::create($data);
    Mail::to(config('mail.inquiries'))->queue(new InquiryReceived($inquiry));

    Notification::make()
        ->title('Poptávka odeslána')
        ->success()
        ->send();
}

E-mail posílám přes frontu (queue), takže odeslání formuláře je okamžité a doručení řeší worker na pozadí — uživatel nečeká na SMTP.

Na co si dát pozor

  • Validace patří do polí, ne až za formulář. required(), email(), numeric() hlídají krok po kroku, ne až na konci.

  • Stav mezi kroky. Pole s podmíněnou viditelností musí záviset na poli s ->live(), jinak se překreslení nespustí.

  • Enumy místo natvrdo psaných options. PropertyType::class drží hodnoty na jednom místě a nedovolí překlep.

Závěr

Vícekrokový formulář přes Filament Wizard je pár desítek řádků a výrazně zvedne konverzi poptávky. Přesně tenhle přístup jsem použil na webu kominické firmy — detail najdete mezi projekty. Když do formuláře přidáte živou validaci volných termínů, hodí se svižný web a čistá struktura dat, kterou pak zpřístupníte přes REST API. Řešíte podobný formulář? Napište mi.