Zpracování formuláře (v kompontě)

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

Jak můžu zpracovat formulář vytvořený v komponentě? Zkusil jsem do deklarace formuláře přidat:

<?php
    $form->onSubmit[] = array($this, 'eventMyForm1Click');
?>

a vytvořit (také ve třídě s komponentou) metodu:

<?php
    public function eventMyForm1Click(AppForm $form)
    {
        // ... nejake akce po odeslani formu

        $this->redirect('Default:');
    }
?>

Ovšem to nejde, zatím nechápu proč, a vlastně ani vnitřní vztahy při zpracování signálů v komponentách (jestli to říkám správně).

jasir
Člen | 746
+
0
-

A co to hlásí? Takhle se to dělá…

grogy
Člen | 147
+
0
-

Právě že vůbec nic. JS validace (scripty) se samozřejmě na klienta zašlou, ale po odeslání se nic neděje. – Ale měla by se stránka přesměrovat.

Ještě zmíním, že komponenta je tvořena v továrničce (class KontaktFormControl extends Control …) – v tom může být ten zakopaný pes.

Ondřej Mirtes
Člen | 1536
+
0
-

Ukaž celý zdroják té komponenty.

Nezaložils náhodou jen Form namísto AppForm?

grogy
Člen | 147
+
0
-

Ne, na to mě už někdo upozorňoval, tak vím, že pro componenty i prezenter je AppForm. Ps. Nesmějte se mi za tu komponentu, dělám ji prvně! xD

<?php
class KontaktFormControl extends Control
{
    private $form;

    public function  createMyForm()
    {
        $form = new AppForm;
        $form->addText("jmeno", "*Jméno a příjmení:", 40)
             ->addRule(Form::FILLED, "Prosím vyplňte jméno");
        $form->addText("email", "*E-mailová adresa:", 40)
             ->addRule(Form::FILLED, "Prosím vyplňte váš email")
             ->addRule(Form::EMAIL, "Email v nesprávném tvaru");
        $form->addImage("odeslat", "/images/button-odeslat.gif", "Odeslat");
        $form->onSubmit[] = array($this, 'eventMyForm1Click');

        $this->form = $form;
    }

    public function eventMyForm1Click(AppForm $form)
    {
        // ... nejake akce po odeslani formu

        $this->redirect('Default:');
    }

    public function render()
    {
        $template = $this->template;
        $template->setFile(dirname(__FILE__) . '/KontaktFormControl.phtml');
        $template->form = $this->form;
        $template->render();
    }
}
?>
jasir
Člen | 746
+
0
-

Zkus tohle:

<?php

class KontaktFormControl extends Control
{
     public function  createComponentMyForm()
     {
         $form = new AppForm;
         $form->addText("jmeno", "*Jméno a příjmení:", 40)
              ->addRule(Form::FILLED, "Prosím vyplňte jméno");
         $form->addText("email", "*E-mailová adresa:", 40)
              ->addRule(Form::FILLED, "Prosím vyplňte váš email")
              ->addRule(Form::EMAIL, "Email v nesprávném tvaru");
         $form->addImage("odeslat", "/images/button-odeslat.gif", "Odeslat");
         $form->onSubmit[] = array($this, 'eventMyForm1Click');
         return $form;
     }

     public function eventMyForm1Click(AppForm $form)
     {
         // ... nejake akce po odeslani formu

         $this->presenter->redirect('Default:');
     }

     public function render()
     {
         $template = $this->template;
         $template->setFile(dirname(__FILE__) . '/KontaktFormControl.phtml');
         $template->form = $this->getComponent('myForm'); //jde i $this['myForm']
         $template->render();
     }
 }
?>

Editoval jasir (22. 7. 2009 22:38)

grogy
Člen | 147
+
0
-

Už to něco dělá, ale pořád nevím jak z toho. Do URL adresy mi to přidalo: /pohled?do=form-myForm-submit

Vidím tu chybu v mém návrhu, podle tvého se vytvoří formulář (instance AppForm) automaticky při vykreslování, já musel sám ručně + celý objekt se ukládal asi zbytečně do proměnné.

jasir
Člen | 746
+
0
-

grogy napsal(a):

Už to něco dělá, ale pořád nevím jak z toho. Do URL adresy mi to přidalo: /pohled?do=form-myForm-submit

Vidím tu chybu v mém návrhu, podle tvého se vytvoří formulář (instance AppForm) automaticky při vykreslování, já musel sám ručně + celý objekt se ukládal asi zbytečně do proměnné.

No hlavně jsi to createMyForm() nikde nevolal (Nette hledá createComponent{name}), formulář nebyl připojen do stromu komponent. Jo, ještě jedna věc! Pro přesměrování v komponentě na jiný presenter/view použij $this->presenter->redirect(...).
Volání $this->redirect(...) funguje pod úrovní presenteru, čili vede na signály komponenty.

Editoval jasir (22. 7. 2009 22:42)

grogy
Člen | 147
+
0
-

createMyForm() – to jsem volal v metodě createComponentForm() v presenteru, ovšem to byl jednoznačně špatný návrh.

Ten redirect, přesně tak. Díky, už to bude chodit. :)

kucix
Člen | 33
+
0
-

Využiju tohoto tématu k dotazu, řeším stejný problém…

Chci vytvořit komponentu, která se bude starat o přihlášení uživatele. A chci, aby to byla komponenta, abych to mohl jednoduše vložit do jakékoliv stránky.


mám třídu s komponentou:

<?php

class LoginForm extends Control {

	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');

		$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 !!";
			//prihlasovani
		} catch (AuthenticationException $e) {
			$form->addError($e->getMessage());
		}
	}

	public function render() {
		$template = $this->createTemplate();
		$template->setFile(dirname(__FILE__)."/LoginComponent.phtml");
		$template->form = $this->getComponent("LoginForm");
		$template->render();
	}
}
?>

A v BasePresenteru mám mimo jiné tohle:

<?php

abstract class BasePresenter extends Presenter {

	protected function createComponent($name) {
		switch ($name) {
			case 'LoginForm':
				$loginForm = new LoginForm();
				$this->addComponent($loginForm, 'LoginForm');
				break;
			default:
				parent::createComponent($name);
				return;
		}
	}
// dalsi metody
}
?>

Informace o nette:

/**#@+ Nette Framework version identification */
const NAME = ‚Nette Framework‘;

const VERSION = ‚0.9‘;

const REVISION = ‚475 released on 2009/08/04 12:44:08‘;

const PACKAGE = ‚PHP 5.2‘;
/**#@-*/


Chyba: Component with name ‚LoginForm‘ does not exist.


PS: Když jsem to upravil tak, že to jakoby chodilo(vytvoření bylo v __construct a formulář jsem si předával v třídní proměnné) a formulář to vykreslilo, tak stejně se neodeslal.. resp. odeslal, ale už ho nezpracovala obslužná metoda(nikdy se nevypsalo to echo, uživatel se nepřihlásil…). Když jsem zkusil $form->isSubmitted(), tak to zase hlásilo: Component is not attached to ‚Presenter‘.


Mám takový pocit, že mi uniká nějaká prkotina, kvůli které to nejede..
Dokáže mi někdo poradit, jak z toho vybruslit ven?


Ondřej Mirtes
Člen | 1536
+
0
-

Je to prkotina, nové továrničky jsou case-sensitive a název komponenty musí začínat malým písmenem:

Takže v LoginForm.php do metody render() patří:

$template->form = $this->getComponent("loginForm");

A přes __construct ti to neběželo asi z toho důvodu, žes nezavolal konstruktor rodiče a nepředals mu připojený presenter.

Editoval LastHunter (9. 8. 2009 11:48)

kucix
Člen | 33
+
0
-

Díky
Prkotinu jsem čekal, ale tohle…
Teď si připadám jak debil :D

Ondřej Mirtes
Člen | 1536
+
0
-

kucix napsal(a):

Díky
Prkotinu jsem čekal, ale tohle…
Teď si připadám jak debil :D

V pohodě, ona je to docela novinka a IMHO neintuitivní.

David Grudl
Nette Core | 8107
+
0
-

Jiné řešení je mít case-insensitive nazvy komponent, otazka je, jestli by to bylo ku prospěchu nebo naopak…

PetrP
Člen | 587
+
0
-

Ja dávám pořád prst nahoru za case-insensitive názvy component. Mít 2 různé komponenty rozdílné jen velikostí písmen je peklíčko (jak by řekl Inza ;])

Honza Kuchař
Člen | 1662
+
0
-

Mít 2 různé komponenty rozdílné jen velikostí písmen je peklíčko (jak by řekl Inza ;])

Souhlas :D

jasir
Člen | 746
+
0
-

PetrP napsal(a):

Ja dávám pořád prst nahoru za case-insensitive názvy component. Mít 2 různé komponenty rozdílné jen velikostí písmen je peklíčko (jak by řekl Inza ;])

Asi ano, ale nějak se mi to něčím nelíbí, ale nemohu najít žádný argument proč… Presentery jsou také case-sensitive. Nicméně – asi lehký palec nahoru. :)