Pořadí callbacků Click a onValidate
- thunderbuff
- Člen | 164
Ve formuláři mám více submitů. Jeden uloží data o uživateli do databáze, druhý submit by měl celý formulář „zahodit“ a do databáze uložit nějaké defaultní hodnoty. Kód vypadá takto:
<?php
class CreateOrEditUserForm extends Form {
public function __construct($DI) {
parent::__construct();
//...
$this->addSubmit('send', $t->_('Update Account'));
$this->addSubmit('sendandview', $t->_('Update Account and continue editing'))
->onClick[] = callback($this, 'redirectSelf');
$this->addSubmit('cancel', $t->_('Cancel and drop changes'))
->onClick[] = callback($this, 'cancel');
//...
}
}
?>
Továrnička v presenteru pak vypadá takto:
<?php
protected function createComponentCreateOrEditUserForm() {
$DI = new \Nette\DI\Container();
$DI->addService('translator', $this->translator);
$DI->addService('connection', $this->context->database);
$DI->parameters['supported_languages'] = $this->context->parameters['supported_languages'];
$DI->parameters['userid'] = isset($this->params['userid']) ? $this->params['userid'] : null;
$component = new CreateOrEditUserForm($DI);
$component->onValidate[] = callback($component, 'validateForm');
$component->onSuccess[] = callback($component, 'formSubmit');
return $component;
}
?>
Potíž nastane ve chvíli, kdy kliknu na tlačítko ‚Cancel and drop changes‘. Před callbackem CreateOrEditUserForm::cancel se totiž volá CreateOrEditUserForm::validateForm. V případě, že do formuláře napíšu nesmysly mi to místo provedení „cancel“ vrátí formulář s chybami. Jak z toho ven? Lze nějak zařídit, aby se validace volala až po clicku?
Editoval thunderbuff (21. 8. 2012 17:41)
- thunderbuff
- Člen | 164
Nakonec jsem se vzdal callbacku, vyřešeno pomocí:
<?php
$form['cancel']->isSubmittedBy()
?>
- Tomáš Votruba
- Moderator | 1114
Přijde mi divné dávat DI container do továrničky na formulář, ale snad máš své důvody. Pokud ne, zkus stejný výsledek dosáhnout v sandboxu, kde to půjde o poznání lépe.
Jen jsem chtěl podotknout, že formuláři stačí předat translator a o překlad už se postará.
- thunderbuff
- Člen | 164
@castamir: díky!
Schmutzka napsal(a):
Přijde mi divné dávat DI container do továrničky na formulář, ale snad máš své důvody. Pokud ne, zkus stejný výsledek dosáhnout v sandboxu, kde to půjde o poznání lépe.
Žádné zvláštní důvody nemám, jen mi to přišlo praktické. Co přesně myslíš formulací „Pokud ne, zkus stejný výsledek dosáhnout v sandboxu“?
Editoval thunderbuff (21. 8. 2012 23:30)
- Filip Procházka
- Moderator | 4668
Opravu je to hrozné :) Ukážu ti jak to udělat lépe.
Nejprve upravíš formulář, aby přijímal konstruktorem konkrétní služby, nikoliv celý DIC
class CreateOrEditUserForm extends Form
{
public function __construct(Nette\Database\Connection $db)
{
parent::__construct()
// ..
$this->addSubmit('send', 'Update Account');
$this->addSubmit('sendandview', 'Update Account and continue editing')
->onClick[] = callback($this, 'redirectSelf');
$this->addSubmit('cancel', 'Cancel and drop changes')
->onClick[] = callback($this, 'cancel');
// ...
}
public function setSupportedLanguages($langs)
{
// předpokládám, že tohle nastavuješ nějakému formulářovému prvku
$this['supported_languages']->setDefaultValue($langs);
}
public function setUserId($userId)
{
$this['userId']->setDefault($userId);
}
}
Potom si nadefinuješ továrničku v DIC
factories:
userSettingsForm:
class: CreateOrEditUserForm # databáze bude předána automaticky
setup:
- setTranslator() # translator bude předán automaticky
- setSupportedLanguages(%supported_languages%)
A potom ji použiješ
protected function createComponentCreateOrEditUserForm()
{
// vytvoří se formulář
// automaticky se předá databáze, translator a podporované jazyky
$form = $this->context->createUserSettingsForm();
// aktuální přihlášený uživatel
$form->setUserId($this->user->id);
$form->onValidate[] = callback($form, 'validateForm');
$form->onSuccess[] = callback($form, 'formSubmit');
return $form;
}
Takhle to vypadá lépe ne? ;) Bez magie.
Editoval HosipLan (22. 8. 2012 9:38)
- David Grudl
- Nette Core | 8218
Úplně bez magie to není, stále tam straší context. Řešil bych to spíš takto.