MadValidationException
Validação Illuminate pura com asInline, asModal, asToast, asDetailForm.
Mad\Form\MadValidationException é lançada por
$this->form->validate($rules) quando algum campo falha — as regras são
Illuminate puro (required|string|max:255, etc.), processadas
via Mad\Form\MadValidator sobre o Illuminate\Validation\Factory
nativo. Não existe um DSL de validação próprio do MAD — se você já validou algo num
FormRequest do Laravel, as regras são exatamente as mesmas.
Esta classe expõe hoje cinco métodos:
getErrors(), asInline(), asModal(),
asToast() e asDetailForm(). Não existem (mais)
asResponse(), first(), has(),
get() nem firstField() — se você viu esses métodos em
material antigo, foram descontinuados/renomeados nesta versão.
Regras — Illuminate puro
A chave da regra aceita o formato 'campo|Label' — o label depois do
| é extraído automaticamente e usado nas mensagens de erro (tem prioridade o
parâmetro $attrs explícito, se informado):
// Regras Illuminate puras — exatamente as mesmas usadas em FormRequest/Validator
// do Laravel. Sem DSL de validação próprio do MAD.
$this->form->validate([
'nome|Nome' => 'required|string|max:255', // 'campo|Label' extrai o label
'cpf' => 'required|cpf', // regra custom registrada no projeto
'idade' => 'nullable|integer|min:18',
'documentos' => 'required|array|min:1',
]);
Assinatura completa: $form->validate(array $rules, array $messages = [], array $attrs = []): static
— retorna o próprio form (encadeável) quando tudo passa, e lança
MadValidationException($errors, array_keys($rules)) quando não. Se
$attrs vier vazio, o MAD cai nos auto-labels: os rótulos que o
MadWire coletou do HTML e enviou em mad_labels — ou seja, na maioria dos casos
a mensagem já sai com o label visível do campo sem você declarar nada.
Padrão típico — try/catch no onSave
use Mad\Form\MadValidationException;
use Mad\Http\MadResponse;
public function onSave(): MadResponse
{
try {
$this->form->validate([
'nome|Nome' => 'required|string|max:255',
'email|Email' => 'required|email',
'valor' => 'required|numeric|min:0',
]);
$data = $this->form->getData();
$produto = Produto::findOrNew($this->registroId);
$produto->fill($data->toArray());
$produto->save();
return MadToast::success('Salvo!')->closeDrawer();
} catch (MadValidationException $e) {
return $e->asInline(); // erros inline nos campos (padrão recomendado)
} catch (\Throwable $e) {
return MadMessage::error('Erro ao salvar', $e->getMessage());
}
}
API
| Método | Retorno | Descrição |
|---|---|---|
getErrors() | array | Mapa ['campo' => 'mensagem'] de todos os erros. |
asInline($toast = 'Corrija os erros antes de continuar.') | MadResponse | Marca cada campo com erro inline + toast de aviso ($toast = '' omite o toast). Padrão recomendado. |
asModal($title = 'Erros encontrados') | MadResponse | Lista todos os erros num dialog (MadResponse->alert(), tipo error). |
asToast($prefix = '') | MadResponse | Só o primeiro erro, como toast de aviso — prefixo opcional. |
asDetailForm($dfName = '') | MadResponse | Erros escopados a um detail-form (dfFieldError()) — evita colidir com campo de mesmo nome no form master. Sem $dfName, usa o nome passado no 3º argumento do construtor. |
Apresentações disponíveis
catch (MadValidationException $e) {
return $e->asInline(); // marca cada campo + toast de aviso (padrão)
}
catch (MadValidationException $e) {
return $e->asModal('Dados inválidos'); // lista de erros num dialog
}
catch (MadValidationException $e) {
return $e->asToast(); // só o primeiro erro, como toast de aviso
}
catch (MadValidationException $e) {
return $e->asDetailForm(); // erros escopados a um detail-form (sem colidir
// com campo de mesmo nome no formulário master)
}
O que asInline() faz, em detalhe
// asInline() faz três coisas:
// 1. clearFieldError() em TODOS os campos que passaram pela validação
// (limpa erros de uma tentativa anterior, mesmo nos que agora passaram)
// 2. fieldError($campo, $msg) em cada campo que falhou desta vez
// 3. toast de aviso (texto customizável; '' para omitir)
return (new MadValidationException($errors, $camposValidados))->asInline('Verifique os campos destacados.');
O primeiro parâmetro do construtor é $errors; o segundo,
$validatedFields, é a lista de TODOS os campos que passaram pela validação
(usada por asInline() para limpar erros de campos que falharam numa tentativa
anterior mas passaram nesta) — $this->form->validate() já popula isso
sozinho a partir das chaves das rules.
Lançar manualmente — validação cross-field
Para regras de negócio que envolvem múltiplos campos (não cabem numa rule
isolada do Illuminate), valide o básico via $this->form->validate() e
lance a exceção manualmente para o restante:
use Mad\Form\MadValidationException;
public function onSave(): MadResponse
{
try {
$this->form->validate(Pedido::rules($this->registroId));
$data = $this->form->getData();
// Validação cross-field — não cabe numa rule isolada do Laravel
$errors = [];
if ($data->valor_promo > 0 && $data->valor_promo >= $data->valor) {
$errors['valor_promo'] = 'Valor promocional deve ser menor que o valor.';
}
if ($data->dt_fim < $data->dt_ini) {
$errors['dt_fim'] = 'Data fim deve ser posterior à data início.';
}
if ($errors) {
throw new MadValidationException($errors);
}
// ... persistir ...
return MadToast::success('Salvo!');
} catch (MadValidationException $e) {
return $e->asInline();
}
}