Jak na neodeslaný checkbox?

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

Ahoj,

mám formulář, v kterém je chceckbox. Po odeslání formuláře chci na základě jeho odeslání něco udělat. Ovšem pokud je nezaškrtnutý, dostanu výjimku Component ‚password_change‘ is not attached to ‚Form‘.

Nejspíš to bude tím, že nezaškrtnutý checkbox se neposílá. Jenže jak potom aplikovat kontrolu?

<?php
if (isset($form['password_change'])) {
	...
}
?>

Snažil jsem se hledat ve fóru, ale nenašel jsem nic kloudného.

Ondřej Mirtes
Člen | 1536
+
0
-

Ukaž kód, Nette pracuje korektně i s nezaškrtnutým checkboxem.

BigCharlie
Člen | 283
+
0
-
<?php
//	Definice formuláře v modelu
static function initEditForm($presenter)
{
	$form = new AppForm($presenter, 'editForm');
	$form->addText('username', 'Uživatelské jméno', 20, 20);
	....
	$form->addCheckbox('password_change', 'Změna hesla')
        	->setDefaultValue(TRUE);
	$form->onSubmit[] = array(
		$presenter,
		'save'
	);
	$form->addSubmit('search', 'Uložit');
	return $form;
}

//	Presenter
public function actionAdd()
{
	$form = $this->initModel()->initEditForm($this);
	$this->template->form = $form;
}

public function save($form)
{
	if (isset($form['password_change'])) {
		unset($form['password_change']);
	}
	parent::save($form);
}
?>

Pokud v metodě save udělám dump $form->getValues(), mám ve výpisu i password_change = FALSE. Už začínám tušit problém – formulář není dělán přes továrničku?

Takže si nejspíš rovnou odpovím sám. Iniciace formuláře do presenteru do továrničky. A všechno bude v pořádku.

Pletu se?

JakubKohout
Člen | 92
+
0
-

jojo udělej to na továrničku (všude na forum najdeś nějakej příklad) a taky metodě save používej $values = $form->getValues(); a pak pracuj už přímo s polem $values

BigCharlie
Člen | 283
+
0
-

Tak jsem to dal do továrničky. Hláška nezmizela, objevuje se stále. A zjistil jsem záhadnou věc. Takhle vypadá presenter (vypichuju jen to podstatné).

<?php
public function createComponentEditForm($name)
{
	$form = new AppForm($this, $name);
	$form->addText('username', 'Uživatelské jméno', 20, 20);
	$form->addCheckbox('password_change', 'Změna hesla')
       		->setDefaultValue(TRUE);
	$form->addPassword('password', 'Heslo', 32, 32)
		->addConditionOn($form['password_change'], Form::EQUAL, TRUE)
		->addRule(Form::FILLED, 'Heslo musí být vyplněno!');
	$form->addPassword('password_confirm', 'Kontrola hesla', 32, 32);
		->addConditionOn($form['password_change'], Form::EQUAL, TRUE)
		->addRule(Form::EQUAL, 'Hesla se neshodují!', $form['password']);
	$form->onSubmit[] = array(
		$this,
		'save'
	);
	$form->addSubmit('search', 'Uložit');
	return $form;
}

public function save($form)
{
	if (!$form['password_change']) {
		unset($form['password']);
	}
	if (isset($form['password_change'])) {
		unset($form['password_change']);
	}
	unset($form['password_confirm']);
	parent::save($form);
}
?>

Původní hláška je způsobena pravidly, nastavenými u pole password. Pokud je zakomentuju, hláška zmizí. Takže je to kombinace dvou problémů. Tohle je ten první.

Ten druhý: V metodě save se unset($form['password']) nikdy neprovede. Ostatní unset se provedou, tenhle ne. Potom se mi vyhodí logicky hodí výjimka při ukládání do DB.

Pokud zruším podmínku a dám ho tam natvrdo, provede se. Napadá někoho důvod?

Editoval BigCharlie (31. 10. 2009 14:11)

JakubKohout
Člen | 92
+
0
-

Ten první problém nevidím, ale tomu druhému problému:
Přistupuješ k instanci AppForm ale ta sama o sobě nemá hodnoty, musíš je zavolat pomocí metody getValues()

public function save(AppForm $form)
{
	$values = $form->getValues();
        if (!$values['password_change']) {
                unset($values['password']);
        }
        if (isset($values['password_change'])) {
                unset($values['password_change']);
        }
        unset($values['password_confirm']);
        parent::save($values);
}

A doporučil bych po odeslání formuláře přesměrovat stránku ;)

Editoval dRaGen (31. 10. 2009 14:08)

BigCharlie
Člen | 283
+
0
-

Bože já jsem pitomec.

<?php
if (!$values['password_change']) {
	unset($values['password']);
}
?>

Tohle samozřejmě nikdy neproběhne, protože ja se sice chci ptát na hodnotu, jenže ta tam před zavoláním getValues není.

BigCharlie
Člen | 283
+
0
-

dRaGen: Díky, koukám, že jsi byl o něco rychlejší.

AD přesměrování – jasná věc, jen jsem si říkal, zda mi díky přesměrování nějaké chyby neutíkají, takže jsem ho dočasně pozastavil.

Editoval BigCharlie (31. 10. 2009 14:16)