Nefunkční přidávání kontejnerů u replikátoru

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

Zdravím,

snažím se vytvořit funkční formulář s dynamickým počtem prvků s využít komponenty. Mám trochu problém se zpracováním. Popíšu to na kód, který je napsaný v sandboxu této komponenty.

Základní formulář

	protected function createComponentMyForm($name)
	{
		$form = new Form;

		$presenter = $this;
		$invalidateCallback = function () use ($presenter) {
			/** @var \Nette\Application\UI\Presenter $presenter */
			$presenter->invalidateControl('usersForm');
		};

		// jméno, továrnička, výchozí počet
		$replicator = $form->addDynamic('users', function (Container $container) use ($invalidateCallback) {
			$container->currentGroup = $container->form->addGroup('člověk', FALSE);
			$container->addText('name', 'Jméno');
			$container->addText('email', 'Email')->setRequired();

			$container->addSubmit('remove', 'Smazat')
				->addRemoveOnClick($invalidateCallback);

			$container->addSubmit('removeAjax', 'Smazat Ajaxem')
				->setAttribute('class', 'ajax')
				->addRemoveOnClick($invalidateCallback);
		}, 1);

		/** @var \Kdyby\Replicator\Container $replicator */
		$replicator->addSubmit('add', 'Přidat dalšího')
			->addCreateOnClick($invalidateCallback);

		$replicator->addSubmit('addAjax', 'Přidat dalšího Ajaxem')
			->setAttribute('class', 'ajax')
			->addCreateOnClick($invalidateCallback);

		$form->addSubmit('send', 'Zpracovat')
			->onClick[] = callback($this, 'MyFormSubmitted');

		$form->addSubmit('sendAjax', 'Zpracovat Ajaxem')
			->setAttribute('class', 'ajax')
			->onClick[] = callback($this, 'MyFormSubmitted');

		$this[$name] = $form;
		$form->action .= '#snippet--usersForm';
		return $form;
	}

Jde mi o to, že pokud bych chtěl použít zpracování formuláře, které je uvedené v návodu u komponenty tedy

public function FormSubmitted(Form $form)
{
    foreach ($form['users']->values as $user) { // hodnoty formulářového prvku
        dump($user['name'] . ' ' . $user['surname']);

        foreach ($user['addresses'] as $address) { // pracujeme s polem hodnot
            dump($address['city']);
        }
    }
}

musel bych upravit odeslání formuláře takto

	$form->addSubmit('send', 'Zpracovat');
	$form->onSuccess[] = $this->FormSubmitted;

Pokud je to takhle upravím, tak mi nefunguje přidávání dalších prvků ve formuláři a vždy když kliknu na tlačítko „Přidat dalšího“ tak se celý formulář odešle ke zpracování. Vyzkoušej jsem všechny kombinace které mě napadli, ale nic mě k výsledku nevedlo.

Díky za každou radu.

2k
Člen | 15
+
0
-
	$form->addSubmit('send', 'Zpracovat');
	$form->onSuccess[] = $this->FormSubmitted;

Proč tam nenecháš onClick?

David Matějka
Moderator | 6445
+
0
-

pouzivam neco na tenhle zpusob:

public function FormSubmitted(Form $form)
{
    if(!$form['submit']->isSubmittedBy()) {
        return;
    }
    //zpracovani
}
quiced
Člen | 85
+
0
-

2k napsal(a):

	$form->addSubmit('send', 'Zpracovat');
	$form->onSuccess[] = $this->FormSubmitted;

Proč tam nenecháš onClick?

No protože když ho tam nechám tam mi to vypisuje tuto chybu

Argument 1 passed to SendPresenter::AddInvoiceFormSubmitted() must be an instance of Nette\Application\UI\Form, instance of Nette\Forms\Controls\SubmitButton given

což znamená, že bych upracování musel udělat nějak tak jak je uvedeno v sandboxu

public function FormSubmitted(SubmitButton $button){
}

problém u toho zpracování je, že nevím jak s ním pracovat.

quiced
Člen | 85
+
0
-

matej21 napsal(a):

pouzivam neco na tenhle zpusob:

public function FormSubmitted(Form $form)
{
    if(!$form['submit']->isSubmittedBy()) {
        return;
    }
    //zpracovani
}

Díky za vyřešení mého problému, stačilo tam vložit tvoji podmínku a už to funguje tak jak potřebuju.

Ještě jednou díky.

2k
Člen | 15
+
0
-

problém u toho zpracování je, že nevím jak s ním pracovat.

Co třeba skoro stejně?

$values = $button->getForm()->getValues();
quiced
Člen | 85
+
0
-

2k napsal(a):

problém u toho zpracování je, že nevím jak s ním pracovat.

Co třeba skoro stejně?

$values = $button->getForm()->getValues();

Ještě jednou díky za pomoc všem. To co jsi ty napsal na to jsem přišel taky, ale problém je že s tím neumím pracovat. Narazil jsem i tu toho zpracování, které je uvedeno v návodu tedy:

foreach ($form['users']->values as $user) { // hodnoty formulářového prvku
    dump($user['name'] . ' ' . $user['surname']);

    foreach ($user['addresses'] as $address) { // pracujeme s polem hodnot
        dump($address['city']);
    }
}

Můžete mi ještě poradit jak ideálně dostat ta data do modelu, kde mám funkci pro ukládání do databáze.

Díky

2k
Člen | 15
+
0
-

Můžete mi ještě poradit jak ideálně dostat ta data do modelu, kde mám funkci pro ukládání do databáze.

Do presenteru si ho můžeš předat z configu pomocí „inject“:

public function injectUsers(DB\UserRepository $users)
{
	$this->userRepository = $users;
}

popř. přes context ve „startupu“:

protected function startup()
{
	parent::startup();

	$this->users = $this->presenter->context->createUsers();
}

a v submitu už jen:

$this->users->update($id, $values['user'])

Pokud chceš rovnou pole z hodnot, tak:

$values = $button->getForm()->getValues(TRUE);

Víc toho najdeš tady: https://doc.nette.org/cs/quickstart

Draffix
Člen | 146
+
0
-

Můžete mi ještě poradit jak ideálně dostat ta data do modelu, kde mám funkci pro ukládání do databáze.

Využívejme toho DI když už je k dispozici. Jak to tam optimálně nacpat najdeš tady