get a AppForm – jak na to?
- MartinJanda
- Člen | 60
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
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
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
a neměl by ten redirect bejt s 303jkou?
Editoval vrtak-cz (22. 5. 2009 11:25)
- phx
- Člen | 651
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
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
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 :(
- PetrP
- Člen | 587
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
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
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 ;]
- hjr
- Člen | 24
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
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
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
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.