Vyplňování selectboxu pomocí javascriptu

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

Ahoj,

vyplňuji formulářové pole pomocí javascriptu a mám na sobě závislé selectboxy. Teprve když se vybere hodnota z prvníha selectboxu, přidají se položky do druhého (stejně je to i mezi druhým a třetím).

Vše se vygeneruje správně, ale v momentě odeslání formuláře zmizí přidané které jsem javascriptem přidal a formulář nahlásí chybu – vyplňte formulářové pole.

formulář vypadá tako:

...
$region = $this->addSelect('regionID', 'Kraj', $this->regionDao->getRegions()->fetchPairs('id', 'name'));
$region->setPrompt("- Vyberte položku -");
$region->addRule(Form::FILLED, 'Prosím vyplňte kraj');
$region->setAttribute('class', 'regionID');

$district = $this->addSelect('districtID', 'Okres'); // vyplní se až javascriptem
$district->setPrompt("- Vyberte položku -");
$district->addRule(Form::FILLED, 'Prosím vyplňte okres');
$district->setAttribute('class', 'districtID');

$city = $this->addSelect('cityID', 'Město'); // vyplní se až javascriptem
$city->setPrompt("- Vyberte položku -");
$city->addRule(Form::FILLED, 'Prosím vyplňte město');
$city->setAttribute('class', 'cityID');
...

Myslím, že to má nějakou souvislost s tím, že prvky selectboxu generuji až na klientovi. Když udělám místo

$district = $this->addSelect('districtID', 'Okres');

toto

$district = $this->addSelect('districtID', 'Okres', $districts);

a pak prvky smažu a znovu naplním javascriptem, toto pole pak projde. Můžete mi prosím někdo poradit co s tím? Díky moc.

David Matějka
Moderator | 6445
+
+1
-

viz moje dnesni odpoved u jineho topicu: https://forum.nette.org/…mular-a-ajax#…

Jeriiii
Člen | 21
+
0
-

Díky Davide, moc mi to pomohlo. Kdyby ještě někdo narazil na podobný problém, nastíním řešení. Předem upozorňuji, že to jde dost přes ruku a že se tím rozhodně práci neušetříte. Pokud chcete něco snadného, použijte nějakou již hotovou komponentu. A teď to řešení s javascriptem:
Nesmíte vůbec nette nechat kontrolovat selectboxy, tedy:

//zakomentujte
//$district->addRule(Form::FILLED, 'Prosím vyplňte okres');
//$city->addRule(Form::FILLED, 'Prosím vyplňte město');

a to je už první problém, protože si musíte napsat vlastní javascriptovou kontrolu. Formulář vám ale už půjde alespoň odeslat.
Jenže nette vám ve $form->getValues() nic nevrátí. Je to z důvodu, že jste tam ty hodnoty neměli v době vyrendrování formuláře. Nette si jednoduše myslí, že je to chyba a radši vám je nepředá. Jde je ale vytáhnout přes $form->getHttpData():

$values->cityID = $form->getHttpData()['cityID'];
$values->districtID = $form->getHttpData()['districtID'];

A to je celé.
(více méně jsem jen zjednodušil návod od http://www.zeminem.cz/…t-select-box)

duke
Člen | 650
+
0
-

Nezkoušel jsem, ale možná by také stačilo rozšířit třídu SelectBox a změnit chování metod getValue a setValue (odstranit tu kontrolu vůči definovaným položkám) a toto rozšíření pak použít.

Tj. nějak takto:

class UnrestrictedSelectBox extends Nette\Forms\Controls\SelectBox
{
	public function setValue($value)
	{
		$this->value = $value === NULL ? NULL : key(array((string) $value => NULL));
		return $this;
	}

	public function getValue()
	{
		return $this->value;
	}
}
David Matějka
Moderator | 6445
+
0
-

@Jeriiii tyjo ten „hack“ s $this[$name] = $form; nefunguje? :) imho by mohl.. ja to teda nezkousel, ale celkem se mi to libi. zitra na to mrknu.

ziskavani pres getHttpData se mi totiz moc nelibi…

mrtnzlml
Člen | 140
+
0
-

Koukám, že je to stále aktuální problém… (-:

Aktualizoval jsem demo, které je funkční: https://github.com/…t-select-box

duke
Člen | 650
+
+1
-

Jinak pokud je mi známo, tak zápis:

$form = new UI\Form;
$this[$name] = $form;

… není žádný hack, ale naprosto legitimní záležitost. Dokonce ani není nutné dělat to takto oklikou, nýbrž stačí prosté:

$form = new UI\Form($this, $name);