AppForm a událost

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

určitě to bude blbost, ale koukám na to už den a pro oči asi nevidím … mám control

class LoginForm extends Control {

        var $loginForm;
        var $template;

        public function __construct() {
            parent::__construct();
	}


        public function createComponentLoginForm() {
                $form = new AppForm;
                $form->addText('username', 'Uživatelské jméno:')
                        ->addRule(Form::FILLED, 'Zadejte uživatelské jméno.');
                $form->addPassword('password', 'Heslo:')
                        ->addRule(Form::FILLED, 'Zadej heslo.');
                $form->addSubmit('login', 'Přihlásit')->onClick(array($this, 'loginFormSubmitted'));
                $form->onSubmit[] = array($this, 'loginFormSubmitted');
                $form->addProtection('Prosím přihlašte se znovu.');
                return $form;
        }

        public function loginFormSubmitted(AppForm $form) {
                try {
                        echo "jsem v loginFormSubmitted !!";
                        exit;
                        //prihlasovani
                } catch (AuthenticationException $e) {
                        $form->addError($e->getMessage());
                }
        }

        public function render() {
                $this->template = $this->createTemplate();
                $this->template->setFile(dirname(__FILE__)."/LoginComponent.phtml");
                $this->template->form = $this['loginForm'];
                $this->template->render();
        }
}

ale nikdy mi to nepřejde do loginFormSubmitted ošetření odeslání formuláře – ve zdrojáku stránky je ve form action url a akce „do=loginForm-loginForm-submit“ …
neuvidí to někdo hned?
Dík

Editoval kravčo (30. 8. 2009 14:37)

vlki
Člen | 218
+
0
-

Bude to nejpravděpodobněji tím, že nemáš komponentu LoginForm správně zaregistrovanou ve chvíli zpracování parametrů.

Není to tím, že překrýváš konstruktor toho Controlu? Že se správně nezaregistruje do stromu komponent. Btw. jak ho vytvářiš LoginForm v presenteru?

Mimochodem, proč je u definování submit tlačítka ta událost onClick, když máš nastavený stejný handler při události onSubmit?

jannemec
Člen | 78
+
0
-

v presenteru mám

       public function actionLogin($backlink) {

           $user = Environment::getUser();
           $this->template->loginForm = $this->getComponent("loginForm")->render();
atd ...

překrývám ten constructor … dělal jsem tam ještě neco jiného, ale to jsem zaremoval a volám constructor předka …
a ty události – původně tam bylo více tlačítek, taky jsem je odstranil, aby to bylo co nejjednodušší.

Editoval kravčo (30. 8. 2009 14:37)

kravčo
Člen | 721
+
0
-

Viď zápis kódu v tomto fóre

Keď ti ide o komponent „loginForm“, ktorý je formulárom, mal by si správne zapísať

class MyPresenter extends MyBasePresenter
{
    // ...

    protected function CreateComponentLoginForm()
    {
        // vytvorenie formulára
    }

    public function loginFormSubmitted()
    {
    }

    // ...
}

Ak ti ide o vlastnú šablónu, lepším riešením by bolo:

class LoginForm extends Control
{
    public function __construct()
    {
        parent::__construct();

	$form = new AppForm;
        // vytvorenie formulára
        $this->addComponent($form, 'form');
    }
}

Namiesto pridávania obsahu formulára do šablóny môžeš použiť makro {control ...}, ktoré ti komponentu vykreslí do šablóny…

šablóna pre MyPresenter

<!-- meno komponentu v rámci prezenteru MyPresenter -->
{control loginForm}

šablóna pre LoginForm

<!-- meno komponentu v rámci controlu LoginForm -->
{control form}
Panda
Člen | 569
+
0
-

Komponenta by se správně měla vykreslovat až v šabloně pomocí makra {widget}, případně přímým voláním funkce render:

{control loginForm} {* nebo *} {!$component['loginForm']->render()}

Odpadne pak řádek $this->template->loginForm = $this->getComponent("loginForm")->render(); z presenteru, který má to nebezpečí, že signál (tzn. odeslání formuláře) by se zpracoval až po vykreslení formuláře a uživateli se nezobrazily případné chyby připojené k formuláři.

Řádek

$form->addSubmit('login', 'Přihlásit')->onClick(array($this, 'loginFormSubmitted'));

nepřiřazuje submitu událost, nýbrž jí volá s parametrem array($this, 'loginFormSubmitted').

//Doplnění: u překrývání konstruktorů ještě pozor na parametry, protože už v konstruktoru lze komponentu připojit k rodiči.

Editoval Panda (30. 8. 2009 14:59)

jannemec
Člen | 78
+
0
-

Jj. předělal jesm template na

{control loginForm}

resp

{control form}

a přesunul jsem vytvoření šablony do konstruktoru, ale žádná změna … co se tedy volá za metodu, pokud je v URL
admin/?do=loginForm-form-submit
tedy presenter AdminPresenter (admin/) obsahující komponentu (Control) loginForm obsahující komponentu (AppForm) form?

Editoval jannemec (30. 8. 2009 20:46)

jannemec
Člen | 78
+
0
-

aha, tak chyba bude v routování – když jsem dal

$router[] = new SimpleRouter('Admin:default');

tak to proběhlo bez problému … jak to ale dostat do

$router[] = new Route(BASE_URI . 'admin/<action>', array(
            'presenter' => 'Admin'
            , 'action' => 'default'
    ));

koukám, že už jsem při večeru pěkně zmatený…

Editoval jannemec (30. 8. 2009 20:46)

Honza Marek
Člen | 1664
+
0
-

Ta konstanta BASE_URI se mi moc nezdá. Zkus to bez toho.

Taky bych si nedovolil přepsat konstruktor Controlu bez parametrů $parent a $name, ale v tom chyba být nemusí.

jannemec
Člen | 78
+
0
-

BASE_URI jsem odstranil, konstruktor taky a … furt to samé. Asi zkusím štěstí zítra – ale dík všem za motivaci.

Ondřej Mirtes
Člen | 1536
+
0
-

Já osobně bych se vykašlal na dělání formuláře – komponenty jako potomka Control a udělal bych přímo potomka AppForm. Odpadne jedna zbytečná šablona navíc a bude stačit jedna továrnička v presenteru.

class MyForm extends AppForm {
	public function __construct(IComponentContainer $parent = NULL, $name = NULL) {
		parent::__construct($parent, $name);

		//plnění formulářů
		$this->addText...;
	}

}

(jestli nejde AppForm použít jako komponenta, tak bych mu dal ještě implements IComponent.

jannemec
Člen | 78
+
0
-

tak předka LoginForm samozřejmě změnit mohu … jde o to, že by měl nakonec obsahovat více formulářů. Ale co mě mate víc je, že to s SimpleRouter funguje bez problémů, ale jakmile dám

$router[] = new Route('admin/<action>', array(
            'presenter' => 'Admin'
            , 'action' => 'default'
    ));

tak to ten signál dál nepředá. Jakoby form v tu chvíli ještě onu obsluhu neměl definovanou. Jenže opět, jaký na to má vliv změna routování?
JN