filtrovací formulář jako komponenta

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

Zdravím,
chci se zeptat jak řešíte tohle. Mám jednoduchý filtrovací formulář jehož výsledkem by měl být redirect zpět (this) s parametry z formuláře. Formulář mám jako komponentu, protože ho používám ve více presenterech. Nevím jak v komponentě zavolat redirect. Díky

Jan Suchánek
Člen | 404
+
0
-

Redirect je v dokumentaci myslím popsaný.

Redirect si můžeš v presenteru na komponentu navěsit přes událost.

F.Vesely
Člen | 369
+
0
-

Mne se osvedcil tento pristup https://jiripudil.cz/…yby-doctrine Sice je to pro Doctrine, ale s mensi upravou to funguje i bez ni.

rumcais1
Člen | 81
+
0
-

Používám komponentu dle Best practise

protected function createComponentForm()
    {
        $form = new UI\Form;
        // mohu použít $this->database
        $form->addText('rok');
        $form->addSubmit('send', 'Odeslat');
        $form->onSuccess[] = $this->processForm;

        return $form;
    }

    public function processForm($form)
    {
        // A tady bych chtěl něco takového
        $values = $form->getValues();
        $this->redirect('this', array('rok' => $values->rok));
    }

Editoval rumcais1 (20. 10. 2015 18:05)

Azathoth
Člen | 495
+
0
-

tak zkuste $this->presenter->redirect

Šaman
Člen | 2666
+
+1
-

rumcais1 napsal(a):

Používám komponentu dle Best practise

protected function createComponentForm()
    {
        $form = new UI\Form;
        // mohu použít $this->database
        $form->addText('rok');
        $form->addSubmit('send', 'Odeslat');
        $form->onSuccess[] = $this->processForm;

        return $form;
    }

    public function processForm($form)
    {
        // A tady bych chtěl něco takového
        $values = $form->getValues();
        $this->redirect('this', array('rok' => $values->rok));
    }

Tohle ale není podle best practise. Komponenta neumí redirectovat (není to úplně přesné, protože to může udělat přes $this->presenter->…) a ani by to umět neměla. Ona přece neví, jaká je struktura presenterů. Ona dokáže zpracovat hodnoty, třeba je uložit do db (má k dispozici model), ale v těch ukázkách se vždy redirectuje až v továrně v presenteru. Presenter už samozřejmě redirect umí a ten jediný ví, kam se má po zpracování přesměrovat. (Dokonce je běžné, že se po zpracování bude přesměrovávat pokaždé jinam. Třeba pokud slouží komponenta jako formulář jednou pro registraci uživate, podruhé v admin modulu pro přidání nového uživatele správcem a potřetí pro editaci uživatele. A i ta editace může být na více místech – frontend a backend. A zpracování bude vždy stejné, inputy taky, ale přesměrování a flashMessage budou pokaždé jiné.)

Editoval Šaman (20. 10. 2015 20:07)

rumcais1
Člen | 81
+
0
-
use Nette\Application\UI;


class RocnikForm extends Nette\Object
{

    /** @var \App\Model\Organizace @inject */
    public $organizaceModel;

    public function __construct(\App\Model\Organizace $organizace)
    {
        $this->organizaceModel = $organizace;
    }

    public function create()
    {
        $form = new UI\Form;
        $organizace = $this->organizaceModel->getData()->fetchPairs('zkratka', 'jmeno');
        $form->addSelect('org', 'Organizace:', $organizace)
                ->setPrompt('Zvolte organizaci')
                ->setRequired('Zvolte organizaci');
        $rok = array('2015' => '2015');
        $form->addSelect('rok', 'Rok', $rok)
                ->setPrompt('Zvolte organizaci')
                ->setRequired('Zvolte rok');
        $form->addSubmit('save', 'Odeslat');
        $form->onSuccess[] = array($this, 'rocnikFormSubmitted');


        return $form;
    }


    public function rocnikFormSubmitted(UI\Form $form) {
        $values = $form->getValues();
        $this->presenter->redirect('this', array('org' => $values->org,'rok' => $values->rok));
    }
}

vrací:
Nette\MemberAccessException

Cannot read an undeclared property RocnikForm::$presenter

Šaman
Člen | 2666
+
0
-

rumcais1 napsal(a):

vrací:
Nette\MemberAccessException

Cannot read an undeclared property RocnikForm::$presenter

Protože ty to nemáš ani jako komponentu, ale jen tovární třídu. Komponenta by presenter znala. Ale i tak nedoporučuji redirectovat přímo v komponentě, viz. můj minulý příspěvek. Nech to klidně takhle a ten redirect navěs až v presenteru.

rumcais1
Člen | 81
+
0
-

Já nevím, ale jak v presenteru z toho vytáhnout ty hodnoty.

David Matějka
Moderator | 6445
+
0
-

@Šaman

Komponenta neumí redirectovat […] a ani by to umět neměla

Umí a v tomhle pripade je i vhodne, aby to delala – tedy v pripade, kdy si drzis filtr v persistenich parametrech komponenty, jak to ukazuje Jiri Pudil na blogu.

@rumcais1 inspiruj se tim odkazovanym clankem , kdyz odeberu vsechny ty filtr tridy, query objecty apod., tak by to mohlo vypadat treba takhle:

class RocnikForm extends Nette\Application\UI\Control
{

	/** @persistent */
	public $rok;

	public function getFilter()
	{
		return array(
			'rok' => $this->rok,
		);
		//nebo strukturu, ktera ti bude vyhovovat
	}

    protected function createComponentForm()
    {
        $form = new UI\Form;
		....
        $form->addSelect('rok', 'Rok', $rok)
                ->setRequired('Zvolte rok')
				->setDefaultValue($this->rok);
        $form->addSubmit('save', 'Odeslat');
        $form->onSuccess[] = array($this, 'rocnikFormSubmitted');


        return $form;
    }


    public function rocnikFormSubmitted(UI\Form $form) {
        $values = $form->getValues();
        $this->redirect('this', array('rok' => $values->rok));
    }
}


class FooPresenter
{
	public function renderDefault()
	{
		$data = $this->fooModel->findBy($this['filter']->getFilter());
	}

	protected function createComponentFilter()
	{
		return ...->create(); //vytvorit treba tovarnou
	}
}
Darkling
Člen | 35
+
0
-

Ahoj, postupuj podle tohoto návodu https://doc.nette.org/…s/form-reuse najdeš tam i jak vytáhnout hodnoty v presenteru. Zjednodušeně řečeno:

komponenta

...
$this->onSuccess($form->getValues(), ...);
...

a v presenteru pak

$control->onSuccess[] = function ($values){
	// dostaneš se k $values
	$this->redirect('this');
};
duskohu
Člen | 778
+
0
-

Ahoj tu mas na to komponentu :NasExt/FilterFormControl
Tato ti zabezpeci aj redirect, a data v url si mozes filtrovat, napr datetime.