Zprávy z modelu do formuláře
- llook
- Člen | 407
Problém: Z formuláře vyberu data (Form::getValues()) a předám je modelu, například aby si je uložil (DibiTable::insert()). Model zjistí, že přese všechna validační pravidla ta data stále nejsou v pořádku. Jak tuto informaci předat zpět do formuláře?
Momentálně to dělám takhle:
try {
$model->insert($form->getValues());
} catch (Exception $e) {
$form->addError($e->__toString());
}
Jenže tím se přidá taková obecná chyba. Chyba, která nepatří žádné konkrétní položce. Někdy to stačí (když nastane nějaká DibiException), pokud ale v modelu provádím nějakou vlastní složitější validaci, tak mi ta možnost označit určitou položku docela schází.
Napadlo mě, že by se mohla ustanovit nějaká speciální výjimka, která by tyto informace nesla:
public function insert($data)
{
if ($data["field1"] není validní) {
$e = new InputException;
$e->addError("Zpráva", "field1");
throw $e;
}
}
A pak by se to odchytávalo nějak takhle (formulář by si ty chyby uměl z té výjimky vycucnout):
try {
$model->insert($form->getValues());
} catch (InputException $e) {
$form->importErrors($e);
} catch (Exception $e) {
$form->addError($e->__toString());
}
Zatím je to jenom nápad, ale myslím, že něco takového by vůbec nemuselo být špatné. Co myslíte?
- David Grudl
- Nette Core | 8218
Ve „starých“ formulářích bylo možné jako druhý parametr metody addError() uvést název položky, ke které byla zpráva přiřazena. U nových formulářů mají metodu addError() už i jednotlivé položky:
$form['field1']->addError('Not valid');
ad výjimky: něco podobného funguje v nových formulářích. Existuje tu podpora uživatelských validátorů (jako callbacky). Ty v případě negativního výsledku vrátí FALSE.
function myValidator($control, $arg)
{
return $control->value <> 123;
}
$form = new Form();
$form->addText('field', 'Číslo:')
->addRule('myValidator', 'Chybová zpráva');
V PHP 5.3 půjde uživatelské validátory zapisovat i takto:
$form = new Form();
$form->addText('number', 'Číslo:')
->addRule(
function ($control) { return (bool) $control->value % 2; },
'Zadané číslo není dostatečně liché'
);