Formuláře
Validace formulářů
Pravidla na třech úrovních — pole, formulář a pipeline — a která z nich vyhrají, když se neshodnou.
Na této stránce
- Pravidla na úrovni pole
- Typové helpery nejsou validace
- Unikátní hodnoty
- Vlastní validační zprávy
- Pravidla na úrovni formuláře
- Programová validace
- validate()
- getValidationRules()
- Validace v životním cyklu uložení
- Samostatná validace (bez Livewire)
- Podmíněná pravidla
- Podmiňovací helpery
- Live validace
- Zobrazení chyb
Wire Forms poskytuje validaci na třech úrovních: pravidla na úrovni pole, pravidla na úrovni formuláře a programová validace přes Core ValidationPipeline.
Pravidla na úrovni pole
Každé pole deklaruje svá vlastní validační pravidla:
TextInput::make('name') ->required() ->maxLength(255) ->rules(['string', 'regex:/^[a-zA-Z\s]+$/']); TextInput::make('email') ->email() ->required() ->unique(); TextInput::make('age') ->numeric() ->rules(['integer', 'min:18', 'max:120']); Select::make('role') ->required() ->rules('in:admin,editor,viewer');
Typové helpery nejsou validace
->email(), ->numeric(), ->integer(), ->url() a ->tel() jsou typové
presety: nastaví HTML input typ a inputmode, což vybere klávesnici na telefonu a
nechá prohlížeč nabídnout vlastní nápovědu. ->maxLength() a ->minLength()
vykreslí atributy maxlength / minlength. Žádný z nich nepřidává Laravel
pravidlo a žádný nepřežije request, který nepřišel z vašeho formuláře — serveru
se musí zvlášť říct, co přijme:
| Metoda | Co doopravdy dělá | Pravidlo, které dopsat |
|---|---|---|
->email() |
type=email, inputmode=email |
->rules(['email']) |
->numeric() |
type=number, inputmode=decimal |
->rules(['numeric']) |
->integer() |
type=number, inputmode=numeric, step=1 |
->rules(['integer']) |
->url() |
type=url |
->rules(['url']) |
->tel() |
type=tel |
->rules(['regex:…']), nebo použijte PhoneInput |
->maxLength(255) |
maxlength="255" |
->rules(['max:255']) |
->minLength(3) |
minlength="3" |
->rules(['min:3']) |
Helpery, které pravidlem jsou: ->required() (a ->requiredWith()), který
předřadí required, a ->unique(). Některá pole navíc nesou
implicitní pravidla, která si přidají sama, protože jejich stav jinak
zkontrolovat nejde: MoneyInput validuje částku za
formátovaným textem, PhoneInput číslo za předvolbou,
FileUpload nakonfigurované mime typy a velikosti a pole
s options() omezení in: nad vlastními klíči voleb (pokud jste si žádné
nedeklaroval).
Vyprázdněné číselné pole nepotřebuje pravidlo, aby bylo bezpečné.
<input type=number>po vymazání odešle''aTextInputz toho cestou k záznamu udělánull, místo aby do číselného sloupce zapsal prázdný řetězec. Viz Prázdné hodnoty.
Unikátní hodnoty
unique() sestaví laravelovské Rule::unique() z toho, co formulář už zná:
tabulku z navázaného modelu, sloupec z názvu pole a — v režimu editace —
vyloučí editovaný záznam z jeho vlastní kontroly.
TextInput::make('email')->unique(); // unique:users,email, ignoruje tohoto uživateleTextInput::make('email')->unique(ignoreRecord: false); // počítá se každý řádek, včetně tohotoTextInput::make('tax_id')->unique(column: 'vat_number'); // pole, jehož název není sloupecTextInput::make('name')->unique(table: 'companies'); // formulář bez ->model()
Pravidlo vzniká až při validaci, ne při deklaraci schématu. To je podstatné,
protože záznam předává formulářový runtime až poté, co vaše metoda form()
skončila — pravidlo vyhodnocené při deklaraci by neignorovalo nic právě na tom
formuláři, pro který bylo napsáno.
Kontrolu dále zúžíte přes modifyRuleUsing, které dostane pravidlo Unique:
TextInput::make('email') ->unique(modifyRuleUsing: fn (Unique $rule) => $rule->where('team_id', $this->teamId));
Formulář bez ->model() nemá z čeho tabulku odvodit, takže ji předejte: bez
jednoho i druhého vyhodí unique() výjimku FormConfigurationException s
názvem pole.
Vlastní validační zprávy
TextInput::make('name') ->required() ->validationMessages([ 'required' => 'Please enter a name.', 'max' => 'Name is too long.', ]);
Pravidla na úrovni formuláře
Přidejte pravidla na úrovni formuláře, která zahrnují více polí:
Form::make() ->schema([ TextInput::make('password')->password()->required()->rules(['confirmed']), TextInput::make('password_confirmation')->password()->required()->dehydrated(false), ]) ->validationMessages([ 'password.confirmed' => 'Passwords do not match.', ]);
Potvrzovací pole má pravidlo, ale žádný sloupec za sebou, proto je označené
dehydrated(false): účastní se validace a před zápisem záznamu vypadne. Bez
toho by uložení zkusilo nastavit na modelu atribut password_confirmation a
selhalo na chybějícím sloupci — viz
Životní cyklus uložení.
Programová validace
validate()
Zvaliduje stav proti všem posbíraným pravidlům a vrátí zvalidovaná data:
// V Livewire komponentěpublic function save(): void{ $data = $this->form->validate(); // $data obsahuje jen zvalidovaná pole // Při selhání vyhodí Illuminate\Validation\ValidationException}
getValidationRules()
Prohlédnout si posbíraná pravidla bez validace:
$rules = $this->form->getValidationRules();// ['name' => ['required', 'string', 'max:255'], 'email' => ['required', 'email'], ...]
Validace v životním cyklu uložení
Při volání $form->save() proběhne validace automaticky jako první krok:
save()├── 1. Validace ← všechna pravidla polí + formuláře├── 2. mutateDataBeforeSave()├── 3. Plugin hook: form.saving├── 4. beforeSave()├── 5. Perzistence (create/update)├── 6. Uložení relací├── 7. afterSave()├── 8. Plugin hook: form.saved└── 9. Úspěšná notifikace
Pokud validace selže, save() vyhodí ValidationException a kroky 2-9 se přeskočí.
Samostatná validace (bez Livewire)
$form = Form::make() ->schema([ TextInput::make('name')->required(), TextInput::make('email')->email()->required(), ]) ->state(['name' => '', 'email' => 'not-an-email']); try { $data = $form->validate();} catch (ValidationException $e) { $errors = $e->errors(); // ['name' => ['The name field is required.'], 'email' => ['The email field must be a valid email address.']]}
Podmíněná pravidla
Pravidla mohou používat closury pro dynamickou validaci. Closura dostane reaktivní
accessory $get / $set pole, takže pravidla mohou záviset na živém stavu
sousedů. Closura může obalit celou sadu pravidel, nebo sedět uvnitř pole pravidel
jako jedna položka:
TextInput::make('company_name') ->required(fn (callable $get) => $get('type') === 'business') ->rules(fn (callable $get) => $get('type') === 'business' ? ['min:2'] : []); // Closury mohou být i jednotlivé položky v poli pravidel:TextInput::make('slug')->rules([ 'string', fn (callable $get) => $get('type') === 'business' ? 'required' : 'nullable',]);
Podmiňovací helpery
Fluent zkratky vyjadřují nejběžnější mezipolní podmínky bez psaní closury. Každá porovnává živou hodnotu jiného pole; předání pole odpovídá „je jedno z“.
| Metoda | Chování |
|---|---|
->requiredIf('type', 'business') |
required, když se type rovná hodnotě (nebo je jednou z pole) |
->requiredUnless('type', 'individual') |
required, pokud se type nerovná hodnotě |
->requiredWith('company') |
required, když má company neprázdnou hodnotu |
->visibleWhen('type', 'business') |
zobrazeno jen když type odpovídá |
->hiddenWhen('type', 'individual') |
skryté když type odpovídá |
->disabledWhen('locked', true) |
disabled když locked odpovídá |
Select::make('department') ->visibleWhen('type', 'business') ->requiredIf('type', 'business');
visibleWhen / hiddenWhen / disabledWhen jsou sdílené foundation helpery,
takže jsou dostupné i na sloupcích, filtrech a akcích. Na povrchu bez kontextu
živého stavu jsou no-op (nechají komponentu viditelnou/zapnutou).
Skrytá pole se během validace přeskočí, takže pravidlo required na poli, které
uživatel aktuálně nevidí, nikdy nezablokuje odeslání.
Live validace
Ve výchozím stavu formulář validuje jako celek při odeslání. Zapněte poli per-field validaci během reaktivního roundtripu, aby se jeho chyba objevila (a zmizela), jak uživatel interaguje, bez označení zbytku formuláře:
TextInput::make('email')->email()->required()->validateLive(); // při každé změněTextInput::make('name')->required()->validateOnBlur(); // když focus odejde
validateLive() zapne live() a validateOnBlur() zapne live.blur vazbu, takže
server vidí změnu a obnoví jen položku error bagu daného pole. Podmiňovací helpery
jako requiredIf() se ctí i live, protože čtou aktuální stav sousedů při každém
roundtripu. Live validace funguje i pro pole uvnitř Repeater položek — pole
každého řádku validuje proti své vlastní item path (např. data.contacts.0.email).
Live validace kontroluje jedno pole po druhém. Pravidla, která porovnávají surové hodnoty sousedů přes řetězcovou syntax Laravelu (např.
required_if:other,value), je nejlepší validovat při odeslání; pro reaktivní ekvivalent použijterequiredIf().
Zobrazení chyb
Validační chyby se automaticky navážou na Livewire error bag a zobrazí se vedle příslušných polí. Prefix state path se aplikuje automaticky:
// Když statePath('data') a pole je TextInput::make('name')// Klíč chyby: data.name// Livewire zobrazí: @error('data.name')
V Blade není potřeba žádné manuální vykreslování chyb.