Mizící addHidden vlastnost formu

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

Nedaří se mi dostat ke komponentě formuláře typu addHidden(), která je přidaná pouze za podmínky. viz kód a komentáře:

<?php
// v presenteru
private $product;

public function renderDefault($id = '') {
	if ($id != '') {
		// vratim si data o produktu, k jeho vlastnostem se pristupujue $this->product->vlasnost
		$this->product = $this->context->productsService->get($id);
	}
}

public function createComponentProductForm() {
	$form = new Nette\Application\UI\Form;
	$form->addText('nazev', 'Název');
	if (isset($this->product)) {
		$form->addHidden('edit', 1);
		$form->setDefaults(array(
			'nazev' => $this->product->name
		));
	}
	$form->addSubmit('send');
	$form->onSuccess[] = callback($this, 'productFormSubmitted');
	return $form;
}

public function productFormSubmitted(Nette\Application\UI\Form $form) {
	$values = $form->getValues();
	if (isset($values["edit"])) {
		// po odeslání formuláře vždy false, i když je nastaven $this->product
		// při 1. načtení $values["nazev"] se načte z DB,
		// po odeslání formuláře zůstane změna zachována
	}
}
?>

Co mi uniká, že mi to komponenta ve formu addHidden nikdy neprojde do výsledné metody productFormSubmitted?

greeny
Člen | 405
+
+2
-

Render metody se provádí až po submit eventu formu (viz "":https://doc.nette.org/…n/presenters#… ). Přesuň to do action metody a bude fungovat.

Jan Endel
Člen | 1016
+
+1
-

Dej si prosím pozor na zpracování takovéhoto formu, ten hidden ti potencionálně může kdokoliv zeditovat, tedy přidej do zpracování formu podmínku, že k editování tohoto produktu má uživatel oprávnění, pokud to v tvé aplikaci dává smysl.

Etch
Člen | 403
+
0
-

Osobně nepovažuji podobné podmínkování v továrničce formuláře za ideální a rozhodně to není noc přehledné.

public function actionDefault($id = '') {
    if ($id != '') {
        // vratim si data o produktu, k jeho vlastnostem se pristupujue $this->product->vlasnost
        $this->product = $this->context->productsService->get($id);
		$this['productForm']->setDefaults(array(
			'edit' => $this->product->id, // or whatever
            'nazev' => $this->product->name
        ));
    }
}

protected function createComponentProductForm() {
    $form = new Nette\Application\UI\Form;
    $form->addText('nazev', 'Název');
    $form->addHidden('edit');
    $form->addSubmit('send');
    $form->onSuccess[] = callback($this, 'productFormSubmitted');
    return $form;
}

public function productFormSubmitted(Nette\Application\UI\Form $form) {
    $values = $form->getValues();
    if ($values["edit"] !== null) { // Nejsem si úplně jistý, ale mělo by to vracet null pokud nebude prvek nastaven.
        // po odeslání formuláře vždy false, i když je nastaven $this->product
        // při 1. načtení $values["nazev"] se načte z DB,
        // po odeslání formuláře zůstane změna zachována
    }
}

Tohle mi přijde jako o něco rozumnější řešení.

Editoval Etch (25. 2. 2015 11:21)

James07
Člen | 41
+
0
-

@Etch
Ten způsob se mi líbí, je to mnohem přehlednější a lépe rozdělené. Ale jak nastavit výchozí hodnotu pro komponentu addCheckboxList?

<?php
	// získání všech kategorií
	$categories = $this->context->categoriesService->getAll()->order('name')->fetchAll();
	$raw = array();
	foreach ($categories as $category) {
		$raw[$category->id] = $category->name;
	}
	// productForm v generování má:
	// 	$form->addCheckboxList('categories', 'Kategorie');
	$this["productForm"]->setDefaults(array(
		'name'			=> $this->product->name,
		'categories'	=> $raw // zde to vychodí chybu Nette\InvalidArgumentException
	));
?>
Etch
Člen | 403
+
0
-

Tam by mělo snad fungovat, když tam předáš pole hodnot:

// získání všech kategorií
$categories = $this->context->categoriesService->getAll()->order('name')->fetchAll();
$raw = array();
foreach ($categories as $category) {
    $raw[] = $category->id;
}
// productForm v generování má:
//  $form->addCheckboxList('categories', 'Kategorie');
$this["productForm"]->setDefaults(array(
    'name'          => $this->product->name,
    'categories'    => $raw
));
James07
Člen | 41
+
0
-

@Etch
To právě nejde. háže to stejnou chybu Nette\InvalidArgumentException
Values ‚3‘, ‚2‘, ‚4‘, ‚1‘, ‚5‘ are out of allowed range [] in field ‚categories‘
předtím to házelo tu stejnou s tím, že Values byly názvy, nyní to jsou id kategorií.

David Matějka
Moderator | 6445
+
+1
-

Polozky nastav pomoci setItems

James07
Člen | 41
+
0
-

@DavidMatějka
A jak některým položkám v tom checkboxListu nastavím checked na true?
Napadlo mě něco ve stylu:

<?php
// $productCategories = array(1, 2, 6);
foreach ($productCategories as $category) {
	// nefunguje
	$this["productForm"]["categories"][$category]->setDefaultValue(TRUE);
	// nebo možná ještě nějak jinak přes to setItems();
}

Ale ani jedna dereference mi neprojde úspěšně. Jak se to má udělat?
?>

Editoval James07 (25. 2. 2015 18:45)

Aurielle
Člen | 1281
+
0
-

Nastavuješ přes $form->setDefaults(['checkboxList' => 'key']);, kde key je klíč položky, kterou chceš zaškrtnout.

James07
Člen | 41
+
0
-

Jenom doplním, v action se to dá nastavit:

<?php
// nazev formulare				  		            nazev checkboxListu   	pole vychozich hodnot
$this["productForm"]->setDefaults(['categories' => $productCategory]);
?>