get a AppForm – jak na to?

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

Ahoj,
byl nějaký posun v možností využití metody GET v AppForm? Jak na to? Mám komponentu, která pracuje s metodou SET dobře. Jak to obecně předělat na GET, aby to fungovalo?

Předem díky.

MartinJanda
Člen | 60
+
0
-

Ještě abych to upřesnil.

Tady ve fóru jsem vyčetl, že lze udělat hidden ‚do‘ kam vložit jmenoKomponenty-jmenoFormulare-submit. Problém, který přetrvává je přepisování persistentních GET parametrů. Jak to vyřešit?

phx
Člen | 651
+
0
-

Tato cast je kapku nedoresena. Osobne to resim tak, ze odesilam metodou POST a pote provadim toto:

			$persisten = array(
				'fromDate',
			);

			foreach($persisten as $one) {
				if (!isset($form[$one])) continue;
				$value = $form[$one]->value;
				$this->$one = $value;
			}
			$this->redirect('this');

Coz prevede mnou definovane persistenti parametry z formulare do presenteru a presmeruje sam na sebe.

Pouzivam to napr pri filtrovani tabulky kde vsechny parametry filtru jsou persistentni v presenteru. Kdyby fungoval GET jen bych pomoci formulare menil ony persistentni parametry, ale v soucasne chvili musim takto:(

Patrik Votoček
Člen | 2221
+
0
-

a neměl by ten redirect bejt s 303jkou?

Editoval vrtak-cz (22. 5. 2009 11:25)

phx
Člen | 651
+
0
-

A v cem by to bylo lepsi? V tech cislech presmerovani se kapku ztracim.

Patrik Votoček
Člen | 2221
+
0
-

Koukni sem a možná pochopíš… :-) http://latrine.dgx.cz/…ani-pod-http

phx
Člen | 651
+
0
-

Pekny:)

Takze koukam zte skoro vsude v App bych mel mit 303.

Ha koukam ze ji tam mam:) Ona je totiz vyhcozi:))

public function redirect($code, $destination = NULL, $args = array())
	{
		if (!is_numeric($code)) { // first parameter is optional
			$args = $destination;
			$destination = $code;
			$code = /*Nette\Web\*/IHttpResponse::S303_POST_GET;
		}

		if (!is_array($args)) {
			$args = func_get_args();
			if (is_numeric(array_shift($args))) array_shift($args);
		}

		$presenter = $this->getPresenter();
		$presenter->redirectUri($presenter->createRequest($this, $destination, $args, 'redirect'), $code);
	}
Patrik Votoček
Člen | 2221
+
0
-

Lol tak teď jsi mě dostal!!! Sem myslel že tam je 301. (Ne nadarmo se říká myslet znamená … vědět)

Edit: teď musím přepsat celou APP já protože všude mám zbytečně 303 a tam kde by měly být 301 tak tam nejsou. ;-(

Editoval vrtak-cz (22. 5. 2009 11:27)

MartinJanda
Člen | 60
+
0
-

phx: díky, to řeší problém přepisování persistentních parametrů.

Jako problém ale zůstává samotný POST. Prostě mám požadavek na umožnění kroku zpět, tam kde to jde. Třeba takový datagrid s parametry v URL a bez žádosti o znovu zaslání při použití tlačítka zpět…

Jako dá se bez toho přežít, ale bohužel to mám mezi požadavky :(

phx
Člen | 651
+
0
-

Tak leda nacist si URL odkazu.

$url = $this->link(...);

Parsnout z toho persistentni parametry,

$pole = parse_url($url);
// ...

ktere pak narvat do hidden policek v AppFrom.

PetrP
Člen | 587
+
0
-

phx napsal(a):

$pole = parse_url($url);
// ...

OT: parse_url zapouzdruje v Nette třída Uri

Ale pro získání persistentích paremetrů to je podle mě dost nepoužitelné.

Možná experimentovat s PresenterComponent::getPersistentParams() a postupně si je vytahovat z Presenter::$params

phx
Člen | 651
+
0
-

Pri pouziti $this->link(...) se clovek nemusi starat o to zda tam ten parametr ma ci nema byt (pri vychozi hodnote v URL neni). A navic se tam umisti i nepersistentni parametry typu do=…

Pokud by tam clovek dal vsechny tak Nette provede canonizaci pomoci presmerovani. Coz je mozna nezadouci.

PetrP
Člen | 587
+
0
-

Mno ono to co chceš není získávaní perzistentních parametrů, ale získaní query. Protože perzistentní parametr může být i mimo query.

$uri = new Uri($url);
parse_str($uri->query,$query);
$uri->query = '';
print_r($uri->getAbsoluteUri(), $query);

Stejně by ale bylo nejlepší kdyby pro to david dodělal podporu ;]

David Grudl
Nette Core | 8218
+
0
-

Mělo by to být vyřešené v revizi 346

hjr
Člen | 24
+
0
-

Pokud jsou persistentní parametry pole, nastávají problémy. Tím, že se celé pole rozepíše do hidden položek a poté je ve formuláři multiselect se stejným názvem a hranatými závorkami, dojde k duplikaci hodnot v odeslaném poli. Možná to vysvětluju trochu kostrbatě, takže příklad:

Mějme persistentní parametr PRD. Je to pole, například (1,2,3). ConventionalRenderer vloží do hidden polí PRD[0]=1, PRD[1]=2, PRD[2]=3. Ve formuláři se vyskytuje select multiple s názvem PRD[], který má vybrané options podle hodnot pole. Pokud ve formuláři nic nezměním, všechno se mi zdvojí, protože se odešlou hidden položky a pak hodnoty ze samotného selectu. Po odeslání formuláře a přesměrování budou v hidden polích samozřejmě už hodnoty PRD[0]=1, PRD[1]=2, PRD[2]=3, PRD[3]=1, PRD[4]=2, PRD[5]=3 a tak dále.

Ono se to vlastně děje i když proměnná není pole, ale potom samozřejmě další odeslané hodnoty původní přepíší a všechno je OK, nic se nezdvojuje.

Přemýšleli jsme o možných řešeních a jako nejlepší se nám jeví nevypisovat hodnoty parametru do hidden pole, pokud je na toto jméno parametru navázán prvek formuláře:

ConventionalRenderer.php:247 nebo 248

$sep = ini_get('arg_separator.input');
foreach (explode($sep ? $sep[0] : '&', $uri[1]) as $param) {
	$parts = explode('=', $param, 2);
	$bname = $name = urldecode($parts[0]);
	// bare name - jmeno bez hranatych zavorek
	if (($sqbr = strpos($bname, '[')) !== FALSE)
	{
		$bname = substr($bname, 0, $sqbr);
	}
	// hidden element pridame jen pokud neexistuje ve formulari prvek naseho jmena
	if (!$this->form->getComponent($bname, false))
	{
		$s .= Html::el('input', array('type' => 'hidden', 'name' => $name, 'value' => urldecode($parts[1])));
	}
}

Ovšem kolega Honza tu poznamenává – a já s ním souhlasím – že tohle by se mělo dít někde ve vyšší vrstvě tak, aby se i ostatní případné renderery chovaly korektně. Vyšší vrstva by se na tohle měla připravit, změnit action a tiše do formuláře vložit hidden položky pomocí addHidden.

Editoval hjr (16. 9. 2009 17:55)

David Grudl
Nette Core | 8218
+
0
-

Pokud proměnná není pole, tak už ji to nepřepíše ale vynechá, je tam test if (!isset($this->form[$name])) (implementováno před pár dny).

Ono to samozřejmě není ideální – vhodnější by bylo testovat getHtmlName(). Tvé řešení zase počítá jen s jednorozměrným polem. V tuto chvíli už nemám sil na vytvoření dokonalého algoritmu ;)

S tou vrstvou je to celkem ožehavé – pokud by to řešil přímo Form, tak tím způsobem, že rozparsuje URL a vytvoří nové HiddenField s příslušnými hodnotami. Otázka je, jestli to nebude mít nějaké nechtěné vedlejší efekty. Vyšší vrstvy, jako je třeba presenter, to dělat nemůžou, protože takovéto míchání parametrů a prvků formuláře nepřipouštějí.

hjr
Člen | 24
+
0
-

Vida, tak to jsem ve fóru předtím nenašel. Každopádně můj návrh řešení byl opravdu jen návrh :)

Já teda ještě mrknu na tu aktuální verzi, odstraňování hranatých závorek jsem tam měl pro to, že se mi pole oindexuje a pak nesedí jméno proměnné, tj. "PRD[0]" !== "PRD[]".

Měla by to asi dělat třída Form. Jde o to, že pokud vyměníš renderer (což by mělo jít udělat, jak naznačuje IFormRenderer), budeš v něm muset znova implementovat tyhle věci, aby fungovala persistence. Což je podle mě dost WTF…

David Grudl
Nette Core | 8218
+
0
-

hjr napsal(a):

Já teda ještě mrknu na tu aktuální verzi, odstraňování hranatých závorek jsem tam měl pro to, že se mi pole oindexuje a pak nesedí jméno proměnné, tj. "PRD[0]" !== "PRD[]".

Jasně, jde jen o to, že může existovat PRD[EL][0] ad PRD[IM][], pričemž obojí je něco jiného.