Jak vkládat přes AJAX inputy do formuláře?

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

Jak řešit přidání položek do formuláře přes AJAX. Vyberu v selectu jednu kategorii a podle toho co vyberu, tak potřebuji aby se doplnili nějaké atributy, či-li podle nich bude libovolný počet, buď selectů, textarea nebo inputů.

Samozřejmě je bez problémů vložím do formuláře, ale už po odeslání tam samozřejmě logicky není.

Jiří Nápravník
Člen | 710
+
0
-

Zkusím přeformulovat, když nikdo neodpvídá.

Mám select – v něm vyberu nějakou kategorii. A ta kategorie má nastaveno, že mohu vyplnit dvě textarey a jeden select. Tak naslouchám na onchange a v handle přidám ty 2 textarey a select.

Pak když kliknu na submit button, tak je dostanu jen přes getHttpData()

Problém je tu ale v tom, že když mám v tom formuláři ještě například Replicator, tak když kliknu na přidání pro další containery, tak se mi samozřejmě ztratí ty přidané textareay a selecty.

Jak na to?

norbe
Backer | 405
+
0
-

Tak asi si ty data budeš muset někde ukládat (nejjednodušeji asi v hidden inputu) a pak to podle toho znovu vytvořit?

Líp se samozřejmě bude radit, když sem hodíš konkrétní kód..

Jiří Nápravník
Člen | 710
+
0
-

Do hidden pole to nepujde asi, protoze nevim predem, co vse tam bude. Tady je osekany kod toho handleru co pridava ty inputy:

		$parameters = $this->categoryFacade->getParametersForCategoryIds($categoryIds);
		$container = $this['form-parameters'];
		foreach ($parameters as $parameter) {
			if ($parameter->getType() === TYPE_SELECT) {
				$items = array_map(function($item) {
					return $item->getName();
				}, $parameter->getParameterValues());
				$container->addSelect($parameter->getId(), $parameter->getName(), $items);
			} elseif ($parameter->getType() === TYPE_TEXT) {
				$container->addText($parameter->getId(), $parameter->getName());
			} elseif ($parameter->getType() === TYPE_TEXTAREA) {
				$container->addTextarea($parameter->getId(), $parameter->getName());
			}
		}

Me ted napadlo udelat to tak, ze v attached se podivam, jake kategorie byly vybrany a podle nich pridam uz tam tyhle parametry a pripadn z httpData doplnim. To by nemuselo byt tak spatne a mohlo fungovat ne?

Zax
Člen | 370
+
0
-

Co takhle na vybranou kategorii použít persistentní parametr a podle něj pak tvořit formulář? Neboli přesunout ten kód z handlu do továrny a v handlu akorát nastavovat parametr… to by mohlo jít, ne?

norbe
Backer | 405
+
0
-

Já to dělám tak, že co parametr, to řádek v replicatoru. Pří změně kategorií se ajaxem vytvoří parametry, které dosud neexistují a invaliduje se to… Při dalším odeslání si to replicator načte sám.

Jiří Nápravník
Člen | 710
+
0
-

Zatím se mi zdá, že to v attached funguje…

@Zax Dobrý nápad, to by dle mě mohlo fungovat, problém je, že těch kategorií mohu navolit více, ale to je detail, bude persistentní pole. I když mě teď napadá jedna věc tam asi fungovat nebude, když už budu mít nějaký parametr nastavený, tak se nepředvyplní, protože formulář se vygeneruje sice s dobrými parametry, ale ne asi předvyplněnými.

@norbe replikátor jsem přemýšlel, nějak použít, ale nenapadlo mě vůbec jak. Replikátor vytváří přeci jen další počet existujícíh kontejnerů ne? Můžeš kdyžtak nějak naznačit kódem?

Editoval Jiří Nápravník (9. 10. 2014 13:27)

Zax
Člen | 370
+
0
-

Jiří Nápravník napsal(a):
I když mě teď napadá jedna věc tam asi fungovat nebude, když už budu mít nějaký parametr nastavený, tak se nepředvyplní, protože formulář se vygeneruje sice s dobrými parametry, ale ne asi předvyplněnými.

Nejsem si jistý, zda rozumím… ale nešlo by to vyřešit třeba pomocí array_merge? ;-)

norbe
Backer | 405
+
0
-

@JiříNápravník Vtip je v tom nepoužívat createOne(), ale prostě jen přistoupit k $propertyContainer[$property->id]. Id parametru se prostě použije jako název řádku/kontejneru, který obsahuje daný parametr..

akadlec
Člen | 1326
+
0
-

To co bys měl použít by měly být závislé select boxy ne? Ten replikátor máš pak mimo tyto podmíněné prvky? Pokud jo tak si invaliduj jen snippet co bude obalovat ten konkrétní replikátor a tak se ti nerozbije celý ten form co máš vygenerovaný (teda pokud to děláš ajaxem ;))

Jiří Nápravník
Člen | 710
+
0
-

@norbe asi jsem natvrdly ale moc nepobiram, nebyl by pls kousek kodu:-)

norbe
Backer | 405
+
0
-

Rychlý nástřel zhruba takto:

public function onFormAttached($form) {
	$categoryIds = $form['categories']->getValue();
	$this->parameters = $this->categoryFacade->getParametersForCategoryIds($categoryIds)->fetchPairs('id');
	$parameters = $form->addDynamic('parameters', $this->createParameterRow);
	foreach(array_keys($this->parameter) as $parameterId) {
		$form['parameters'][$parameterId]; // pokud existuje, nic se nestane, pokud ne vytvoří se..
	}
}

public function createParameterRow($container) {
	if(!isset($this->parameters[$container->name])) {
		return;
	}
	$parameter = $this->parameters[$container->name];
	switch($parameter->type) {
	...
	}
}

Ještě by asi bylo dobré pomocí getHttpData dotáhnout do $this->parameters parametry, které tam zůstali z dříve vybraných kategorií, případně ty kontainery unsetnout…

Edit: V podstatě to samý půjde i bez replicatoru:

$parameters = $form->addContainer('parameters');
	foreach(array_keys($this->parameter) as $parameterId) {
		$row = $form['parameters']->addContainer($parameterId);
		$this->createParameterRow($row);
	}

Editoval norbe (9. 10. 2014 20:26)

norbe
Backer | 405
+
0
-

@JiříNápravník Pokročil jsi nějak?

Jiří Nápravník
Člen | 710
+
0
-

@norbe Díky za upřesnění. Pokdu jsem to dobře pochopil, tak to vlastně mám nějak podobně. Handler přidá inputy. A pak mám v attached, že mrknu na zvolenou aktegorii a podle ní sestavím případně inputy. Asi to tak nechám, aztím to funguje:-)