Validace formuláře – výpis form hodnoty do message
- Sentinel
- Člen | 5
!! Koukám že jsem to založil do špatné skece, .. jestli je to možné, přesuňte to prosím do sekce Forms
Dobrý den,
snažím se proniknout do nette, vytvářím jednoduchý form. Odeslání
e-mailu do databáze. Před uložením chci provézt kontrolu, jeslti záznam
existuje. Pokud existuje rád bych vypsal vyplněný údaj do chybové hlášky,
např. Email aaa@bbb.ccc byl
již zaregistrován. Používám následující kód, ale domnívám se, že
určitě existuje efektivnejší řešení.
<?php
class RegisterForm extends AppForm {
public function __construct($parent = NULL, $name = NULL) {
parent::__construct($parent, $name);
$this->addText('email', 'E-mail')
->addRule(Form::FILLED, 'Nevyplnili jste e-mail')
->addRule('RegisterForm::emailValidator', 'Email %s byl již registrován.', $this['email']);
$this->addText('nick', 'Nick')->addRule(Form::FILLED, 'Nevyplnili jste nick');
$this->addSubmit('save', 'Registrovat')
->setValidationScope(TRUE)
->onClick[] = array($this, 'RegisterUser');
}
public static function emailValidator($control, $arg) {
foreach ($control->rules as $rule) {
$operationName = split('::', $rule->operation);
if (count($operationName) > 1) {
if ($operationName[1] == 'emailValidator') {
$rule->message = sprintf($rule->message, $arg->value);
}
}
}
// tady bude nejaká kontrola, ted vzdy vratim false
return false;
}
...
}
?>
Metoda emailValidator($control, $arg) má v sobě cyklus, kdy procházím rules a když se jedná o validaci ulozim arg hodnotu do zprávy. V případě, že pouze vrátím false (bez foreach cyklu), hodnota z textboxu email se mi nezobrazí. Jde tedy pouze o zobrazení hodnoty z formuláře do zprávy.
Otázka tedy zní: jak to napsat efektivně?
Děkuji :)
Editoval Sentinel (14. 6. 2009 15:54)
- lucass
- Člen | 89
jasir napsal(a):
Mě stačí jen vrátit FALSE a nic neprocházet:
<?php public static function emailValidator($control,$arg) { return FALSE; } ?>
Hláška se vypíše. Registraci formuláře jsem dal do
actionDefault()
v presenteru.
Samotná validace je ok, hlášku to vrátí, ale bez nahrazení té konkrétní hodnoty %s za $this[‚email‘], tj. v pseudopřepisu: Email %s byl již registrován. → Email $this[‚email‘]->value byl již registrován, např. tedy Email aaa@bbb.ccc byl již registrován. Jestli jsem to napsal srozumitelněji.
- jasir
- Člen | 746
Samotná validace je ok, hlášku to vrátí, ale bez nahrazení té konkrétní hodnoty %s za $this[‚email‘], tj. v pseudopřepisu: Email %s byl již registrován. → Email $this[‚email‘]->value byl již registrován, např. tedy Email aaa@bbb.ccc byl již registrován. Jestli jsem to napsal srozumitelněji.
Teď mi došlo o co ti jde. A nevím jak na to :)
Ideální by asi bylo, kdyby Nette umožňovalo nějaký placeholder, něco
jako:
...->addRule('RegisterForm::emailValidator', 'Email %value% byl již registrován.');
.
Místo %value%
by se pak vložila aktuálně odeslaná hodnota.
Editoval jasir (15. 6. 2009 12:06)
- vlki
- Člen | 218
Podpora pro toho v pravidlech je. Konkrétně je to řešeno pomocí funkce vsprintf. Viz API – https://api.nette.org/…les.php.html#194
Myslím, že stačí argument pravidla dát do pole…
<?php
...
->addRule('RegisterForm::emailValidator', 'Email %s byl již registrován.', array($this['email']));
...
?>
- jasir
- Člen | 746
vlki napsal(a):
Podpora pro toho v pravidlech je. Konkrétně je to řešeno pomocí funkce vsprintf. Viz API – https://api.nette.org/…les.php.html#194
Myslím, že stačí argument pravidla dát do pole…
Nene, to nestačí. Odeslaná hodnota formulářového prvku ještě není při vytváření formuláře známa.
- vlki
- Člen | 218
Jojo, už to taky vidím. Řešením by byl placeholder.
A nešlo by tu hodnotu předat odkazem? Vyžadovalo by to úpravu
v útrobách Nette, ale pokud by se $this['email']->value
předalo odkazem, tak v okamžiku validace (kdy se chybová zpráva vytváří)
už bude hodnota formulářového prvku taková, jakou potřebujeme
testovat.
- _Martin_
- Generous Backer | 679
No, zatím lze použít řešení, kdy chybu hlásí samotný validátor, tj.:
static function emailValidator(IFormControl $control)
{
$email = $control->value;
if (emailExists($email)) { // nějaká vlastní funkce kontrolující existenci emailu
$control->addError("Email $email byl již registrován.");
return FALSE;
} else {
return TRUE;
}
}
Edit: ještě jsem si pozorněji prohlídnul tvůj kód a říkám si, zda by nešlo následující:
public static function emailValidator(IFormControl $control, $arg)
{
foreach ($control->rules as $rule) {
$operationName = split('::', $rule->operation);
if (count($operationName) > 1) {
if ($operationName[1] == 'emailValidator') {
$rule->message = str_replace('%value%', $control->value, $rule->message);
$rule->message = sprintf($rule->message, $arg->value); // pro případné další parametry
}
}
}
// ...
}
Editoval _Martin_ (15. 6. 2009 14:19)
- David Grudl
- Nette Core | 8228
jasir napsal(a):
Nene, to nestačí. Odeslaná hodnota formulářového prvku ještě není při vytváření formuláře známa.
Tohle už by mělo aktuálně fungovat, během vytváření formuláře
zpravidla je hodnota známa. Nicméně zkusil jsem experimentálně přidat
podporu pro placeholder %value
, ale samozřejmě to nebude fungovat
v JavaScriptu.