Jak nastavit výchozí hodnotu pro select po selhání validace

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

Ahoj. Mám velice jednoduchý formulář s jedním selectem sloužící pro výběr stránek. V selectu je několik položek, které se občas mění. Chová se to tak, že pokud třeba vyberu položku „5“, která však není dostupná po novém renderování formuláře, tak nette nastaví NULL, protože se ta hodnota už nenachází v tom seznamu a tudíž to bere jako nesprávné. Já bych chtěl toto chování změnit tak, aby místo NULL nastavoval první položku ze seznamu. Jak to udělat?

22
Člen | 1478
+
0
-

Nestačí ve zpracování dát podmínku, když je to NULL, ať se nastaví ta a ta hodnota?

vasek125
Člen | 34
+
0
-

Teoreticky stačí, ale je to nesystémové řešení. Myslel jsem, že toto by mohlo být nějak ve fw vyřešeno, ale nevím jak – dokumentace je zoufale málo a po prozkoumání těch tříd jsem také nepřišel na to jak to udělat. Navíc jsem se nikde nedočetl, zda se nette takto bude chovat i v příštích verzích – aby to najednou místo NULL ty hodnoty prostě nezačalo z pole vymazávat apod.

22
Člen | 1478
+
0
-

Pošli kód, čeho chceš vlastně dosáhnout.. beztak to bude souviset se životním cyklem presenteru

vasek125
Člen | 34
+
0
-

Používám jen Forms.

...

$pages_array = array();
for ($i=0; $i <= ($groups_count/1000); $i++) {
	$pages_array[$i] = $i+1;
}

$form->addSelect('page', 'Stranka', $pages_array)->getControlPrototype()->onchange("this.form.submit()");

...

$page = 0;
if ($form->isSubmitted() && $form->isValid()) {
	$form_values = $form->getValues();
	if (isset($form_values['page']))
		$page = $form_values['page'];
	else
		$page = 0;
}

Chci tu část s isset nahradit něčím hezčím, co by fungovalo i v budoucích vydáních nette. Teda jestli něco takového existuje. Něco jako addCondition(~Form::FILLED)->setValue(‚0‘) ....., ale conditions neumožňují nastavovat hodnoty.

Filip Procházka
Moderator | 4668
+
0
-

Ukážeme si několik triků, ok?

Tomu prvnímu se říká range

// $pages_array = array();
// for ($i=0; $i <= ($groups_count/1000); $i++) {
//         $pages_array[$i] = $i+1;
// }
$pages_array = range(0, $groups_count/1000);
// Pokud je v tom cyklu ta $i+1 schválně, pak třetí argument range nastavuje kroky, takže dosaď dvojku

$form->addSelect('page', 'Stranka', $pages_array)
	->getControlPrototype()->onchange("this.form.submit()");

Tomu druhému ternární operátor a třetímu Nette\Callback.

protected function createComponentNejakyForm()
{
	$form = new Form();
	// nastavení prvků formuláře

	$form->addSubmit('send', 'Odeslat');
	$form->onSubmit[] = callback($this, 'NejakyFormSubmitted');
	return $form;
}

// formulář zavolá tuhle metodu sám, pokud je odeslaný a validní a předá jí sebe
public function NejakyFormSubmitted(Form $form)
{
	$values = $form->values;
	$values['page'] = $values['page'] ?: 0; // když nic neobsahuje, dosadí se nula
	// zpracování hodnot...
}
vasek125
Člen | 34
+
0
-

Range mi nepomůže, nejjednodušší je použití cyklu – třetí parametr mi moc platný nebude. Nedělám kroky 0, 2 …, ale 0 ⇒ 1, 1 ⇒ 2, … Nette callbacky v tomto kontextu vůbec nepoužívám, protože vždy chci zobrazit formulář, takže na to nemám žádné speciální funkce. K tomu ternáru – přebývá mi tam jedna podmínka else, tak se zdá, že je ternár jednodušší. Nicméně aby to správně fungovalo, mělo by to být isset($values[‚page‘]) ? $values[‚page‘] : 0, už proto kdyby v dalších releasech nette místo null proměnnou zahazoval.

smasty
Člen | 90
+
0
-

@vasek125: Ale veď range() ti vytvorí presne to.

$array = range(1, 5);
// Vytvorí toto:
array(1, 2, 3, 4, 5)
// A to je to isté ako to tvoje: (keďže polia sa indexujú od 0).
array(
  0 => 1,
  1 => 2,
  2 => 3,
  3 => 4,
  4 => 5
)
Filip Procházka
Moderator | 4668
+
0
-

vasek125 napsal(a):

Range mi nepomůže, nejjednodušší je použití cyklu – třetí parametr mi moc platný nebude. Nedělám kroky 0, 2 …, ale 0 ⇒ 1, 1 ⇒ 2, …

Nemáš pravdu, ale asi jsem tě trochu zmátl a špatně si přečetl tvůj script. Kdyby jsi, jak psal smasty, napsal jako první argument 1, né 0, bude se to chovat jak potřebuješ

Nette callbacky v tomto kontextu vůbec nepoužívám, protože vždy chci zobrazit formulář, takže na to nemám žádné speciální funkce.

Tahle věta vůbec, ale vůbec nedává smysl ;) Nette callbacky na formuláři dělají přesně to, co potřebuješ.

K tomu ternáru – přebývá mi tam jedna podmínka else, tak se zdá, že je ternár jednodušší. Nicméně aby to správně fungovalo, mělo by to být isset($values[‚page‘]) ? $values[‚page‘] : 0, už proto kdyby v dalších releasech nette místo null proměnnou zahazoval.

To je naprostá hloupost. Proč by to někdo dělal?

uestla
Backer | 799
+
0
-

vasek125 napsal(a):

Nette callbacky v tomto kontextu vůbec nepoužívám, protože vždy chci zobrazit formulář, takže na to nemám žádné speciální funkce.

Callbacky se neboj používat, jen pokud používáš formuláře samostatně bez Nette\Application, nezapomeň po definici zavolat

$form->fireEvents();