Více formulářů a isSubmitted()

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

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

protože to je zastaralý přístup, udělej tu komponentu jak jsem ti napsal já a bude to samo zázračně fungovat

i.magine
Člen | 81
+
0
-

super… opravdu to jede :-), jenom jedna věc: je takhle mozny volat i jinou cast komponenty – napriklad bych chtel tu komponentu trochu predelat a pridat tam jeste renderUserInfo() coz by ukazovalo stav uzivatele po zalogovani (avatar, tlacitko odhlasit, … atd..).

redhead
Člen | 1313
+
0
-

pak

{control comp:userInfo}

( bude volat renderUserInfo() )

Editoval redhead (14. 12. 2009 19:26)

Filip Procházka
Moderator | 4668
+
0
-

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}
i.magine
Člen | 81
+
0
-

Paráda, to jsem myslel.