2 submit tlačítka s 2 různými callbacky, ale volá se vždy jen jeden

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

Ahoj,

mám NEajaxový formulář, který obsahuje 2 submit tlačítka. V závislosti na tom, kterým tlačítkem formulář odešlu, chci provést něco jiného. Z nějakého důvodu se však vždy volá pouze v pořadí druhý nadefinovaný callback. PROČ?

Takhle vypadá samotný formulář:

<?php
class MyForm extends FormFactory
{
	/** @return Form */
	public function createComponentForm()
	{
		$form = new Form($this, 'form');

		//nejake inputy...
		//...

		$form->addSubmit('check', 'XXX')
            ->onClick[] = [$this, 'processForm1']
		;
		$form->addSubmit('reserve', 'YYY')
			->onClick[] = [$this, 'processForm2']
		;

		return $form;
	}

	public function processForm1(\Nette\Forms\Controls\SubmitButton $button)
	{
		$form = $button->getForm();
		$values = $form->getValues();

		dump('check'); // NIKDY se nevypise
	}

	public function processForm2(\Nette\Forms\Controls\SubmitButton $button)
	{
		$form = $button->getForm();
		$values = $form->getValues();

		dump('reserve'); // vypise se VZDY
	}
}
?>

Toto je rodičovská komponenta:

<?php
class FormFactory extends UI\Control
{
	//..

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

        $this->template->setFile(__DIR__ . '\templates\@form.latte');
		$this->template->render();
	}

	function setRenderer($form, $labelContainerClass = 'col-sm-5', $controlContainerClass = 'col-sm-5')
    {
		$form->getElementPrototype()->class[] = 'form-horizontal';

		$renderer = $form->getRenderer();
		$renderer->wrappers['controls']['container'] = NULL;
		$renderer->wrappers['pair']['container'] = 'div class="form-group"';
		$renderer->wrappers['pair']['.error'] = 'has-error';
		$renderer->wrappers['control']['container'] = 'div'.($controlContainerClass ? ' class="'.$controlContainerClass.'"' : '');
		$renderer->wrappers['label']['container'] = 'div class="control-label'.($labelContainerClass ? ' '.$labelContainerClass.'"' : '').'"';
		$renderer->wrappers['control']['description'] = 'span class="help-block"';
		$renderer->wrappers['control']['errorcontainer'] = 'span class="help-block"';
	}
}
?>

Formulář vytvářím pomocí služby:

<?php
interface IMyFormFactory
{
	/** @return MyForm */
	public function create();
}
?>

Zde je Presenter:

<?php
class DefaultPresenter extends AdminBasePresenter
{
	/** @var IMyFormFactory @inject */
	public $myFormFactory;

	protected function createComponentMyForm()
	{
		$form = $this->myFormFactory->create();
		return $form;
	}
}
?>

Co způsobuje, že se volá stále tentýž callback? Něco přehlížím?
Díky za rady!
D.

CZechBoY
Člen | 3608
+
0
-

Možná blbá otázka ale… neklikáš prostě pořád jen na tlačítko „reserve“? Nevypisuješ to tlačítko třeba dvakrát v latte a neklikáš na to druhé v domnění, že to je to druhý?
Můžeš poslat ještě tu šablonu @form.latte?

btw. pokud chceš mít komponentu z formuláře tak můžeš v render metodě volat bez jakékoliv šablony jen

$this['form']->render();

Editoval CZechBoY (2. 5. 2016 17:50)

dady
Člen | 12
+
0
-

CZechBoY napsal(a):

Možná blbá otázka ale… neklikáš prostě pořád jen na tlačítko „reserve“? Nevypisuješ to tlačítko třeba dvakrát v latte a neklikáš na to druhé v domnění, že to je to druhý?
Můžeš poslat ještě tu šablonu @form.latte?

Ne, opravdu klikám na obě tlačítka, vždy se ale volá stejný callback.
Šablonu mám zatím stupidní, obsahuje jen tu komponentu + statické html, které jsem pro zjednodušení vypustil:

{control form}

btw. pokud chceš mít komponentu z formuláře tak můžeš v render metodě volat bez jakékoliv šablony jen

$this['form']->render();

Chci, aby má formulářová komponenta měla vlastní šablonu, protože samotný formulář bude následně obklopen statickým HTML, abych dosáhl určitého vzhledu.

CZechBoY
Člen | 3608
+
0
-

Hele někde máš problém, mně to bez změny tvého kodu funguje jak bych očekával.

  1. Kliknu na XXX → „check“
  2. Kliknu na YYY → „reserve“

Jediné co jsi neuvedl je šablona presenteru. Pro jednoduchost jsem použil pouze

{block content}
	{control myForm}
{/block}

Dále je možné, že nepoužíváš Nette\Application\UI\Form, ale jen obyčejný Nette\Forms\Form.

Editoval CZechBoY (3. 5. 2016 9:58)

dady
Člen | 12
+
0
-

CZechBoY napsal(a):

Jediné co jsi neuvedl je šablona presenteru. Pro jednoduchost jsem použil pouze

{block content}
	{control myForm}
{/block}

Tak tady je zakopaný pes! V této šabloně mám v podstatě jen to, co jsi napsal, ALE… navíc je zde bootstrap validace, která je příčinou problému.

<script>
	$('#frm-myForm-form').bootstrapValidator({
		//...validacni podminky
	});
</script>

Zatím nevím přesně, co s tím, ale asi bude potřeba zajistit, ať se při odeslání formuláře javascriptem (bootstrapValidatorem) odešlou také informace o tom, které tlačitko submit vyvolalo.
Pokud někdo tuší, jak to inteligentně řešit, nepohrdnu radou :o)

Dále je možné, že nepoužíváš Nette\Application\UI\Form, ale jen obyčejný Nette\Forms\Form.

Pro úplnost – UI\Form používám.

Moc díky za rady!

CZechBoY
Člen | 3608
+
0
-

Nevim jestli si procházel jejich examply, ale maj tam přímo návod na formulář s více submit tlačítkama
http://formvalidation.io/…ple-buttons/

dady
Člen | 12
+
0
-

Popisované problémy souvisely s použitím knihovny bootstrapValidator 0.4.5
S verzí 0.5.2 již vše funguje správně.

@CZechBoY: Díky za tvůj čas a nasměrování.

Dady

GEpic
Člen | 566
+
0
-

PS: Pro Nette existuje https://componette.org/…-validation/

A s BootStrapem funguje skvěle! Stačí si nastavit jak a kde se která hláška bude vypisovat a zbytek pořešíš přímo při tvoření formu v php.

Editoval GEpic (11. 5. 2016 23:58)