Viacero akcií vo formulári
- steelbull
- Člen | 241
Mám formulár, kde mám tlačidlo Save a Cancel. Save uloží záznam a presmeruje na presenter a action, ktorý bol posledný pred vstupom do formulára.
Chcel by som pridať ešte jednu action „Apply“, ktorá formulár uloží, ale nepresmeruje. V metóde success presmerujem formulár po uložení. Tam potrebujem pridať redirect(‚this‘), ale chýba mi nejaké action, na základe ktorého by som rozhodol, či uložiť alebo uložiť a presmerovať.
Môj testovací formulár vyzerá takto:
<?php
use Nette\Application\UI,
Nette\Database\Context,
Kdyby\Translation\Translator,
Nette\Security\User,
App\Model;
/**
* Class BaseListForm
*/
class BaseListForm extends UI\Control
{
/** @var int */
private $id;
/** @var string */
private $name;
/** @var \Nette\Database\Context */
private $context;
/** @var \Kdyby\Translation\Translator */
private $translator;
/** @var \App\Model\BaseListModel */
private $model;
/** @var UI\Form */
private $form;
/** @var User */
private $user;
public $onSuccess;
public $onError;
/**
* Constructor.
* @param Context $context
* @param Translator $translator
* @param User $user
*/
public function __construct(Context $context, Translator $translator, User $user)
{
$this->context = $context;
$this->translator = $translator;
$this->user = $user;
$this->form = new UI\Form;
$this->model = new App\Model\BaseListModel($this->context, $this->user);
}
/**
* createComponentForm method.
* @return UI\Form
*/
public function createComponentForm()
{
$this->id = $this->presenter->getParameter('id');
if (!$this->name) {
$this->presenter->flashMessage('Table name empty or not allowed.', 'danger');
$this->presenter->redirectBack();
}
$form = $this->form;
$form->method = 'post';
$form->getElementPrototype()->addAttributes(array('id' => $this->getReflection()->name, 'class' => 'k-form ajax'));
$form->addText('title', $this->translator->translate('lr_projects.form.title') . ':')
->setRequired($this->translator->translate('lr_projects.form.please_insert_the_title'));
$form->addText('description', $this->translator->translate('lr_projects.form.description') . ':');
$form->addCheckbox('published', 'Published');
$form->addProtection();
if ($this->id)
$form->setDefaults($this->model->getItem($this->id));
$form->onSuccess[] = array($this, 'success');
$form->onError[] = function () {
if ($this->presenter->isAjax()) {
$this->redrawControl('form');
}
$this->onError();
};
$form->setRenderer(new \Nette\Forms\Rendering\KendoFormRenderer());
return $form;
}
/**
* render method.
*/
public function render()
{
$template = $this->template;
$template->setFile(__DIR__ . '/BaseListFormFactory.latte');
$template->render();
}
/**
* setName method.
* @param $name
*/
public function setName($name)
{
$this->name = $name;
$this->model->setTableName($name);
}
/**
* success method.
* @param UI\Form $form
*/
public function success(UI\Form $form)
{
$this->id = $this->presenter->getParameter('id');
try {
if (!$this->name)
throw new \PDOException('Table name empty or not allowed');
$this->model->setTableName($this->name);
$data = $form->getValues();
// Add id to data
if ($this->id)
$data->id = $this->id;
$this->model->saveItem($data);
$this->presenter->flashMessage($this->translator->translate('flash.record_was_saved'), 'success');
$this->presenter->redirectBack();
} catch (\PDOException $e) {
$this->presenter->flashMessage($e->getMessage(), 'danger');
if ($this->presenter->isAjax()) {
$this->presenter->redrawControl('flashmessages');
} else {
$this->redirect('this');
}
}
$this->onSuccess();
}
}
/**
* IBaseListFormFactory interface.
*/
interface IBaseListFormFactory
{
/**
* @return BaseListForm
*/
function create();
}
Editoval steelbull (25. 2. 2018 15:28)
- Nax
- Člen | 35
Já sám bych prostě přidal nějaký hidden input element kteremu bych při apply nastavil hotnotu apply a při save hodnotu save a potom bych si při onSuccess napsal podminku ze if($data->tvujInput == ‚save‘) $this->redirectBack(); else redirect(‚this‘) nebo tak něco
steelbull napsal(a):
Mám formulár, kde mám tlačidlo Save a Cancel. Save uloží záznam a presmeruje na presenter a action, ktorý bol posledný pred vstupom do formulára.
Chcel by som pridať ešte jednu action „Apply“, ktorá formulár uloží, ale nepresmeruje. V metóde success presmerujem formulár po uložení. Tam potrebujem pridať redirect(‚this‘), ale chýba mi nejaké action, na základe ktorého by som rozhodol, či uložiť alebo uložiť a presmerovať.
Môj testovací formulár vyzerá takto:
<?php use Nette\Application\UI, Nette\Database\Context, Kdyby\Translation\Translator, Nette\Security\User, App\Model; /** * Class BaseListForm */ class BaseListForm extends UI\Control { /** @var int */ private $id; /** @var string */ private $name; /** @var \Nette\Database\Context */ private $context; /** @var \Kdyby\Translation\Translator */ private $translator; /** @var \App\Model\BaseListModel */ private $model; /** @var UI\Form */ private $form; /** @var User */ private $user; public $onSuccess; public $onError; /** * Constructor. * @param Context $context * @param Translator $translator * @param User $user */ public function __construct(Context $context, Translator $translator, User $user) { $this->context = $context; $this->translator = $translator; $this->user = $user; $this->form = new UI\Form; $this->model = new App\Model\BaseListModel($this->context, $this->user); } /** * createComponentForm method. * @return UI\Form */ public function createComponentForm() { $this->id = $this->presenter->getParameter('id'); if (!$this->name) { $this->presenter->flashMessage('Table name empty or not allowed.', 'danger'); $this->presenter->redirectBack(); } $form = $this->form; $form->method = 'post'; $form->getElementPrototype()->addAttributes(array('id' => $this->getReflection()->name, 'class' => 'k-form ajax')); $form->addText('title', $this->translator->translate('lr_projects.form.title') . ':') ->setRequired($this->translator->translate('lr_projects.form.please_insert_the_title')); $form->addText('description', $this->translator->translate('lr_projects.form.description') . ':'); $form->addCheckbox('published', 'Published'); $form->addProtection(); if ($this->id) $form->setDefaults($this->model->getItem($this->id)); $form->onSuccess[] = array($this, 'success'); $form->onError[] = function () { if ($this->presenter->isAjax()) { $this->redrawControl('form'); } $this->onError(); }; $form->setRenderer(new \Nette\Forms\Rendering\KendoFormRenderer()); return $form; } /** * render method. */ public function render() { $template = $this->template; $template->setFile(__DIR__ . '/BaseListFormFactory.latte'); $template->render(); } /** * setName method. * @param $name */ public function setName($name) { $this->name = $name; $this->model->setTableName($name); } /** * success method. * @param UI\Form $form */ public function success(UI\Form $form) { $this->id = $this->presenter->getParameter('id'); try { if (!$this->name) throw new \PDOException('Table name empty or not allowed'); $this->model->setTableName($this->name); $data = $form->getValues(); // Add id to data if ($this->id) $data->id = $this->id; $this->model->saveItem($data); $this->presenter->flashMessage($this->translator->translate('flash.record_was_saved'), 'success'); $this->presenter->redirectBack(); } catch (\PDOException $e) { $this->presenter->flashMessage($e->getMessage(), 'danger'); if ($this->presenter->isAjax()) { $this->presenter->redrawControl('flashmessages'); } else { $this->redirect('this'); } } $this->onSuccess(); } } /** * IBaseListFormFactory interface. */ interface IBaseListFormFactory { /** * @return BaseListForm */ function create(); }
- Ondřej Kubíček
- Člen | 494
ty bys měl ideálně přesměrovat až v presenteru
v baselistform
public function createComponentForm()
{
...
$save = $form->addSubmit('save', 'Uložit a redirect');
$save->onClick[] = [$this, 'processForm'];
$apply = $form->addSubmit('apply', 'Uložit');
$apply->onClick[] = [$this, 'processForm'];
...
}
public function processForm(Nette\Forms\Controls\SubmitButton $button)
{
$values = $button->getForm()->getValues();
if ($button->name === "save") {
$this->onSuccess['save']();
} else {
$this->onSuccess['apply']();
}
}
presenter
public function createComponentBaseListForm()
{
$control = ...->create();
$control->onSuccess['save'] = function () {
//redirect
};
$control->onSuccess['apply'] = function () {
};
...
}
Editoval Ondřej Kubíček (25. 2. 2018 15:54)
- steelbull
- Člen | 241
@OndřejKubíček To by sa mi ale objavil vo values a musel by som ho potom vzdy zmazat pred pouzitim v modely. Mna napadlo upravit url vo form action a priat ?action=‚apply‘ alebo ?action=‚save‘ a potom ho ziskat pomocou getParamters(), ale neviem, ci to nie je bad practice.
Editoval steelbull (25. 2. 2018 15:56)
- Ondřej Kubíček
- Člen | 494
@steelbull podle mě se ti tam neobjeví, ale nemůžu to ted vyzkoušet, šak je to submit, normálně se tam taky neobjeví, nevidím duvod proč ted by měl
- steelbull
- Člen | 241
@OndřejKubíček @DavidMatějka Jaaaj, OK, tak takto sa to dá. Submit samozrejme v datach nie je.
Akurat ja mam submit tlacitka mimo formulara a form submit posielam javascriptom.
$('#' + target).submit();
Co mam robit, aby som nerobil nejaku halusku? Mam si vytvorit submit buttony v Nette, skryt ich CSSkom a javascriptom namiesto submit form urobit submit button click?
Alebo mam v Javascripte nechat ten form submit, a pridat pred submitom skryty input a ten v success vycitat?
Alebo vas pada nieco lepsie?