Jak nastavit výchozí hodnotu pro select po selhání validace
- vasek125
- Člen | 34
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?
- vasek125
- Člen | 34
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.
- vasek125
- Člen | 34
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
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
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.
- Filip Procházka
- Moderator | 4668
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
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();