Odeslání formuláře uvnitř komponenty způsobí ztrátu parametru v url

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

Zdravím,

mám formulář uvnitř komponenty a na stránku formuláře přistupuji přes takovouto url acl/privilege/store/1. Problém je, že pokud odešlu na této stránce formulář, tak se mi url změní na acl/privilege/store/?do=privilegeForm-privilegeForm-store. Ztratí se mi tedy z url číslo 1, což je v tomto případě parametr id. Mohl bych označit parametr id v presenteru jako persistent, ale to se mi potom zobrazuje i v akcích jako je list, a to nechci. Spíš by mě zajímalo, proč se to chová takto a jak ten parametr do té url dostanu jinak než pomocí persistent parametru. Osobně bych čekal, že se nové parametry připojí za stávající a ne že se přemažou.

Za pomoc děkuji.

Kód jsem pro přehlednost ořezal.

final class ResourcePresenter extends BasePresenter
{
	protected function createComponentResourceForm()
	{
		return new ResourceFormControl();
	}
}

class ResourceFormControl extends Control
{
	public function render()
	{
		$this->template->setFile(dirname(__FILE__) . '/templates/resourceForm.latte');

		$this->template->render();
	}

	protected function attached($presenter)
	{
		parent::attached($presenter);

		if (!$this['resourceForm']->isSubmitted()) {
			$resourceId = $presenter->getParameter('id', NULL);

			$this->resourceFormSetDefaults($this['resourceForm'], $resourceId);
		}
	}

	protected function createComponentResourceForm()
	{
		$form = new ResourceForm();

		$form->onSuccess[] = callback($this, 'resourceFormSubmitted');

		return $form;
	}

	protected function resourceFormSetDefaults($form, $resourceId = NULL)
	{
	}

	public function resourceFormSubmitted(ResourceForm $form)
	{
	}
}

final class ResourceForm extends Form
{
	public function __construct()
	{
		parent::__construct();

		$this->create();
	}

	protected function create()
	{
		$this->addGroup('Zdroj');
		$this->addText('name', 'Identifikátor')
			->setRequired('Vyplňte identifikátor.');

		$this->addText('title', 'Název')
			->setRequired('Vyplňte název.');

		$this->addTextArea('description', 'Komentář');

		$this->addProtection();

		$this->addSubmit('save', 'Uložit');
	}
}

Editoval darthcz (26. 7. 2013 20:48)

Oli
Člen | 1215
+
0
-

a presmerovavas na konci zpracovani formulare? Myslím, že by mohlo pomoct něco jako:

public function resourceFormSubmitted(ResourceForm $form)
{
	//zpracovani formulare

	$this->redirect('this');
	//nebo
	$this->getPresenter()->redirect('this');
}

Pokud ani jedno nepomuže, tak by mělo pomoct uložit si do proměnné to id a pak presmerovat na stejnou adresu jako ze ktere jsi odesilal formular. Neco jako:

class SomePresenter extends \BasePresenter
{
	private $editId;

	function actionDefault($id)
	{
		$this->editId = $id;
	}
}

class ResourceFormControl extends Control
{

    public function resourceFormSubmitted(ResourceForm $form)
    {
	$this->getPresenter()->redirect('Presenter:action', $this->getPresenter()->editId);
    }
}

Psal jsem vsechno z hlavy, ale nejak takhle me to funguje…

darthcz
Člen | 113
+
0
-

Přesměrování funguje v pohodě. Jde o to, že se mi po submitu formuláře ztratí ten parametr id, takže nemůžu upravit záznam.

Jasně šlo by to přes hidden, ale já chci vědět, proč ten parametr zmizí a jak to udělat, aby nezmizel… Nejlíp je to vidět, když při odeslání nastane chyba. Je blbý mít před odesláním formuláře adresu resource/5 a po odeslani resource/?do=resourceForm-submit bez té pětky :)

frosty22
Člen | 373
+
0
-

Ale Oli nic s hidden nepsal, to je sice taky možnost, ale to neuváděl. Problém je, že ta proměnná ID se nedrží, jelikož nemá důvod se držet – aby se držela buď by to musel být parameter handlu nebo action, což ty nemáš, ty přímo čteš z presenteru.

Jednoduše pointa je v podstatě v tom mít třeba v tom presenteru:

<?php
public function actionDefault($id) { ... }
?>

čímž už nette ví, že parametr $id k něčemu slouží a nechá ho tam …

BTW: Velice jednoduše řečeno, už je půl třetí není čemu divit.

Edit:
V podstatě, to co psal Oli v tom druhém příkladu … jen tedy já bych nepřistupoval k proměnné presenteru z komponenty, to je závislost, která by tam být neměla.

Správně bych udělal v té komponentě setter na ID a potom v tom actionDefault udělal:

<?php
public function actionDefault($id) {
   $this["resourceForm"]->setResourceId($id);
}
?>

A potom tedy namísto v attached bych resourceFormSetDefaults volal v tom setteru… hruba tak…

Editoval frosty22 (27. 7. 2013 2:40)

darthcz
Člen | 113
+
0
-

Máte pravdu, úplně jsem to nejprve nepochopil :-/ actionStore($id) vyřešilo problém. Měl jsem tuto metodu prázdnou, takže jsem ji smazal a netušil jsem, že to způsobí tento problém, ale dává to smysl, takže v ní budu předávat parametr do komponenty.

Děkuji moc :)