Multiplier & manuální vykreslení formuláře

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

Ahoj, používám Nette 2.0 a PHP 5.3.4. Pokouším se vytvořit pomocí multiplieru formulář, který se bude na stránce opakovat a rád bych ho renderoval po svém. Použití si můžete představit na stránce administrace ve výpisu článků, kde u každého bude formulář se skrytým polem, kde bude id článku a odesílacím, které bude mít za úkol ho smazat.

Mám následující kód:

Presenter

<?php
protected function createComponentDeleteContent($id) {
	$presenter = $this;

	return new \Nette\Application\UI\Multiplier(function($id) use ($presenter) {
			//$form = new \Projekt\Forms\AjaxForm($control, $id);
			$form = new DeleteContentForm();

			/*$form->id->setValue($id);*/
			/*$form->onSuccess[] = callback($presenter, 'deleteContent');*/

			return $form;
	});
}
?>

šablona, která volá multi-komponentu

{control "deleteContent-$content->id"}

formulář pro smazání

<?php
class DeleteContentForm extends Form
{


	public function __construct(IContainer $parent = null, $name = null) {
		parent::__construct($parent, $name);

		$this->_initForm();
	}

	private function _initForm() {

		$this->addHidden('id');
		$this->addSubmit('delete');

	    return $this;

	}

	public function render() {
		$template = $this->presenter->template;
		$template->setFile(__DIR__ . '/DeleteContentForm.latte');
		$template->render();
	}

}
?>

a nakonec latte, která by měla vykreslit samotný jeden formulář

{form deleteContent}

{input id}
{input delete}

{/form}

výsledkem tohoto kódu je, že dostanu MemberAccessException – Call to undefined method Nette\Application\UI\Multiplier::getElementPrototype()

Evidentně něco dělám špatně. Můžete mne prosím nasměrovat na řešení? Díky.

edit: formátování upraveno

Editoval xlilien (29. 2. 2012 12:55)

Filip Procházka
Moderator | 4668
+
0
-

V první řadě bych tě poprosil, koukni se na Texy a nauč se používat formátování příspěvků. Tohle je hrozné.

K věci:
Tohle se mi nelíbí, když už „kradeš“ šablonu presenteru, tak si ji naklonuj

class DeleteContentForm extends Form
{
	// ...

        public function render()
	{
                $template = clone $this->presenter->template;
                $template->setFile(__DIR__ . '/DeleteContentForm.latte');
                $template->render();
        }
}

a nakonec latte, která by měla vykreslit samotný jeden formulář

To máš předpokládám v šabloně DeleteContentForm.latte. Kvůli nedokonalosti ve formulářovém makru to tak jak to máš, udělat nemůžeš.

Máš tam jenom dvě políčka, takže, co takhle to zjednodušit?

	public function render()
	{
		parent::render('begin');
		echo $this['delete']->control;
		parent::render('end'); // hidden se vyrenderuje automaticky na konci
}

Tadá! A nemusíš řešit šablony.

Vojtěch Dobeš
Gold Partner | 1316
+
+1
-

Otázkou je, kde máš tu šablonu formuláře? Pokud je to spolu s makrem {control ...} v jednom souboru, tak to skutečně moc nedává smysl… Respektive tobě se v makru {form deleteContent} volá prostě $presenter['deleteContent']->getControlPrototype(), ale $presenter['deleteContent'] vrací celý Multiplier, ne jednotlivé formuláře v něm.

Myslím, že by mohlo fungovat {form deleteContent-$content->id}, přičemž {control ...} není potřeba volat vůbec.

xlilien
Člen | 27
+
0
-

HosipLan napsal(a):

V první řadě bych tě poprosil, koukni se na Texy a nauč se používat formátování příspěvků. Tohle je hrozné.

Omlouvám se, upraveno.

To máš předpokládám v šabloně DeleteContentForm.latte. Kvůli nedokonalosti ve formulářovém makru to tak jak to máš, udělat nemůžeš.

Přesně tak. Můžeš nějak rozvést tu „nedokonalost“? Jen abych věděl, o co se zhruba jedná.

Tadá! A nemusíš řešit šablony.

Tadá! A ono to funguje! Bezvadný, moc děkuju.

vojtech.dobes napsal(a):

Otázkou je, kde máš tu šablonu formuláře? Pokud je to spolu s makrem {control …} v jednom souboru,

ne, měl jsem to v odděleném souboru. Vyřešil jsem to HosipLanovo způsobem.

Ještě jednou děkuju.

Filip Procházka
Moderator | 4668
+
0
-

xlilien napsal(a):

Přesně tak. Můžeš nějak rozvést tu „nedokonalost“? Jen abych věděl, o co se zhruba jedná.

Když se koukneš na makro {control} (do kódu) tak zjistíš, že mu můžeš předat nejenom string, ale i objekt. Tohle {form} neumí, ale mohl by to umět. Potom by se dalo zapsat

$this->template->form = $this;
{form $form}
	...
{/form}

A bylo by, ale to nejde, protože {form} makro takovou konstrukci neumí. Muselo by se tam předávat několik parametrů a jako $control objekt pro šablonu bys musel použít přímo presenter. To bys pak mohl rovnou vykreslovat takto, v šabloně presenteru

{foreach $nejakaId as $id}
	{form deleteContent-$id}
		{input id}
		{input delete}
	{/form}
{/foreach}

Což je rozumná alternativa :)