Formular z presenteru presunout do vlastniho souboru

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

Ahoj, mám v presenteru funkční formulář na přidávání produktů, ale potřebuji tam přidat další formulář a už by presenter nebyl tak přehledný.

Mám to zatím takto

presenter

public function createComponentFormProductAdd(){
	return new \FormProductAdd($this->database);
}

app/forms/FormProductAdd.php

<?php

use Nette\Forms\Form;

class FormProductAdd extends Nette\Object {

	private $database;

    public function __construct(Nette\Database\Context $database)
    {
        $this->database = $database;
        $this->createForm();
    }

    public function createForm(){
		$form = new Nette\Application\UI\Form;

		$form->addText('name', 'Název:')
				->setRequired('Zadejte prosím jméno');

		...

		$form->addSubmit('send', 'Přidat');

		$form->onSuccess[] = $this->process;
		return $form;
	}




public function process($form){
		try {

			...

		$this->flashMessage('Produkt vložen.');
	        /* $this->redirect('this'); */

	    } catch(Exception $e) {
            $form->addError('Při vkládání se vyskytla chyba.'/*.$e*/);

            if ($e instanceof \Nette\Application\AbortException) {
                throw $e;
            }
        }
	}

}

Ale hlásí mi to chybu

Nette\UnexpectedValueException
Method App\BProductsPresenter::createComponentFormProductAdd() did not return or create the desired component.

Pročpak ? :-)

Tohle řešení mi přijde dobré v tom, že z toho můžu rovnou udělat továrničku pokud bych to chtěl v app použít vícekrát.

Editoval Skywalk3r (16. 2. 2014 16:02)

Tabetha
Člen | 140
+
0
-

Skus dat

return $this->createForm()

Editoval Tabetha (16. 2. 2014 16:03)

Skywalk3r
Člen | 8
+
0
-

Tabetha napsal(a):

Skus dat return $this->createForm() …

Vrátí to stejnou chybu :P

Šaman
Člen | 2666
+
0
-

Ty ale v té továrničce v presenteru vytváříš instanci typu Nette\Object, takže ti to skutečně nevytvoří komponentu (což metoda createComponentXxx zjistí a reklamuje).

Ukázku funkčního řešení najdeš třeba tady.
Ty tam navíc budeš mít samozřejmě i ten konstruktor kvůli předání závislosti na db.

Pokud bys nechtěl tvořit komponentu, tak bys musel mít ten formulář jako poděděný Form a nebo, to je to, co jsi možná chtěl na začátku vytvořit si továrničku, ale pak v presenteru jen nevytvářej tovární třídu, ale zavolej její konkrétní metodu, která ti vrátí nakonfigurovanou instanci Form.

Editoval Šaman (16. 2. 2014 16:14)

Skywalk3r
Člen | 8
+
0
-

Šaman napsal(a):

Ty ale v té továrničce v presenteru vytváříš instanci typu Nette\Object, takže ti to skutečně nevytvoří komponentu (což metoda createComponentXxx zjistí a reklamuje).

Ukázku funkčního řešení najdeš třeba tady.
Ty tam navíc budeš mít samozřejmě i ten konstruktor kvůli předání závislosti na db.

Pokud bys nechtěl tvořit komponentu, tak bys musel mít ten formulář jako poděděný Form a nebo, to je to, co jsi možná chtěl na začátku vytvořit si továrničku, ale pak v presenteru jen nevytvářej tovární třídu, ale zavolej její konkrétní metodu, která ti vrátí nakonfigurovanou instanci Form.

Děkuji, teď už mi to funguje až na jednu drobnost.. pokud chci vykreslit ten formulář pomocí výchozího formátování.. tak na {$form->render()} mi to spadne že $form neni definované ? :-)

Jinak mi šlo pouze o přesun kódu, což by vlastně šlo vyřešit includem což by ale bylo nehezké :-)
Není mi ale jasná jedna věc.. proč ta metoda createComponent (alias továrnička) kontroluje jestli vypisuje objekt Control když

zde https://forum.nette.org/…nebo-tovarna do ní jde Nette/Object

a zde https://doc.nette.org/cs/forms#… do ní jde UI/Form

a ani u jednoho to nespadne ?

Pro moje účely bude asi nejlepší ta varianta s UI/Forms, protože tam nemusím vytvářet speciální šablonu pro tu Componentu.. za ten odkaz díky dá se z toho dobře naučit jak vytvářet komponenty :-)

Skywalk3r
Člen | 8
+
0
-

Tak jsem se pokusil podle toho UI/Form navodu a hazi to nejakou chybu ale netusim co s tim.

<?php
use Nette\Application\UI\Form;
class FormProductAdd extends Nette\Application\UI\Form {

	private $database;

    public function __construct(Nette\Database\Context $database)
    {
        $this->database = $database;
        return $this->createForm();
    }

    public function createForm(){
		$form = new Nette\Application\UI\Form;

		$form->addText('name', 'Název:')
				->setRequired('Zadejte prosím jméno');

		...

		$form->addSubmit('send', 'Přidat');

		$form->onSuccess[] = $this->process;
		return $form;
	}

public function process($form){

		$this->flashMessage('Produkt vložen.');
	        $this->redirect('this');

	}

}

a presenter

public function createComponentFormProductAdd(){
		return new \FormProductAdd($this->database);
	}

pricemz mi to hazi chybu

Notice
Trying to get property of non-object

v souboru File: …\vendor\nette\nette\Nette\Forms\Form.php:206

Editoval Skywalk3r (16. 2. 2014 17:11)

Milo
Nette Core | 1283
+
0
-

Nevoláš konstruktor předka. Btw. hezké čtení https://doc.nette.org/…tion/factory

Šaman
Člen | 2666
+
0
-

Jestli chceš jenom přesunout továrničku a obslužnou metodu, tak:

  1. Vytvoř si FooFormFactory. Ta bude mít metodu (často create()), která vytvoří, nakonfiguruje a vrátí hotový formulář.
  2. Tuto si zaregistruj jako službu a normálně ji předej (injectuj) do presenteru (řekněme do proměnné fooFormFactory).
  3. V metodě createComponentFoo() pak zavoláš něco jako return $this->fooFormFactory->create();.

Jinak ta moje ukázka vytváří komponentu s formulářem, nikoliv samotný formulář. Proto ti nefungoval renderer.

Skywalk3r
Člen | 8
+
0
-

Šaman: díky, už to funguje :-)