getValues vraci select a multiselect jako prazdne hodnoty

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

Dobry vecer!

Ve sve aplikaci v jednom (jedinem formulari) se mi zobrazuje chyba. Do formulare strkam jednu hidden a jeden select. Vykresleni i odeslani je v poradku. Data v POSTu jsou tez, ale jakmile zavolam getValues, tak hodnoty ze selectu nebo multiselectu zmizi. Nefunguje zmena nazvu objetku a je to jenom v jednom formulari (mezi dalsimi mnoha). Nejvice me zarazi ze az getValues hodnoty nevrati. Prosim o radu.
Dekuji

public function createComponentAddRole(){
		$form = new AppForm();
		$select = array();
		if($this->notInRole) foreach($this->notInRole as $r){
			$select[$r['id']] = $r['nazev'];
		}

		$form->addHidden('user');
		$form->addSelect('role','Pridat roli',$select);
		$form->setDefaults(array('user'=>$this->showUser));
		$form->onSubmit[] = callback($this,'processAddRole');
		$form->addSubmit('save','Pridat');

		return $form;
	}

	public function processAddRole($form){
		$values = $form->getValues(); // -> vrati hodnoty 'user'->spravne naplnene, 'role'->prazdne
		$this->admin->addRole($values);
		$this->flashMessage('Role pridana');
		$this->redirect('this');
	}

Editoval Finalgrab (28. 4. 2010 0:59)

nAS
Člen | 277
+
0
-

Pravděpodobně při obsluze odeslání formuláře ještě nemáš nastavenu proměnnou $this->notInRole, takže při vytvoření formuláře se selectu nenastaví možné hodnoty a potom při vyhodnocování nemá z čeho vybírat a tak vrátí prázdné pole.

Finalgrab
Člen | 15
+
0
-

Nevim jestli tvoji odpoved chapu spravne. $this->notInRole je naplnena spravne pri vytvareni formulare, navic je toto pole jenom zdrojem dat pro pole $select, ktere se vklada do formulare. Formular se vykresli spravne a hodnoty v nem jsou (v kodu stranky jsou value naplneny. Dokonce i POST data prenese, ale getValues uz hodnotu ze selectu nevrati.
Pochopil jsem spravne ze pri behu funkce, ktera zpracovava formular musim mit nekde docasne ulozene to pole? Neuchovava si ho nahodou $form od chvile, co jsem do nej to pole vlozil?

Šaman
Člen | 2665
+
0
-

Ne, není potřeba nic dočasně ukládat, ta chyba bude jinde.

Mě se tam nezdá to volání obslužné fce:

<?php
$form->onSubmit[] = callback($this,'processAddRole');
$form->addSubmit('save','Pridat');
?>

Zkusil jsem to u sebe tam mi to hází výjimku Argument 1 passed to MyPresenter::processAddRole() must be an instance of SubmitButton, instance of AppForm given.
Je zajímavý, že to u tebe projde, ale zkus to přepsat takto:

<?php
$saveBtn = $form->addSubmit('save','Pridat');
$saveBtn->onClick[] = callback($this,'processAddRole');
?>

//Edit: Aha, su lama. Já totiž u svých obslužných metod chci jako parametr SubmitButton a ty Form. Pak to používám takhto (v presenteru):

<?php
function okClicked(SubmitButton $button)
{
	$values = $button->getForm()->getValues();
	$this->data->setData($values);
	$this->redirect('nekamJinam');
}
?>

Takže to tím asi nebude, ale jinou nesrovnalost tam já nevidím.

Editoval Šaman (28. 4. 2010 11:58)

Finalgrab
Člen | 15
+
0
-

Tak to je potom zahada, hlavne tenhle zpusob naplnovani promennych pouzivam na nekolika mistech a vsude to funguje. V kazdem pripade ale dekuju.

Ma nekdo nejaky jiny napad?

nAS
Člen | 277
+
0
-

Finalgrab napsal(a):

Nevim jestli tvoji odpoved chapu spravne. $this->notInRole je naplnena spravne pri vytvareni formulare, navic je toto pole jenom zdrojem dat pro pole $select, ktere se vklada do formulare. Formular se vykresli spravne a hodnoty v nem jsou (v kodu stranky jsou value naplneny. Dokonce i POST data prenese, ale getValues uz hodnotu ze selectu nevrati.
Pochopil jsem spravne ze pri behu funkce, ktera zpracovava formular musim mit nekde docasne ulozene to pole? Neuchovava si ho nahodou $form od chvile, co jsem do nej to pole vlozil?

V jaké fázi plníš $this->notInRole? Při výpisu formuláře se createComponentAddRole() volá až když se formulář vykresluje, což je pravděpodobně ve fázi render. Když ale formulář odešleš, tak se ve fázi handle zpracovává stav formuláře. Tehdy ale ještě proměnná nemusí být naplněna. Zkus si schválně před odesláním formuláře přidat na začátek createComponentAddRole():

Debug::dump($this->notInRole);
exit;

Kdyžtak tu je něco o Životním cyklu presenteru.

Finalgrab
Člen | 15
+
0
-

odkazem volam actionZobrazUzivatele, kde naplnim promenou daneho presenteru notInRole nejakymi pravy. v sablone teto action se mi pak vykresluje formular, ktery bere data z promenne presenteru.

Jinak debug me vypsal objekt naplneny spravnymi daty. Jakt ma vliv faze renderovani na to, co se pak stane pri volani getValues? Jeste stale trochu nechapu, co se deje pri odeslani formulare, jak tam vypada zivotnost presenteru, protoze mam pocit, ze je to tam trochu jine oproti standartni zivotnosti.

nAS
Člen | 277
+
0
-

Tak to vypadá, že to máš správně. Tak to nevím, kde by mohla být chyba.

Ještě k těm fázím: odeslání formuláře je signál, takže se zpracovává ve fázi handle. Pokud ještě není formulář vytvořený, tak se nejprve musí vytvořit v createComponentXXX(). Proto se po odeslání formuláře vytváří v jiné fázi než při zobrazování. A v obsluze handle se kontroluje, zda položka která dorazila je jedna z možností, které byly definovány při tvorbě formuláře. Pokud není, tak se vrátí NULL, což by odpovídalo tvému problému, proto jsem si myslel, že by to mohlo být ono.

SquirrelCZE
Člen | 15
+
0
-

zdravim, muzu se zeptat zda nekdo pokrocil ohledne tohohle problemu? mam uplne stejny problem a tez si nevim rady :(, v HTML kodu jsou jednotlive selecty, ale v getValues() ne:(

Finalgrab
Člen | 15
+
0
-

nijak jsem nepokrocil. Nedostal jsem se k tomu od te doby. Ale stalo se mi to pouze na jednom miste.

Pari
Člen | 15
+
0
-

Mám stejný problém a opět jsem skončil někde v Nette zřejmě chybička… oprava?

Pari
Člen | 15
+
+1
-

Tak zdá se, že jsem na to přišel… základ je vždycky v životním cyklu.

Problém je ten, že Nette formuláře obsahují feature, která kontroluje zda souhlasí SELECT vygenerovaný a SELECT přijatý. Jelikož jsem SELECT generoval na základě $this->tyden tak tato proměnná nebyla dostupná ve fázi tohoto porovnání, které se děje právě v getValues. Řešením bylo nastavit $this->tyden jako persistent. Můj problém to vyřešilo a věřím že u vás to bude stejný důvod.

David Grudl
Nette Core | 8228
+
+1
-

Eventuelně lze použít SelectBox::getRawValue()