Callback ve formuláři a rozlišení edit a add

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

Zdravím,

snažím se vytvořit co nejjednodušeji formulář pro vytváření/editaci článku. Pro začátek pracuji jen s jednoduchou tabulkou kde je id, titulek a text.

Formulář mám ve zvláštním souboru, má dvě členské proměnné article a operation. V init() metodě vytvořím formulář a na základě opreation buďto vytvořím submit s callbackem na metodu create nebo na metodu edit. Pokud je operací edit, vytvoří se zároveň hidden pole s id článku a formulář se naplní defaultními hodnotami.

Vkládání nového záznamu funguje bez problémů. Problém je v tom, že pokud se pokusím o editaci, sice se vytvoří správný submit a formulář se naplní defaultními daty, nicméně po odeslání se přesměruje na metodu add místo na edit.

Debuggováním jsem zjistil že v metodě init() podmínka na operaci projde správně a objekt formuláře skutečně obsahuje i skryté pole id (a operaci ‚edit‘ s nastavenou proměnou article), ale když pak volá metodu create($button), již hidden pole neobsahuje (a operace je nastavena na ‚add‘).

Zřejmě bude problém někde při přiřazování operace z presenteru. Presenter má členskou proměnnou article, továrnu na formulář a dvě render metody pro create a edit. V případě create se article nastaví na null, v případě edit se nastaví příslušná entita z db.

V konstruktoru formuláře se pak kontroluje jestli parent presenter má nastavenou proměnnou article (je to objekt) a na základě toho pak volí operaci.

Přikládám kód presenteru a formuláře. (v šablonách je jen {control articlesForm}). Pro zjednodušení jsem kód ‚osekal‘ jen na diskutované části:

Presenter

<?php
use Nette\Application\UI\Form;

class ArticlesPresenter extends basePresenter {

    public $service;

    public $article;

    protected function startup() {
        parent::startup();
        $this -> service = new ArticlesService();
    }

    public function renderAddArticle() {
	    $this->article = null;
    }

    public function renderEditArticle($id) {
	    $this->article = $this->service->getOne($id);
    }

    public function createComponentArticlesForm() {
	    return new ArticlesForm($this, 'articlesForm');
    }
}
?>

Formulář

<?php
class ArticlesForm extends Nette\Application\UI\Form {

	private $article;
	private $operation;

	public function __construct($parent, $name) {
		parent::__construct($parent, $name);

		if(isset($this->presenter->article)) {
			$this->operation = 'edit';
			$this->article = $this->presenter->article;
		} else {
			$this->operation = 'create';
		}

		$this->init();
	}

	protected function init() {
		$this->addText('title_cz', 'Titulek');
		$this->addTextarea('text_cz', 'Text novinky');

		if($this->operation == 'create') {
			$this->addSubmit('save', 'Uložit')->onClick[]->callback($this, 'create');
		} elseif($this->operation == 'edit') {
			$this->addHidden('id');
			$this->addSubmit('save', 'Upravit')->onClick[]->callback($this, 'edit');
			$this->setDefaults($this->article->getAllAsArray());
		} else throw new InvalidArgumentException('Neplatná operace formuláře!');

	}

	public function create($button) {
		$values = $button->form->values;

		$entity = new Article;
		$entity->setTitle_cz($values['title_cz']);
		$entity->setText_cz($values['text_cz']);

		$this->presenter->service->create($entity);
		$this->presenter->flashMessage('Záznam byl vytvořen', 'success');
		$this->presenter->redirect('default');
	}

	protected function edit($button) {
		$values = $button->form->values;

		$entity = $this->presenter->service->getOne($values['id']);

		$entity->setTitle_cz($values['title_cz']);
		$entity->setText_cz($values['text_cz']);

		$this->presenter->service->update($entity);
		$this->presenter->flashMessage('Záznam byl upraven', 'success');
		$this->presenter->redirect('article', $entity->getId());
	}
}
?>

Všechno je funkční až na editaci.

Najde se dobrá duše která mi poradí proč tento přístup nefunguje?