formulořová komponenta

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

Ahoj,
chtel jsem si vytvorit komponentu s formularem ale nejak se mi ji nedaří načíct a kdyz ji dam do presenteru tak je problem s setMethod. A potrebuju ji vykreslovat ručně. Nevíte co s tim?

<?php
class myOrder extends Control{
    function __construct($parent, $name){
            parent::__construct($parent, $name);

    }

    protected function createComponentOrderForm()
	 {

        $form = new AppForm($this, 'orderForm');
        $form->setMethod('post');
        $form->setAction($this->link('Default:default') ) ;

        $form->addText('label', 'zadej label')
            ->addRule(Form::FILLED, 'Zadej label');

        $form->addSubmit('ok', 'Odeslat');
        $form->onSubmit[] = array($this, 'orderFormSubmitted');
        return $form;
	  }

    public function orderFormSubmitted($form)
    {
    //zpracování formulare
  }
}
?>
Honza Marek
Člen | 1664
+
0
-

Myslim, že nette nemá rádo, když v továrničce komponentu zároveň připojíš ($form = new AppForm($this, 'orderForm');) a zároveň vrátíš.

Tip: Jinak taky můžeš využít parametru name pro připojení.

protected function createComponentOrderForm($name) {
    $form = new AppForm($this, $name);
    ...
}
sin
Člen | 82
+
0
-

Nechapu proc ale proste to tu komponentu nevidí.

<?php
Component with name 'orderForm' does not exist.
?>

Mam pak nejak pripojovat soubor s komponentou do presenteru?

Editoval sin (15. 10. 2009 12:43)

Milhauz
Člen | 26
+
0
-

Ano. Připojí se pomocí addComponent():

<?php
  $this->addComponent($form, 'nazev');
?>
Honza Kuchař
Člen | 1661
+
0
-

Myslim, že nette nemá rádo, když v továrničce komponentu zároveň připojíš ($form = new AppForm($this, ‚orderForm‘);) a zároveň vrátíš.

Pokud vim, tak si nette tu komponentu nepřipojí 2×


Já tu komponentu vidím, jako ok. Ale chyba pravděpodobně bude v tom, že ten form vykresluješ v šabloně presenteru. (usuzuji z toho, ze ta komponenta nemá metodu render)

sin
Člen | 82
+
0
-

Milhauz napsal(a):

Ano. Připojí se pomocí addComponent():

<?php
  $this->addComponent($form, 'nazev');
?>

mohl bych poprosit o krátký příklad? Nejak jsem to z API nepochopil

Honza Marek
Člen | 1664
+
0
-

honzakuchar napsal(a):
Pokud vim, tak si nette tu komponentu nepřipojí 2×

Právě. Vyhodí výjimku zmetek místo toho, aby to v tichosti přepojil nebo nic neudělal.

Honza Kuchař
Člen | 1661
+
0
-

Tak mě napadlo, že by se nejdřív zjistilo pokud komponenta se stejným názvem existuje. Pokud ano, tak by srovnal, tu co chci zaregistrovat s tou co tam už je. Pokud by to byla ta stejná, tak by potichu neudělalo Nette nic. Pokud by to byla nějaká jiná komponenta, tak by se vyhodila výjimka.

Ondřej Mirtes
Člen | 1536
+
0
-

Myslím, že je lepší řešení podědit si AppForm, než vytvářet formulář uvnitř potomka Controlu…

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

        $this->addText('label', 'zadej label')
            ->addRule(Form::FILLED, 'Zadej label');

	//setAction ani setMethod není s AppFormem potřeba

        $this->addSubmit('ok', 'Odeslat');
        $this->onSubmit[] = array($this, 'formSubmitted');
	}

	public function formSubmitted(MyForm $form) {
		//zpracovani
	}
}
Honza Marek
Člen | 1664
+
0
-

honzakuchar napsal(a):

Tak mě napadlo, že by se nejdřív zjistilo pokud komponenta se stejným názvem existuje. Pokud ano, tak by srovnal, tu co chci zaregistrovat s tou co tam už je. Pokud by to byla ta stejná, tak by potichu neudělalo Nette nic. Pokud by to byla nějaká jiná komponenta, tak by se vyhodila výjimka.

Nevyhazuje se výjimka, že na tom místě už něco sedí. (Možná taky, ale nepotkal jsem.) Vyhodí se něco jako „Control už má rodiče“, což je podle mě naprosto k ničemu…

sin
Člen | 82
+
0
-

LastHunter napsal(a):

Myslím, že je lepší řešení podědit si AppForm, než vytvářet formulář uvnitř potomka Controlu…

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

        $this->addText('label', 'zadej label')
            ->addRule(Form::FILLED, 'Zadej label');

	//setAction ani setMethod není s AppFormem potřeba

        $this->addSubmit('ok', 'Odeslat');
        $this->onSubmit[] = array($this, 'formSubmitted');
	}

	public function formSubmitted(MyForm $form) {
		//zpracovani
	}
}

Supr, to je to co jsem potreboval jenom mam problem u zpracování signálu… udelal jsem to podle tvé ukázky ale hází mi to chybu:

<?php
The signal receiver component 'myOrderForm' is not found.
?>

V presenteru to volam u before render jako nový objekt…

Ondřej Mirtes
Člen | 1536
+
0
-

No musíš to strčit do továrničky :)

Klokan
Člen | 47
+
0
-

Podle životního cyklu presenteru se zpracování signálu provádí před renderováním. Proto Ti hlásí, že ještě neexistuje. Vytvoř si továrničku, která objekt vrací když jej aplikace potřebuje, jak popisuje přispěvěk od LastHunter

sin
Člen | 82
+
0
-

OK, zkusil jsem tovarnicku ale nejak mi to porad nejede…
dotaz: má třída s komponentou(orderForm.php) koncit return $this; nebo ne?

Template:

<?php
{control Myform, 'mujFormular'}
?>

Presenter:

<?php
protected function createComponentMyform($name)
    {
        $form = new OrderForm($this, $name);
        return $form;
    }
?>

orderForm.php

<?php
class OrderForm extends AppForm {
    public function __construct($parent, $name) {
        parent::__construct($parent, $name);
	//dalsi prvky atd
	}
}
?>
Ondřej Mirtes
Člen | 1536
+
0
-

Opravím tě :)

{control myForm} <!-- žádný parametr není potřeba -->
protected function createComponentMyForm() //velké F, nemusíš uvádět parametr
    {
        return new OrderForm; //stačí takto, pokud uvádíš $this v konstruktoru a pak objekt ještě returnuješ, připojuješ ho jakoby dvakrát a dostaneš Laděnku
    }
sin
Člen | 82
+
0
-

Upravil jsem to jak pises ale stale stejna chybova hlaska… Component with name ‚MyForm‘ does not exist.
Ty tri soubory jsem dal na adresu http://www.uloz.to/…68/chyba.rar jestli by jste na to nekdo koukli kde to tam je blbe protoze ja to v tom opravdu nevidim… :(

Ondřej Mirtes
Člen | 1536
+
0
-

První písmeno komponenty je malé, musíš tedy všude volat myForm. Ale továrnička se bude stále jmenovat createComponentMyForm.

A v submittovací metodě už nemusíš kontrolovat ani odeslanost, ani validitu, jinak by se ta metoda vůbec nevolala.

Editoval LastHunter (18. 10. 2009 20:52)

blacksun
Člen | 177
+
0
-

Zkus to volat v šabloně jako {control myForm} – s malým „m“.

Edit: tak zase pozdě ;)

Editoval blacksun (18. 10. 2009 20:57)

Honza Kuchař
Člen | 1661
+
0
-

Jenom takový dotaz, je ta šablona kde se volá ten widget opravdu od té komponenty kde je to createComponentMyForm?

Ondřej Mirtes
Člen | 1536
+
0
-

Továrnička je v DefaultPresenter, šablona je Default.default.phtml, takže to by mělo být správně.

Ještě jsem si všiml jednoho detailu – podle coding standards (opravdu doporučuji si je prostudovat) má být název souboru se třídou začínat velkým písmenem, stejně jako třída.

sin
Člen | 82
+
0
-

Supr, konecne správná sestava velkych a malich pismen… ja nikdy nevim ktere kde ma byt…
este mi ale nekolik veci nejde…

  1. v ketre casti muzu nastavit setDefaults ? mam to na konci construct a tam mi to hazi chybu Form is not anchored and therefore can not determine whether it was submitted.
  2. muzu nejak z komponenty pristoupit do modelu? potrebuju v te fci ktera zpracovává odeslany formular pouzit select ktery mam ve funkci v modelu…
Ondřej Mirtes
Člen | 1536
+
0
-
  1. setDefaults by měl nastavovat Presenter, nejlépe v action* metodě (ve které máš přístup k parametru, podle kterého se nastavuje) nebo v továrničce (createComponentOrderForm), kde si parametr vytáhneš přes $this->getParam('id').
  2. Ano, udělej si v tom OrderForm private property $model, v konstruktoru toho formu ho založ (new OrderModel nejspíš) a pak na něj zavolej jeho metodu, pomocí které naplníš ten select.
sin
Člen | 82
+
0
-
  1. Super, funguje. Děkuju
  2. To jsem moc nepochopil… udelam si promenou private $model ale jak pak se dostanu do modelu ktery v presenteru volam jako $this->model->nejakaFce();?
blacksun
Člen | 177
+
0
-

Pokud je to komponenta, kterou vytvoříš v tom presenteru a je k němu připojená, tak k modelu můžeš přistoupit přes rodiče toho formu..

Zkusil bych $form->parent->model->fceXYZ();

kravčo
Člen | 721
+
0
-

Honza M. napsal(a):

Myslim, že nette nemá rádo, když v továrničce komponentu zároveň připojíš ($form = new AppForm($this, 'orderForm');) a zároveň vrátíš.

Tip: Jinak taky můžeš využít parametru name pro připojení.

protected function createComponentOrderForm($name) {
    $form = new AppForm($this, $name);
    ...
}

Nesúhlasím, podmienka v ComponentContainer.php @ line 191 podľa mňa jasne demonštruje, že ak už pripojený komponent vrátim, opäť sa nepripojí. Samozrejme je to zbytočné, ukazuje to, že človek, ktorý to píše, tomu celkom nerozumie, no ladenku by to vyvolať rozhodne nemalo…

sin
Člen | 82
+
0
-

Model delam v BasePresenteru od ktereho se dedí DefaultPresenter. Ale kdyz jsem dal

<?php
$this->parent->model->NejakaFCE();
?>

tak mi to hodilo Cannot read an undeclared property DefaultPresenter::$model.

Honza Marek
Člen | 1664
+
0
-

Aha, tak se to změnilo :-)

sin
Člen | 82
+
0
-

:D Ups a nevite jak to je tedka?