Nette 2.2 Zpracování formuláře s Form\Container

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

Zdravím,

mohli byste mi prosím poradit, jak zpracovat formulář s containery? Případně mi napsat, kde dělám chybu? Jde o uložení 4 článků do db – 4 jazykové mutace. Řeším to už druhý den a co šlo vygooglit jsem vygooglil a mám pocit, že jsem zkusil uplně všechno.. Nejprve jsem používal Multipler, ale potřeboval jsem všechny verze článku uložit naráz, takže jsem se to snažil předělat na form s containery a je možné, že tam zůstalo něco co tam možná být nemá.. Případně by mi velmi pomohlo, kdybyste mi poradili, jak rozchodit fireLog.. zkoušel jsem dumpnout a následně lognout $values z fce processForm, ale ve firelogu se nic nezobrazilo. Předem díky.

ArticleForm.php

class ArticleForm extends \Nette\Object
{
	/**
	* @inject
	* @var App\Model\Repositories\ArticleRepository
	*/
	private $articleRepository = NULL;

	public $artRepo;

	public function __construct(\App\Model\Repositories\ArticleRepository $articleRepository) {
		$this->artRepo = $articleRepository;
	}

	public function create()
	{
		$form = new UI\Form;

		$form->addSubmit('submit');
		$form->onSubmit[] = $this->processForm;
		return $form;
	}

	public function processForm($form) {
		$values = $form->getValues(TRUE);
		foreach ($values["editedArticles"] as $article) {
			foreach ($article as $key => $value) {
				$article = $this->artRepo->getByID($value['id']);
				$article->title = $value['title'];
				$article->showtitle = ($value['showtitle'] == TRUE ? 1 : 0);
				$article->slug = $value['slug'];
				$article->content = $value['content'];
				$article->active = $value['active'];
				$this->artRepo->persist($article);
			}
		}
	}
}

CategoryPresenter.php

class CategoryPresenter extends BasePresenter
{

	/**
	* @inject
	* @var \App\Model\Repositories\CategoryRepository
	*/
	public $catRepo = NULL;

	/**
	* @inject
	* @var \App\Model\Repositories\ArticleRepository
	*/
	public $artRepo = NULL;

	/** @var \App\AdminModule\Components\ArticleForm @inject */
	public $articleFormFactory;

	public $cid = NULL;

	public function startup() {
    	parent::startup();
    }

    /**
	* @inject
	* @var \App\FrontModule\Classes\ImgDir
	*/
	public $imgDir = NULL;

    protected function createComponentArticleForm()
	{
		$form = $this->articleFormFactory->create();
		$articles = $this->artRepo->findBy(array('cid' => $this->cid));
		$articlesContainer = $form->addContainer('editedArticles');
		foreach ($articles as $article) {
			$currentContainer = $articlesContainer->addContainer("$article->lang");
			$currentContainer->addText('title', $article->title);
			$currentContainer->addCheckbox('showtitle');
			$currentContainer->addTextarea('content', $article->content);
			$currentContainer->addHidden('id', $article->id);
		}
		$form->onSuccess[] = function () {
			$this->flashMessage('Změny byly úspěšně uloženy.', 'success');
			$this->redirect('this');
		};
		return $form;
	}

	public function renderDefault($slug)
	{
		$this->template->cats = $this->catRepo->findAll();
	}

	public function renderCategoryArticles($cid, $slug)
	{
		$this->cid = $cid;
		$articles = $this->template->articles = $this->artRepo->findBy(array('cid' => $cid));

		foreach ($articles as $article) {
			$a = $this->artRepo->getBy(array('id' => $article->id));
			$vals = $a->toArray();

			$this["articleForm"]["editedArticles"][$a->lang]->setDefaults($vals);

			$editedArticles[] = $article->lang;
		}

		$this->template->editedArticles = $editedArticles;
	}
}

Articles.latte

<form n:name="articleForm" id="articleLangTabContent" class="tab-content">
	{formContainer editedArticles}
		{foreach $editedArticles as $editedArticle}
			{formContainer $editedArticle}
			<div id="{$editedArticle}" class="tab-pane fade{if $iterator->first} active in{/if}" role="tabpanel" aria-labelledby="{$editedArticle}-tab">
				<div class="col-md-12">
					<div class="form-group">
						<label n:name="title" class="control-label">Titulek:</label>
						<input n:name="title" type="text" class="form-control" />
						<label n:name="showtitle" class="checkbox-inline"><input n:name="showtitle" type="checkbox" /> Zobrazit titulek ve frontendu</label>
					</div>
				</div>
				<div class="col-md-12">
					<textarea n:name="content">
					</textarea>
				</div>
			</div>
			{/formContainer}
		{/foreach}
	{/formContainer}
	<div class="col-md-12">
		<input n:name="submit" type="submit" class="btn btn-success">
	</div>
	<ul class="errors" n:if="$form->hasErrors()">
		<li n:foreach="$form->errors as $error">{$error}</li>
		{$form->render('errors')}
	</ul>
</form>
Marek Šneberger
Člen | 130
+
0
-

Já bych na to použil spíš kdyby/replicator

David Matějka
Moderator | 6445
+
0
-

$this->cid nastavujes az v render metode. Ale ta se provadi az po zpracovani formulare. Ve chvili zpracovani je tak to $this->cid null a vyberou se spatne (resp. zadne) articles

reseni: presun to do action* metody, nebo pouzij v createComponent $this->getParameter('cid')

Editoval matej21 (18. 1. 2015 22:01)

anil
Člen | 4
+
0
-

Díky za upozornění. Nicméně to nepomohlo – články se načítaly stejně/dobře i před tím a v budoucnu se ty containery budou „generovat“ pouze podle počtu jazyků v configu, problém je spíše s uložením. Vzal jsem fci processForm kterou jsem používal s Multiplerem a obalil jsem to cykly foreach, což by mělo být v pořádku..? Předpokládám, že formulář to vrací ve tvaru $values[„container“][„language“][„title“] = Titulek článku.. zkoušel jsem i různé stupně zanoření.. ale bez toho dumpu je to bída :(

David Matějka
Moderator | 6445
+
0
-

Ted koukam, ze tam blbe iterujes ve zpracovani. V tom $articles uz budou hodnoty kontejneru, ten vnitrni foreach je spatne.

ale bez toho dumpu je to bída :(

tak snad dump(...); exit; ne?
nebo si zprovozni xdebug :)

anil
Člen | 4
+
0
-

Ta iterace je tam dobře – ve values je container kam se hází články a v něm jsou další 4 jazykové containery ve kterých jsou jazykové mutace title, content, atd.. :)

Hm.. exit; :D Dík moc :) Já z toho byl tak vystresovanej, že mě to nenapadlo.. pořád jsem ten výstup hledal v logu a v tracy liště :) Problém byl nakonec v processForm – $article->slug = $value[‚active‘]; Jelikož jsem od toho de/aktivování článků upustil. Ale nechápu, proč to nevyhodilo chybu, že slug neexistuje nebo tak něco.. místo toho to prostě nezapisovalo do db.

anil
Člen | 4
+
0
-

Ta iterace je blbě, omlouvám se :) Jsem z toho v průběhu vyhodil to [„editedArticles“], takže mi to fungovalo.. S tím klíčem je to už samozřejmě blbě no :)