Více formulářů a isSubmitted()
- i.magine
- Člen | 81
Ahoj,
v dokumentaci jsem nasel navod jak udelat vice formularu v jednom
presenteru:
class SomePresenter extends BasePresenter
{
public function renderDefault()
{
$this->template->formA = $this['formA'];
$this->template->formB = $this['formB'];
}
...
public function formASubmitted(AppForm $form)
{
// zpracování formA
Debug::dump($form->getValues());
}
public function formBSubmitted(AppForm $form)
{
// zpracování formB
Debug::dump($form->getValues());
}
protected function createComponentFormA()
{
$form = new AppForm;
// ... definice formuláře A
$form->onSubmit[] = array($this, 'formASubmitted');
return $form;
}
protected function createComponentFormB()
{
$form = new AppForm;
// ... definice formuláře B
$form->onSubmit[] = array($this, 'formBSubmitted');
return $form;
}
}
}
Problém začíná, když chci otestovat jestli je jeden z formularu submitted metodou isSubmitted() – tzn. ne jestli je validni ale jestli nekdo tuknul na submit – tak mi to vyhodi tuhle hlasku:
Form is not anchored and therefore can not determine whether it was submitted.
Cosi o ukotvení – nevěděl by někdo co to vlastně znamená a jak by se dalo zjistit jestli je teda submitted?
Diky
- Ondřej Mirtes
- Člen | 1536
Jakou máš revizi Nette? Zkoušel jsi nejnovější vývojovou?
Kde voláš to isSubmitted?
Anchored znamená, že je formulář připojen ke stromu komponent, což se
děje buďto v momentě return $form
v jeho továrničce anebo
když uvedeš konstruktor ve tvaru AppForm($this, 'nazevFormu');
.
Pokud není takto připojen, nelze na něm provádět některé operace,
protože jen tak „visí“ ve vzduchu a není nikde „ukotven“.
Ale nějakou dobu zpátky prošly formuláře dost velkými změnami, co se tohoto týče, které umožnily např. nastavování defaultních hodnot bez jeho ukotvení, což dřív možné nebylo. Proto doporučuji zkontrolovat, jestli máš nejnovější revizi a ne nějakou starou stable.
- i.magine
- Člen | 81
No stahoval jsem to nedávno, takže je to verze:
Nette Framework 0.9.2 (revision b9fd602 released on 2009–11–12)
O to připojení už jsem se pokoušel, ale vyhodí to hlášku:
The signal receiver component ‚formLogin‘ is not found.
– což úplně nechápu, protože formLogin mám jak createComponentFormLogin, tak formLoginSubmitted. Budu rád za každou radu.
- Ondřej Mirtes
- Člen | 1536
Ukaž kód. Podle toho, co píšeš, by to vyhazovat nemělo.
A v 0.9.2 už ty novější formuláře myslím jsou.
- i.magine
- Člen | 81
Takže kód je následující – je to přes defaultPresenter celý volaný, ted to vyhazuje chybu o tom ze komponenta neexistuje a to na tyhle radce:
$this->template->formLogin = $this[‚formLogin‘];
Kód:
abstract class BasePresenter extends /*Nette\Application\*/Presenter
{
public function beforeRender(){
$user=Environment::getUser();
if (!$user->isAuthenticated()){
$this->createForms();
}
}
public function createForms(){
$this->template->formLogin = $this['formLogin'];
$this->template->formForgot = $this['formForgot'];
}
/*Vytvoříme formulář na přihlášení*/
public function createComponentFormLogin()
{
$form = new AppForm($this, "FormLogin");
$form->addText('username', 'Přezdívka:') ->addRule(Form::FILLED, 'Zadejte přezdívku');
$form->addPassword('password', 'Heslo:') ->addRule(Form::FILLED, 'Zadejte heslo');
$form->addImage('login', 'images/btn_logj.png', 'Přihlásit');
$form->addProtection('Prosím odešlete tento formulář znovu (Relace vypršela)');
//Když je validní
$form->onSubmit[] = array($this, 'formLoginSubmitted');
if ($form->isSubmitted(){
//Submitován
}
return $form;
}
/*Pokud je odeslán - přihlásíme nebo hodíme chybu*/
public function formLoginSubmitted(AppForm $form)
{ $this->switchForms("login");
try {
$user = Environment::getUser();
$user->setAuthenticationHandler(new Users);
$user->authenticate($form['username']->getValue(), $form['password']->getValue());
$this->redirect('default');
} catch (AuthenticationException $e) {
$form->addError($e->getMessage());
}
}
/*Druhej formulář je obdobně*/
}
Díky za pomoc
- Ondřej Mirtes
- Člen | 1536
Tato logika do továrničky nepatří no.
Pro zavolání nějaké metody při invalidním submitu slouží pole onInvalidSubmit:
$form->onInvalidSubmit[] = array($this, 'formSubmittedInvalid');
- i.magine
- Člen | 81
Super! Něco takovýho jsem hledal. Měl bych ještě menší dotaz. Rozhod jsem se celý formulář přesunout do komponenty, jenomže když odešlu jeden z formulářů tak hlásí:
The signal receiver component ‚Login-formForgot‘ is not found. (Login je nazev komponenty)
Jakoby skoro nešlo pod komponentou rozjet dva formuláře najednou.
Díky
- Filip Procházka
- Moderator | 4668
a vytváříš vůbec komponentu správně?
public function createComponentLoginForm($name)
{
$form = new AppForm($this, $name);
$form->addText(...
$form->onSubmit[] = array($this, 'loginFormSubmited');
}
public function loginFormSubmited(AppForm $form)
{
debug::dump($form->getValues());
}
mimochodem pokud takto vytvoříš komponetu, nemusíš jí předávat
templatě v proměnné stačí v templatě zavolat
{control loginForm}
, ale bacha je to citlivý na velikost písmen,
hodně citlivý. První musí být dycky malé a ostatní přesně podle názvu
čili komponenta LoginForm
bude volána jako
loginForm
. Pokud chceš ovlivnit vykreslení, doporučuju
jednoduchou podmínku v templatě, což bude asi nejjednodužší.
if(!$user->isAuthenticated()){
$this->template->loginForm = True;
} else {
$this->template->loginForm = False;
}
Templata:
{if $loginForm}{control loginForm}{/if}
Editoval HosipLan (14. 12. 2009 17:25)
- i.magine
- Člen | 81
No prave ze ja jsem to udelal jako komponentu, kterou jsem takhle vlozil do BasePresenteru, podle návodu v quickstartu: https://doc.nette.org/cs/quickstart
$this->login=new Login($this, 'Login');
$this->template->login=$this->login;
No a kdyz udelam submit tak me to chce hodit na ?do=Login-formLogin-submit a vyhodi vyse zminenou hlasku.
- Filip Procházka
- Moderator | 4668
protože to je zastaralý přístup, udělej tu komponentu jak jsem ti napsal já a bude to samo zázračně fungovat
- Filip Procházka
- Moderator | 4668
Pokud jsem to dobře pochopil tak takhle nějak :)
class AuthAppForm extends AppForm
{
public function renderUserInfo()
{
// ...
}
}
<!-- loginForm komplet -->
{control loginForm}
<!-- volá renderUserInfo() -->
{control loginForm:userInfo}