Viacero akcií vo formulári

steelbull
Člen | 241
+
0
-

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
+
0
-

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
+
+1
-

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
+
0
-

@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)

David Matějka
Moderator | 6445
+
0
-

To by sa mi ale objavil vo values

submit button ve values neni

Ondřej Kubíček
Člen | 494
+
0
-

@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
+
0
-

@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?