Pridani promenne do action

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

Ahoj,

uzivatel mi prijde na stranku s promenou trebas ?foo=bar, a podle toho se vypise typ prihlasovaciho formular a dalsi casti stranky.. Pokud uzivatel ale zada spatne heslo, je presmerovan na stranku bez parametru. Da se nejak pridat do action promenna? Dekuji :)

VaKvas
Začátečník | 111
+
0
-

Melo by fungovat neco takoveho :

$form->action .= '?cosi=neco';
Semik
Backer | 135
+
0
-

Nezdá se mi to ale jako správné řešení.

pekelnik
Člen | 462
+
0
-

@semik: To se ti nezdá správně, protože je to nesmysl.

@neznalek: RTFM Persistentní parametry

Editoval pekelnik (8. 9. 2011 14:08)

VaKvas
Začátečník | 111
+
0
-

Pro jednorazove pouziti promene to lze prece pridat do action ne? Treba i pres

$form->setAction(..);
Tharos
Člen | 1030
+
0
-

Jen doplním, že persistentní parametr zde ani není zapotřebí (a jenom kvůli tomuto bych jej asi osobně nepoužil, je s ním větší režie, vyžaduje další public proměnnou a celkově může vnášet nežádoucí chování jinde…). Zkus jednoduše následující:

class DefaultPresenter extends BasePresenter
{

	public function actionDefault($variant = null)
	{
		// ten argument $variant je důležitý
	}

	protected function createComponentForm($name)
	{
		$form = new \Nette\Application\UI\Form($this, $name);

		$variant = (int) $this->getParam('variant');
		if ($variant !== 2) {
			$form->addText('test', 'První formulář:');
		} else {
			$form->addText('test', 'Druhý formulář:');
		}

		$form->addSubmit('send', 'Odeslat');
	}

}

Editoval Tharos (8. 9. 2011 14:12)

Tharos
Člen | 1030
+
0
-

@VaKvas: Tvé návrhy jdou všechny hrubě proti filosofii frameworku. :) Takhle by se v rámci aplikace předávat parametry skutečně neměly.

pekelnik
Člen | 462
+
0
-

@vakvas: kušuj!

@tharos: obávám se že tvůj příklad vnáší pouze zmatek do duše začátečníka… :)

<?php

// Takhle je to snad trochu srozumitelnější...

class DefaultPresenter extends BasePresenter
{
        public function actionDefault($variant = 'basic')
        {
                // ten argument $variant je důležitý
        }

        protected function createComponentForm($name)
        {
                $form = new \Nette\Application\UI\Form($this, $name);

                if ($this->getParam('variant') === 'basic') {
                        $form->addText('test', 'První formulář:');
                } else {
                        $form->addText('test', 'Druhý formulář:');
                }

                $form->addSubmit('send', 'Odeslat');
        }

}
?>

Editoval pekelnik (8. 9. 2011 14:23)

VaKvas
Začátečník | 111
+
0
-

Tharos napsal(a):

@VaKvas: Tvé návrhy jdou všechny hrubě proti filosofii frameworku. :) Takhle by se v rámci aplikace předávat parametry skutečně neměly.

Nj, to mas vlastne pravdu… blbej napad.. Ja to onehda nekde zahledl na foru, tak jsem si rikal, ze by to slo.. tak ne :-)

@pekelnik: nono !

Tharos
Člen | 1030
+
0
-

@pekelnik: Možná máš pravdu… Když ale já mám zase zkušenost, že persistentní parametry dokáží vnést zmatek do aplikace :). A pak taky jsem přesvědčen, že správné pochopení předávání parametrů v rámci aplikace je nezbytné pro nějaké trochu elegantnější používání Nette…

Zde hodně záleží na kontextu (třeba chce tu proměnnou mít opravdu ve všech akcích a pak jsou samozřejmě persistentní parametry na místě).

pekelnik
Člen | 462
+
0
-

@vakvas: myslíš si snad že URL /?do=formSubmit?cosi=neco je v pořádku?

VaKvas
Začátečník | 111
+
0
-

pekelnik napsal(a):

@vakvas: myslíš si snad že URL /?do=formSubmit?cosi=neco je v pořádku?

tak samozrejme „&“ .. omlouvam se !

pekelnik
Člen | 462
+
0
-

@vakvas: za předpokladu že v submit handleru toho formuláře přesměruješ $presenter->redirect('this') – což patří k dobrému zvyku – je tvé „řešení“ k ničemu tak jako tak ;)

VaKvas
Začátečník | 111
+
0
-

Ja se nepřu …
Ale prvni otazka byla, jak pri odeslani formu (do form action=„…“) lze pridat promenou..

Videl jsem to nekde, nezkousel, ale zkusil jsem pouze nasmerovat, me hned nekamenujte … ;)

Editoval VaKvas (8. 9. 2011 14:46)

pekelnik
Člen | 462
+
0
-

@tharos: pokud jde skutečně pouze o „variantu formuláře“ na jedné stránce (default) je tvé řešení lepší ;)

22
Člen | 1478
+
0
-

@Tharos: úplný souhlas, je to naprostá nezbytnost pochopit, jak lze v Nette „žonglovat“ s parametry ať už v rámci presenterů nebo presenter/template a zpět nebo presenter/control. Je to stejně důležité, jako pochopit životní cyklus presenteru. Bez toho v Nette ani rána :-)

neznalek
Člen | 60
+
0
-

pekelnik napsal(a):

@vakvas: kušuj!

@tharos: obávám se že tvůj příklad vnáší pouze zmatek do duše začátečníka… :)

<?php

// Takhle je to snad trochu srozumitelnější...

class DefaultPresenter extends BasePresenter
{
        public function actionDefault($variant = 'basic')
        {
                // ten argument $variant je důležitý
        }

        protected function createComponentForm($name)
        {
                $form = new \Nette\Application\UI\Form($this, $name);

                if ($this->getParam('variant') === 'basic') {
                        $form->addText('test', 'První formulář:');
                } else {
                        $form->addText('test', 'Druhý formulář:');
                }

                $form->addSubmit('send', 'Odeslat');
        }

}
?>

Ktera cast kodu prida parametr do action protoze se nic nestalo, jedine co to udele prepne formular a vytvorila se nova prazdna metoda actionDefault..

Persistentni parametr funguje velice pekne, ale tlaci se i do navigace.. A nejde odstranit redirectem..

Editoval neznalek (8. 9. 2011 16:01)

Tharos
Člen | 1030
+
0
-

@neznalek: V tom upraveném kódu od pekelnika je drobná chybka, ten argument $variant u akce default nemá mít výchozí hodnotu basic, ale null. On tu úpravu myslel dobře (s řetězci coby hodnotami je to celé možná o trochu pochopitelnější), ale bohužel to nepřepsal funkčně úplně na 100%. :)

Možná přece jenom vyzkoušej pro pochopení tu mou první variantu, ta funguje.

„Fígl“ je právě v argumentech té metody actionDefault. Je tento „fígl“ zdokumentovaný? Já ani nevím a možná proto je to tak matoucí.

Editoval Tharos (8. 9. 2011 16:41)

22
Člen | 1478
+
0
-

Pokud uzivatel ale zada spatne heslo, je presmerovan na stranku bez parametru. Da se nejak pridat do action promenna? Dekuji :)

já teda nevím, jestli rozumím úplně tomu problému, ale neměla by to řešit submit metoda, co se stane?

Bertram
Člen | 75
+
0
-

Ahoj teď jsem si uvědomil, že jsem nepochopil „nette-dosazování“ parametrů.
Co vím, je to, že z url se automaticky dosadí parametr do akce presenteru. Ale jak se teď dívám na ukázky výše, tak to vypadá, že to funguje i obráceně, pokud má parametr akce presenteru nastavenu výchozí honotu. Jak jinak by se objevil v getParam() , pokud by nebyl odeslán v url, jak bylo uvedeno v dotazu.
Předem děkuji za objasnění :)

Jan Endel
Člen | 1016
+
0
-

Jenom taková poznámka, v tomhle případě, kdy se v parametru předávají nějaké řetězce mě na základní programátorské učili využít konstanty namísto řetězců. :-)

Tharos
Člen | 1030
+
0
-

@pilec: Když jsem to měl u sebe rozepsané v IDE, psal jsem tak nějak automaticky třídní konstanty, ale pak jsem se rozhodl poslat to sem bez nich, protože začátečníka by IMHO jejich přítomnost mohla spíše zmást (třeba by mohla mít pocit, že se ten parametr předává právě díky těm konstantám).

Myslíš, že by jejich použití v tomto demonstrativním případě, kde se ta konstanta navíc používá jen jednou, bylo lepší?

Samozřejmě ideální by bylo mít v dané ukázce nejen třídní konstanty, ale i PHPDoc komentáře a PHPUnit testy, že ;).

Editoval Tharos (8. 9. 2011 19:18)

Jan Endel
Člen | 1016
+
0
-

No, ideálně přesně tak, což ovšem není kritika tebe :). Jenom jsem to považoval za vhodné dopsat, aby fórum vedlo člověka k co nejčistšímu řešení.

neznalek
Člen | 60
+
0
-

Klidne se priucim cistimu reseni.. Predtim jsem to resil pred sessoin ale musel jsem na hodne mistech osetrovat jeho vycisteni..

V tomto pripade se jedna o takovou specialni prihlasovaci metodu kde uzivatel dostane hash v mailu.. Kdyz klikne na odkaz tak se mu „predvyplni“ login a on zada pouze heslo. Hash slouzi pro zobrazeni nejakych verejnych informaci a po zadani hesla je muze editovat. Ovsem pokud zada spatne heslo, tak se obnovi stranka a hash se ztrati a musi se zadat heslo a login..

Pokud pouziju perzistentni parametr nejde hash nejde zrusit, pouze prepsat v adrese a to muze byt celkem problem pro nektere uzivatele..

Editoval neznalek (8. 9. 2011 20:53)

22
Člen | 1478
+
0
-

pesrsitentni parametr zrušíš přiřazením NULL

VaKvas
Začátečník | 111
+
0
-

neznalek napsal(a):

V tomto pripade se jedna o takovou specialni prihlasovaci metodu kde uzivatel dostane hash v mailu.. Kdyz klikne na odkaz tak se mu „predvyplni“ login a on zada pouze heslo. Hash slouzi pro zobrazeni nejakych verejnych informaci a po zadani hesla je muze editovat. Ovsem pokud zada spatne heslo, tak se obnovi stranka a hash se ztrati a musi se zadat heslo a login..

V tom pripade to vazne musi stacit reseni od Tharose

Prijdes na form, pokud je HASH formular bude pouze na heslo, pokud ne, tak tam hodis login a heslo ..

Editoval VaKvas (8. 9. 2011 20:58)

neznalek
Člen | 60
+
0
-

22 napsal(a):

pesrsitentni parametr zrušíš přiřazením NULL

Ano na to jsem taky prisel, ale je jednoduhsi na jednom pripade si parametr zapamatovat (prihlasovaci formular) na vsech ostatnich ho mazat (vsechny odkazy na webu).

Priklad @Tharos nefunguje, pouze rozdeli formular neprida parametr..

Editoval neznalek (8. 9. 2011 21:21)

Tharos
Člen | 1030
+
0
-

@neznalek: Ale funguje, akorát jsem vycházel z toho, co jsi psal… :)

neznalek napsal(a):

Ahoj,

uzivatel mi prijde na stranku s promenou trebas ?foo=bar, a podle toho se vypise typ prihlasovaciho formular a dalsi casti stranky.. Pokud uzivatel ale zada spatne heslo, je presmerovan na stranku bez parametru. Da se nejak pridat do action promenna? Dekuji :)

Když v tom mém případě přijdeš na stránku a přijdeš na ni s parametrem ?variant=1, vykreslí se Ti první formulář a po jeho odeslání jsi v metodě actionDefault a máš ten parametr variant k dispozici (má hodnotu 1). Když na tu stránku přijdeš s parametrem ?variant=2, vykreslí se Ti druhý formulář a po jeho odeslání jsi opět v metodě actionDefault a opět máš ten parametr variant k dispozici (má hodnotu 2).

Tak jsem to pochopil, že to chceš… Samozřejmě si ten parametr analogicky můžeš přejmenovat na foo a identifikátor varianty formuláře může být bar. :)

neznalek
Člen | 60
+
0
-

Aha jak proste.. Dekuji moc :)

neznalek
Člen | 60
+
0
-

Jeste jsem nasel takovou malou chybku.. Vlastne uzivatelsky panel mam jako control. A formular na prihlaseni vypada nejak takhle:

if ($this->hash === null) {
	$f->addText('email', 'E-mail', 15)->setRequired('Email is required')->addRule(Form::EMAIL, 'Email is not valid');
	$f->addPassword('password', 'Password')->setRequired('Password is required');
	$f->addSubmit('submit', 'Sign in');
} else {
	$f->addPassword('password', 'Password')->setRequired('Password is required');
	$f->addHidden('hash', $this->hash);
	$f->addSubmit('submit', 'Sign in');
	$f->addSubmit('reset', 'Remote hash')
		->setAttribute('class', 'cancelBtn')
		->setValidationScope(false)
		->onClick[] = callback($this, 'remoteHash');
}

//...
public function remoteHash($f) {
	$this->redirect('this', array('hash' => null));
}

Problem je ten se mi nedari vymazat hash z adresy. Po presmerovani ziskam adresu ve tvaru:
userBar-hash=a&hash=c.

Cela aplikace s sklada z vice formularu. V jednom se vytvori nabidka a ten je odeslal na druhy formular, ktery pokud obsahuje hash tak se zobrazi prislusny prihlasovaci formular..

Tharos
Člen | 1030
+
0
-

Bertram napsal(a):

Ahoj teď jsem si uvědomil, že jsem nepochopil „nette-dosazování“ parametrů.
Co vím, je to, že z url se automaticky dosadí parametr do akce presenteru. Ale jak se teď dívám na ukázky výše, tak to vypadá, že to funguje i obráceně, pokud má parametr akce presenteru nastavenu výchozí honotu. Jak jinak by se objevil v getParam() , pokud by nebyl odeslán v url, jak bylo uvedeno v dotazu.
Předem děkuji za objasnění :)

Pokusím se to vysvětlit následovně: zde se využívá toho, že jde o signál. Jak známo, při signálu se Nette snaží předávat všechny parametry, tj. ne jenom ty persistentní (jak je tomu u klasického přechodu mezi akcemi stejného presenteru).

Důležité pro pochopení je zde pole $params v presenteru. Nacházíme-li se v actionDefault a připíšeme-li do url parametr ?variant=1, Nette předá presenteru i tento „cizí“ parametr (tj. nemusí být nadefinován v routě) a ten jej poté má k dispozici právě v poli $params.

Pokud poté vytvoříme odkaz na signál, Nette se logicky pokusí předat i tento parametr, ale to, jestli jej nakonec někam předá závisí na tom, jestli jej „má kam dát“. Tím místem může být právě stejnojmenný argument cílové action metody. Pokud tam takový argument není, Nette prostě ten parametr zahodí. To, že by jej za každou cenu doplnilo do cílové url, nedělá.

Ta defaultní hodnota null znamená, že je ten argument nepovinný a dříve musel být u podobných konstrukcí parametr nadefinován jako nepovinný proto, aby šlo vyvolat danou akci i bez něj (pokud nebyl volitelný, byl prostě vyžadován a jeho nedodání končilo výjimkou). Všiml jsem si ale, že toto chování už je v Nette upravené a nyní už ta jeho nepovinnost není nezbytná, protože pokud současná verze Nette tu metodu volá a hodnotu toho argumentu nemá, dosadí za něj null. Takže v těch mých kódech by při použití aktuálního Nette (nevím přesně, kdy se ta změna odehrála a nechce se mi to hledat) už ten parametr jako nepovinný být nadefinován ani nemusel (i když já bych u toho asi zůstal, protože to přece jenom trochu zlepšuje pochopitelnost toho obratu).

22 napsal(a):

pesrsitentni parametr zrušíš přiřazením NULL

Pozor, tohle není úplně přesné. Persistentní parametr se zruší přiřazením jeho výchozí hodnoty (ta nemusí být a často ani není null).

Tohle je blbost, 22 má pravdu. :) Na výchozí hodnotu lze persistentní parametr nastavit i nastavením na null.

Editoval Tharos (9. 9. 2011 17:50)

22
Člen | 1478
+
0
-

@Tharos: moc tě nechápu teďkom.. NULL udělá to samé, jako výchozí hodnota, tedy potlačí persitentní proměnnou v URL. Samozřejmě fakticky má pořád výchozí hodnotu a je jedno, jestli je definovaná nebo ne.

Tharos
Člen | 1030
+
0
-

@22: No jo, pravdu máš. :) Takže přiřazením null se dá nastavit na výchozí hodnotu také (a tedy docílit jeho nepředávání v URL). To jsem nevěděl, díky za doplnění! Měl jsem zafixované, že toho lze dosáhnout pouze nastavením na výchozí hodnotu.

Editoval Tharos (9. 9. 2011 17:50)

22
Člen | 1478
+
0
-

@Tharos: to je u Nette normální jev, viz. včera já. Asi ani po 3 letech nebudeme vědět všechno :-)

Bertram
Člen | 75
+
0
-

@Tharos

Děkuji za vysvětlení, ale k pochopení si to budu muset ještě párkrát přečíst :)

neznalek
Člen | 60
+
0
-

Nevite jak teda odstanit ten parametr protoze redirectem mi to nejde..

neznalek
Člen | 60
+
0
-

Zkousel jsem i:

<?php
unset($this->parent->hash);
$this-parent->hash = null;
?>

Hash stejne se porad drzi v adrese, formular je umisteny v Controlu.