Nette 2.2.4 a setAction()

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

Zdravím,

updatnul jsem nette z 2.2.3 na 2.2.4 a přestali mi fungovat formuláře. V changelogu je napsané, že setAction() obchází „do“.

Teď potřebuji poradit jak z toho ven. Když setAction() dám pryč, tak mě to vytvoří totálně špatnou URL, co jsem tak zkoumal, tak ta URL se netvoří vůbec přes Router, který v mém případě je celkem složitý.

Jde do Forms nastavit Router nebo jak mám řešit tuto situaci?

Díky moc ;-)

David Grudl
Nette Core | 8139
+
0
-

V2.2.4 obsahuje fix na tento problém a při použití setAction už neodesílá parameter do.

Jak používáš setAction?

jasin755
Člen | 116
+
0
-
	protected function createComponentLoginForm(){
		$factory = new CustomerLoginFormFactory($this->user);
		return $factory->create($this->link('Account:login'),null,$this);
	}

a metoda create:

	public function create($action,$success_redirect_url = null,$presenter = null){
		$this->success_redirect_url = $success_redirect_url;
		$this->presenter = $presenter;

		$form = new \Nette\Application\UI\Form();
		$form->setAction($action);
		$form->addText('login',gettext('Email'))
				->addRule(Form::EMAIL,gettext('Zadaný email není validní'));
		$form->addPassword('password',gettext('Heslo'))
				->addRule(Form::FILLED,gettext('Bez zadaného hesla není možné přihlášení'));
		$form->addSubmit('enter',gettext('Přihlásit'));
		$form->onValidate[] = array($this,'success');

		return $form;
	}

Editoval jasin755 (12. 11. 2014 8:25)

David Grudl
Nette Core | 8139
+
0
-

Tohle je nepříjemná situace, protože ty a @blindAlley (viz) jste narazili na situaci, kdy oprava pro jednoho to rozbije druhému…

Problém je v tom, že odesílání formulářů Nette\Application\UI\Form na jiné URL je šedá zóna. Oni mají metodu setAction(), protože ji dědí od Nette\Forms\Form, ale v podstatě by se neměla používat. Protože UI\Form používá signály (parametr do) a framework nepodporuje volání signálů na jiném presenteru.

blindAlley hlásil jako chybu, že se při nastavení vlastního setAction() se parametr do v Nette 2.2 předává – nově se totiž posílá přes POST a změna action na to neměla vliv. Opravil jsem to, aby chování bylo zpětně kompatibilní s 2.0 a 2.1.

Tvé řešení naopak spoléhá na to, že i po změně setAction() se parametr do předá…

Jestli se nepletu, tak tento způsob používáš až od verze 2.2.x, je to tak? Protože v předchozích verzích by neměl fungovat.

Pak je asi správnější zachovat kompatibilitu s 2.0 a 2.1, tedy ponechat fix, který obsahuje 2.2.4.

Řešení by mělo být poměrně snadné: parametr do předat explicitně:

protected function createComponentLoginForm(){
    $factory = new CustomerLoginFormFactory($this->user);
    return $factory->create($this->link('Account:login', array('do' => 'loginForm-submit')),null,$this);
}

Omlouvám se, že se tohle v setinkové verzi rozbilo, taky jsem se na tom u jednoho projektu, co byl postavený až na v2.2, vypekl, ale nevím, jak lépe to vyřešit.

jasin755
Člen | 116
+
0
-

Tak ja prakticky, ani to setAction nepotřebuji. Továrnička je v BasePresenteru od kterého dědí ostatní, ale pokud tam setAction nedám, tak mě to vytvoří URL ve tvaru neco.cz/8+9?category_default_id=8 (z hlavy nevím jak přesně to bylo), místo toho aby tam bylo neco.cz/kategorie/8/9. Hodí to pak samozřejmě NoRoute.

Stačilo by, kdyby ty adresy vytvářel přes router podle mě.

David Grudl
Nette Core | 8139
+
0
-

To bude problém někde v definici rout.

jasin755
Člen | 116
+
0
-

To se mi nezdá, když si hodím dumpy do metody constructUrl(), tak se nikde poblíž toho formuláře nevolá.

David Grudl
Nette Core | 8139
+
0
-

Tak tu URL si asi nevymýšlí náhodně. Před vykreslením by se to mělo volat.

Šaman
Člen | 2635
+
+1
-

Narazil jsem taky na problém, tentokrál ale setAction('#anchor') používám jen pro narolování na daný formulář (který je až v patičce). Jako rychlý fix tedy stačí nepoužít action, ale rád bych to srolování vrátil co nejčistěji zpátky (ruční odesílání parametru do= se mi moc nezamlouvá). Máte nějaký tip, jak z toho ven, pls?

Casper
Člen | 253
+
0
-

@Šaman Nějak takto:

protected function createComponentSomeForm($name) {
        $form = $this->someFactory->create();
        $this->addComponent($form, $name);
        $form->action .= "#anchor";
}