Přenos dat mezi komponentou a samostatným formulářem

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

Zdravim,

chci se zeptat, jakým způsobem řešíte tento problém:

Mam komponentu v Presenteru, nicméně pokud odešlu formulář a přidám záznam do DB, tak potřebuji to konkrétní ID co se vytvořilo přenést do další funkce v úplně jiném presenteru → Pohoda:SendCustomerToPohoda.

Jakým způsobem to řešíte ?

    public function createComponentCustomerForm()
    {
        $form = $this->customerForm->create($this->customerId);
        $form->onSuccess[] = function () {
            $this->redirect('Pohoda:SendCustomerToPohoda', $this->customerId);
        };
        return $form;
    }
    public function formSucceeded($form, $values)
    {
        if ($this->customerId) {
            $address_id = $this->session->getSection('customer')->values['address_id'];
            $this->addressRepository->update($address_id, $values->address);
            unset($values->address);
            $this->customerRepository->update($this->customerId, $values);
        } else {
            $address_id = $this->addressRepository->insert($values->address);
            unset($values->address);
            $values->address_id = $address_id;
            $this->customerRepository->insert($values);
        }
    }
CZechBoY
Člen | 3608
+
+1
-

Udělej si event v komponentě a v parametru callbacku posílej to id.
cca nějak takto

presenter
{
	protected function createComponentAbc()
	{
		$component = $this->componentFactory->create();
		$component->onAdd[] = function($id) {
			// profit
		};

		return $component;
	}
}
component
{
	public $onAdd = [];

	protected function createComponentForm()
	{
		$form = new Form();

		$form->onSuccess[] = function($form, $values) {
			$address_id = $this->addressRepository->insert($values->address);
			unset($values->address);
			$values->address_id = $address_id;
			$id = $this->customerRepository->insert($values);

			$this->onAdd($id); // vyvolat event
		};

		return $form;
	}
}
kiCkZ
Člen | 153
+
0
-

Ještě by bylo dobré zmínit, že nemam formulář ve stejném souboru jako presenter.
Mam klasicky udělanou továrničku FormFactory a od přes DI CustomerForm, takže createComponent k dispozici nemam.

class CustomerForm
{
    public $customerId;

    /** @var \App\Forms\FormFactory */
    public $formFactory;

    /** @var  \Nette\Http\Session */
    private $session;

    /** @var \App\Model\CustomerRepository */
    public $customerRepository;

    /** @var \App\Model\SellerRepository */
    public $sellerRepository;

    /** @var \App\Model\AddressRepository */
    public $addressRepository;

    public function __construct(Session $session, FormFactory $formFactory, CustomerRepository $customerRepository, SellerRepository $sellerRepository, AddressRepository $addressRepository)
    {
        $this->formFactory = $formFactory;
        $this->session = $session;
        $this->customerRepository = $customerRepository;
        $this->sellerRepository = $sellerRepository;
        $this->addressRepository = $addressRepository;
    }

    public function create($id)
    {
        $this->customerId = $id;

        $form = $this->formFactory->create();

        $form->addGroup('Zákaznické údaje');

        $form->addMultiSelect('user_id', 'Obchodník:', $this->sellerRepository->getSellers())
            ->setAttribute('id', 'js-search-select2')
            ->setRequired('Prosím doplňte obchodníka');

        $form->addText('name', 'Název firmy (interní):')
            ->addRule($form::MAX_LENGTH, null, 50)
            ->setRequired('Prosím doplňte %label');

        $form->addInteger('ico', 'IČO:')
            ->setRequired('Prosím doplňte %label');

        $form->addText('dic', 'DIČ:')
            ->addRule($form::MAX_LENGTH, null, 50)
            ->setRequired('Prosím doplňte %label');

        $form->addButton('ares', 'Získat data z ARESU')
            ->setHtmlId('frm-customerForm-ares')
            ->setAttribute('class', 'pull-right')
            ->setOmitted();


        $form->addGroup('Adresa');
        $address = $form->addContainer('address');

        $address->addText('name', 'Název společnosti:')
            ->addRule($form::MAX_LENGTH, null, 100)
            ->setRequired();

        $address->addText('street', 'Ulice:')
            ->addRule($form::MAX_LENGTH, null, 50)
            ->setRequired();

        $address->addText('city', 'Město:')
            ->addRule($form::MAX_LENGTH, null, 50)
            ->setRequired();

        $address->addInteger('zip', 'PSČ:')
            ->addRule($form::MAX_LENGTH, null, 15)
            ->setRequired();

        $address->addText('country', 'Stát:')
            ->addRule($form::MAX_LENGTH, null, 50)
            ->setRequired();

        $form->addEmail('email', 'Email:')
            ->addRule($form::MAX_LENGTH, null, 50)
            ->setRequired(false);

        $form->addText('www', 'Webové stránky:')
            ->addRule($form::MAX_LENGTH, null, 50)
            ->setRequired(false);

        $form->addTextArea('note', 'Poznámky:')
            ->addRule($form::MAX_LENGTH, null, 50)
            ->setRequired(false);

        $form->addSubmit('save', 'Uložit zákazníka');

        $form->addProtection();

        $form->onSuccess[] = [$this, 'formSucceeded'];

        return $form;
    }

Editoval kiCkZ (2. 5. 2018 8:17)

CZechBoY
Člen | 3608
+
+1
-

Nemuzes to jeste obalit do komponenty? Usetril bys presenterou sablonu (pokud renderujes automaticky tak bys teda neusetril nic…) a mohl vyuzivat eventy.
I s tim automatickym renderem bys nemusel resit sablonu, jen by se zavolalo $this[‚form‘]->render() v render metode komponenty.

kiCkZ
Člen | 153
+
0
-

CZechBoY napsal(a):

Nemuzes to jeste obalit do komponenty? Usetril bys presenterou sablonu (pokud renderujes automaticky tak bys teda neusetril nic…) a mohl vyuzivat eventy.
I s tim automatickym renderem bys nemusel resit sablonu, jen by se zavolalo $this[‚form‘]->render() v render metode komponenty.

Kam přesně pak umísťuješ tu metodu $this[‚form‘]->render() ? Udělal jsem nyní samostatnou komponentu, která má ICustomerFormFactory továrnu, nicméně i tak mam v presenteru šablonu form.latte a v ní ten control.

Druhá věc, jakým způsobem mohu předat to customerID přímo do formuláře, abych ověřil, zda ID existuje a podle toho provedl příslušný krok v tom processForm ?

CZechBoY
Člen | 3608
+
+1
-
class FormComponent extends Nette\Application\UI\Control
{
	private $formFactory;

	public function __construct(CustomerFormFactory $formFactory)
	{
		$this->formFactory = $formFactory;
	}

	protected function createComponentForm()
	{
		return $this->formFactory->create();
	}

	public function render()
	{
		$this->getComponent('form')->render();
	}
}