Publikováno
· Autor: Zdeněk Hejzlar · 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::classdrží 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.