AppForm v Controle, handler v Presenteri inom ako parent
- edke
- Člen | 198
Pozdravujem vsetkych.
Prave riesim situaciu, kedy potrebujem mat formular ako napriklad login box, vyhladavanie na takmer kazdej stranke, preto som si vytvoril Control, ktory sa bude starat o renderovanie formularu, zobrazovanie, pripadne kesovanie vysledneho formularu.
Potrebujem ale nastavit AppForm v tomto Controle tak, aby bol formular po odoslani smerovany do Presenteru a casto krat ineho, ako je parent pre dany Control.
Potrebujem jednak nastavit konstruktor pre AppForm a jednak handler a jeho callback. Vie niekto poradit ako nato ?
- Ondrej
- Člen | 110
edke napsal(a):
Potrebujem ale nastavit AppForm v tomto Controle tak, aby bol formular po odoslani smerovany do Presenteru a casto krat ineho, ako je parent pre dany Control.
Potrebujem jednak nastavit konstruktor pre AppForm a jednak handler a jeho callback. Vie niekto poradit ako nato ?
To podle me nejde. Volani signalu (submit) controlu se dela nad stejnym presenterem.
- Jod
- Člen | 701
No tak si ku controlu pridaj metódu setSubmitCallback.
<?php
class Search extends Control
{
protected $callback;
protected $form;
function setSubmitCallback($callback)
{
$this->callback = $callback;
}
...
function createForm()
{
$form = new AppForm($this, 'form');
$form->addSubmit('search', 'Seearch')
$form->onSubmit[] = $this->callback;
$this->form = $form;
}
}
?>
<?php
class NejakyPresenter extends BasePresenter
{
function actionIndex()
{
$search = new Search($this, 'search');
$search->submitCallback = array($this, 'search_submitted');
}
function search_submitted(AppForm $form)
{
// submitnuté
}
}
?>
Takto by to malo fungovať. Registrovať callback na iný než aktuálny presenter neviem. Ledaže by mal statickú metódu (array(DruhyPresenter, ‚search_submitted‘));
Možno by sa ešte niečo dalo cez perzistentné komponenty v BasePrezenteri.
Editoval Jod (12. 2. 2009 17:14)
- kravčo
- Člen | 721
edke napsal(a):
Potrebujem ale nastavit AppForm v tomto Controle tak, aby bol formular po odoslani smerovany do Presenteru a casto krat ineho, ako je parent pre dany Control.
Potrebujem jednak nastavit konstruktor pre AppForm a jednak handler a jeho callback. Vie niekto poradit ako nato ?
Dôležité je, čo sa myslí smerovaním do prezentera.
Vieme, že po každom odoslaní formulára by malo nasledovať presmerovanie… Logicky, ak má signál spracovať iný prezenter, ako ten, ktorý je aktuálny, potrebujeme inštanciu, ktorú asi nejakým jednoduchým spôsobom nezískame… Otázkou teda je, či je to spracovanie iným prezenterom naozaj nutné, v prípade, že áno, mohla by to vyriešiť statická metóda ako píše Jod…
Skús upresniť, prečo by požiadavku mal spracúvať iný prezenter…
- edke
- Člen | 198
kravco wrote:
Dôležité je, čo sa myslí smerovaním do prezentera.
Vieme, že po každom odoslaní formulára by malo nasledovať presmerovanie… Logicky, ak má signál spracovať iný prezenter, ako ten, ktorý je aktuálny, potrebujeme inštanciu, ktorú asi nejakým jednoduchým spôsobom nezískame… Otázkou teda je, či je to spracovanie iným prezenterom naozaj nutné, v prípade, že áno, mohla by to vyriešiť statická metóda ako píše Jod…
Skús upresniť, prečo by požiadavku mal spracúvať iný prezenter…
Situacia je nasledovna:
Defaultny presenter obsluhuje titulnu stranku, teda prehlad clankov a pod., dalej zobrazenie jedneho clanku atd.
Presenter ktory obsluhuje nieco ako user control panel sa vola User, v nom sa riesia vsetky ulohy, ktore navstevnik potrebuje, teda login, logout, registracia, sprava profilu atd.
Na kazdej stranke, ktoru zobrazim potrebujem zjednoduseny login form a napriklad search form ako ukazuje vo svojom priklade Jod. Ale po vyplneni a odoslani formulara som uz ostatne chcel riesit v Presenteri User, kedze napriklad pre zobrazovanie chybovych sprav (zadaj login, heslo, nespravny login, konto blokovane) nie je na titulke miesto. Preto po vyplneni formulara na login by malo nasledovat presmerovanie a spracovanie signalu v presenteri User, kde sa prihlasovanie vyhodnoti, alebo sa znovu zobrazi uz plna podoba login formularu aj s chybovymi hlaskami.
Nieco podobne je search form, tiez na titulnej stranke je len input na zadanie klucovyuch slov, po odoslani je potrebne presmerovat spracovanie signalu do Presenteru urceneho na vyhladavanie, kde sa znovu zobrazi input s nasimi zadanymi klucovymi slovami ale uz aj vysledkami vyhladavania.
- edke
- Člen | 198
Momentalne som nasiel riesenie, ktore ale mi pride ako velmi nesystemove a len som to obisiel:
1. v presenteri Guest mam kompletne funkcne prihlasovanie, teda formular a handler na jeho spracovanie:
final class FrontEnd_GuestPresenter extends FrontEnd_BasePresenter
{
public function actionLogin()
{
$form = new AppForm($this, 'form');
$form->renderer->clientScript = NULL;
$form->addText('login', 'Prihlasovacie meno')
->addRule(Form::FILLED, 'Zadajte prihlasovacie meno');
$form->addPassword('password', 'Prihlasovacie heslo')
->addRule(Form::FILLED, 'Zadajte prihlasovacie heslo');
$form->addCheckbox('remember_me', 'Zapamätať si ma na tomto počítači.');
$form->addSubmit('ok', 'Prihlásiť sa')
->onClick[] = array( $this, 'Login_onSubmit');
$this->template->form = $form;
$this->template->title = "Log-in";
}
public function Login_onApply( SubmitButton $button)
{
try {
$values= $button->getForm()->getValues();
....
2. routa pre presenter Guest vyzera nasledovne:
$router[] = new Route('<view (register|login|forgot)>/<id>', array(
'module' => 'FrontEnd',
'presenter' => 'Guest',
'id' => NULL,
));
3. komponenta LoginControl moze byt pridana do lub. presenteru a stara sa len o zobrazenie maleho prihlasovacieho formulara:
class LoginControl extends Control
{
public function __construct(IComponentContainer $parent = NULL, $name = NULL)
{
parent::__construct($parent, $name);
}
public function render()
{
$form = new Form('loginform');
$form->setAction('/login/?do=form-submit');
$form->renderer->clientScript = NULL;
$form->addText('login', 'Login')
->setHtmlId('inputlogin');
$form->addPassword('password', ' heslo')
->setHtmlId('inputpassword');
$form->addCheckbox('remember_me', 'Zapamätať si ma na tomto počítači.');
$form->addImage('ok', $this->template->baseUri. 'gui/form-login-input-submit.gif', 'Prihlásiť sa');
ob_start();
$this->template->setFile(Environment::getVariable('templatesDir'). '/components/LoginControl.phtml');
$this->template->registerFilter('CurlyBracketsFilter::invoke');
$this->template->form= $form;
$this->template->render();
echo ob_get_clean();
}
Vyhody
- funguje to tak ako potrebujem
Nevyhody
- nesystemove, nie je ziadna logicka vazba medzi strukturou formulara v Control a handlerom v presenteri Guest
- definicia formulara na 2 miestach, ak bude potrebne formular upravovat, musim zmeny preniest aj do Control-u
- ak zmenim v bootstrap-e routrovanie pre presenter Guest, musim rucne zmenit action pre form v Control-e
Teda ak niekto bude vediet poradit systemovejsie riesenie, budem vdacny a velmi rad aktualne spracovanie prerobim.
- Jod
- Člen | 701
Jednoduché riešenie pomocou BasePresenteru (neni predsa len na registráciu filtrov ,)
Ak myslíš nejaké také prihlasovanie ako je tu , tak to robím cez
BasePresenter.
Môžeš si spraviť LoginControl ktorý vytvoríš v BasePresenteru a bude na
každej stránke v layoute sa vykreslovať. Po odoslaní sa oblúži z metódy
formSubmitted v BasePresenteru. Po nesprávnom prihlásení užívateľa
môžeš presmerovať na GuestPresenter login ak ti to tam vyhovuje, alebo mu
napísať nad formulárom chybu. A nakoniec v GuestPresenteri login buď
zmeníš layout, alebo pridáš podmienku aby sa ti ten loginControl
nerenderoval tam, ale si ho pridáš do šablony.
- TeeBee87
- Člen | 14
V komponentě vytvářím anketu (formulář)
public function __construct(/*Nette\*/IComponentContainer $parent = NULL, $name = NULL) {
parent::__construct($parent, $name);
$this->_setData();
}
private function _setData() {
$form = new AppForm($this, 'poll');
$form->onSubmit[] = array($this, 'processVote');
if ($this->_voted == true) {
// get poll results
$poll = Poll::getInstance()->getPollByAnswerId($this->_answerId);
} else {
$poll = Poll::getInstance()->getPollByRand();
}
...
public function render() { ... }
public function processVote(AppForm $form) {
$this->_voted = true;
$this->_answerId = $form['answer_id']->getValue();
...
}
Jde o to, že anketu vybírám náhodně a když se formulář odešle tak ho před zpracováním signálu musím znovu vytvořit – jenže dokud nezpracuju signál tak nevím, kterou anketu jsem měl vytvořenou …
Můžu si vzít id ankety (respektiwe odpovědi, ale to je jedno) z $_POSTu, ale.. jak by se tohle mělo řešit?