Vlastní validace formuláře před odesláním

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
serten
Člen | 55
+
0
-

Zdravím, mám celkem problém při vytvoření vlastní funkce, která by mi ještě dodatečně kontrolovala formulář. Potřeboval bych, aby se mi ještě před odesláním formuláře provedla kontrola zadaného emailu, jestli se zadaný email už nenachází v databázi. Zkoušel jsem to napsat takto:

public function createComponentAddUser(){
...
$form->onValidate[] = callback($this, 'validateEmail');
$form->onSuccess[] = callback($this, 'addEmpl');

return $form;
}

...

protected function validateEmail($form) {
    $val = $form->getValues();
    $emails = $this->database->table("users")->select("email");
    foreach ($emails as $email) {
    	if ($val["email"] == $email) {
    		$form->addError('Tento email se již v databázi vyskytuje. Zvolte jiný.');
    		return false;
    	}
    }
    return true;
}

Jenže na tu akci onValidate mi to vůbec nereaguje. Mám takovej pocit podle toho co sem si zkoušel, že se to tam ani nedostane. Zkoušel jsem to zapsat i formou

$form->onValidate[] = function($form) {
...
}

jenže to mi taky nefungovalo. Poradil by mi prosím někdo správnej zápis validace před odesláním formuláře? Děkuji za pomoc

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Nemám tušení, proč ti to nefunguje, myslím, že by mělo. Každopádně protože tam stejně využíváš jen email políčko, tak to hoď do klasického validačního rule.

$form->addText('email')
	->addRule(callback($this, 'validateEmail'), 'Tento email se již v databázi vyskytuje. Zvolte jiný.');
protected function validateEmail($input) {
    $value = $input->getValue();
    $emails = $this->database->table("users")->select("email");
    foreach ($emails as $email) {
        if ($value == $email) {
            return FALSE;
        }
    }
    return TRUE;
}

Na zamyšlenou by také bylo refaktorovat tu samotnou validaci :).

return $this->database->table("users")->count('*')->where('email = ?', $value)->fetch() === 0;

Doufám, že tenhle snippet Nette\Database je správně.

JohnyJJP
Člen | 6
+
0
-

Ahoj sertene,

nemáš náhodou problém v tom, že používáš místo správného
\Nette\Application\UI\Form
nekorektní
\Nette\Forms\Form
?

A v tvé metodě validateEmail() nemusíš používat ani return true/false, jelikož podle mého vyzkoušení to nemá na nic vliv a onSuccess/onError callbacky reagují pouze na to zda provedeš přidání erorru via ->addError().
(Pouze tedy pokud neprovádíš unit testování této metody.)

Nebo se mýlím?


V této souvislosti bych taky rád požádal/vyzval někoho, aby nastínil/vysvětlil, proč vůbec je možné/k čemu je dobré nastavit na formulář čtyři různé typy callbacků (onSubmit, onValidate, onSuccess, onError; případně ještě vlastní políčkové validace ->addRule( callback(..)) ) a pak to ideálně doplnil na https://doc.nette.org/cs/forms, kde jsem toto navyčetl (či jinde).

Předem díky. Tuším co bude odpovědí, takže předem předpokladám, že na to budu dale reagovat.