formular nereaguje na callback

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

Dobry den,

po odoslani sa formular znovu vykresli s hodnotamy ktore som zadal, ale nic sa nedumpne

<?php

class FaqPresenter extends BasePresenter
{
  function createComponentAddForm()
  {
    $form = new Form;
    $form->addText('email', 'E-mail')
	    ->addRule(Form::FILLED, 'Zadajte e-mail')
	    ->addRule(Form::EMAIL, 'E-mail je neplatný');
    $form->addText('nadpis', 'Nadpis')
	    ->addRule(Form::FILLED, 'Zadajte nadpis');
    $form->addTextarea('otazka', 'Otázka')
	    ->addRule(Form::FILLED, 'Zadajte otázku');
    $form->addSubmit('pridatOtazku', 'Pridať otázku');
    $form->onSubmit[] = callback($this, 'formSubmitted');
    return $form;
  }

  function formSubmitted($form)
  {
    Debug::dump($values = $form->getValues());
  }
}

?>

Dakujem za pomoc

Editoval japlavaren (21. 3. 2010 17:02)

SyXcz
Člen | 75
+
0
-

zkus použít jen

<?php
Debug::dump($form->getValues());
?>
japlavaren
Člen | 404
+
0
-

Chyba vyriesena – $form = new AppForm; nie form

knyttl
Člen | 196
+
0
-

Mám v podstatě ten samý problém, s tím rozdílem, že form třídy AppForm mám. Přes veškeré snahy, handler „editPlaceFormSubmitted“ se nezavolá:

<?php
	protected function createComponentEditPlaceForm() {
		if( $id = $this->params['id'] ) {
			$p  = PlacesModel::getPlace( $id, "full" );
		}

		$form = new AppForm( $this, "editPlaceForm" );

		$form->addText('cs_name', 'Name CS:')
			->addRule(Form::FILLED, 'Required.')
			->setValue( $name );

		$form->addText('cs_slug', 'Slug CS:')
			->addRule(Form::FILLED, 'Required.')
			->setValue( $slug );

		// callback jsem zkusmo definoval dvakrát, bez výsledku
		$form->addSubmit('update', 'Update')
				->onClick[] = array( $this, 'editPlaceFormSubmitted' );
		$form->onSubmit[] = array( $this, 'editPlaceFormSubmitted' );

		// je tohle nutné? z dokumentace to úplně zřejmé není,
		// někde to zmíněné je, někde není
		$form->fireEvents();

		return $form;
	}

	public function editPlaceFormSubmitted( AppForm $form ) {
		Debug::dump( $form );
		echo "foooo";

		$place = array();
		foreach( $form as $key => $value ) {
			preg_match( "/([a-z]{2,4})_([a-z]+)/", $key, $matches );
			$place[$matches[1]][$matches[2]] = $value;
		}
		PlacesModel::savePlace( $place );
		exit();
	}
?>

Dotazy:

  1. V dokumentaci je psáno, že postačuje volat $form = new AppForm; – to ale očividně nestačí – hlásí to chybu, že formulář není anchored a tak nelze volat Callback – nechtělo by to tam nějak dopsat?
  2. Ten callback – z dokumentace není moc jasný rozdíl mezi následujícími:

    ->onSubmit[] = ‚string‘

    ->onSubmit[] = array(…)

    ->onSubmit[] = callback(…)

  3. V dokumentaci není zmíněno, že je nutné používat $form->fireEvents – to jsem musel okoukat někde ve foru – je to skutečně nutné?

Děkuji za osvětlení.

Editoval knyttr (26. 6. 2010 16:57)

Patrik Votoček
Člen | 2221
+
0
-

->setValue( ... ); WTF? Neměl by jsi tam mít spíš setDefaultValue() ???

Pokud používáš AppForm fireEvents() používat nemusíš.

ad 1) v nové dokumentaci je tohle již zmíněno. (brzy jí nahodíme na ostro)
ad 2a) tohle nemusí korektně fungovat v PHP < 5.3 (tj PHP 5.2.x)
2b) je standartní definování callbacku v PHP
2c) nette vylepšené definování callbacku viz: https://forum.nette.org/…kce-callback?…
ad 3) viz výše.

Editoval vrtak-cz (26. 6. 2010 17:55)

knyttl
Člen | 196
+
0
-

Nevím, oboje má stejný efekt. Na to, že to nevolá callback to ale nemá vliv.

V dokumentaci se mi rozdíl mezi setValue a setDefaultValue najít nedaří.

Editoval knyttr (26. 6. 2010 17:54)

Patrik Votoček
Člen | 2221
+
0
-

editnul jsem předchozí post… doplnil pár informací…

To že to oboje nefunguje ještě neznamená že to není špatně…

Rozdíl mezi setValue() a setDefaultValue() je obrovský. V prvním případě nastavuješ odesílanou hodnotu a ve druhém předvyplněnou hodnotu.

knyttl
Člen | 196
+
0
-

Díky za odpověď, nevím – i tím prvním mi to nastaví předvyplněnou hodnotu. Prakticky v tom nevidím rozdíl. Každopádně by také stálo za to to dopsat do dokumentace.

Pořád ale nechápu, proč mi to nezavolá ten callback. Když do renderDefault dopíšu něco jako Debug::dump( $_POST ); tak je vidět, že ten post se v pořádku odešle.

Patrik Votoček
Člen | 2221
+
0
-

Tím prvním ti to ale zároveň přepíše odeslanou hodnotu… (Tj. pokud něco ve formuláři změníš tak ti se to v nette bude tvářit jako že se nic nezměnilo.

Možné chyby musíš eliminovat postupně… Je ten odesílaný formulář validní? Je na stránce jednou nebo vícekrát? Můžeš zkusit ten form nahodit jenom do skeletonu jestli to bude dělat taky? (jinak řečeno minimalizovat kód který bude stále generovat tuto chybu – nezavolá callback)

knyttl
Člen | 196
+
0
-

Jelikož jsem měl napsaný vlastní router, neuvědomil jsem si, že bych měl i v něm zpracovávat POST požadavek – udělal jsem to tedy takto:

<?php
return new PresenterRequest( $presenter, $httpRequest->getMethod(), $params, $httpRequest->getPost() );
?>

Když dumpnu v Presenteru jeho proměnné, vidím, že request->post již obsahuje odeslaný formulář. Stejně tak request->method==post. Asi tomu ale pořád něco chybí, protože to nevolá ani handler onInvalidSubmit. Zkoušel jsem si otevřít AppForm.php a tam je handler signálů z presenteru – a ten se vůbec nezavolá…

Editoval knyttr (27. 6. 2010 10:56)

Patrik Votoček
Člen | 2221
+
0
-

Jak jsem ti psal už včera zkoušej minimalizovat kód který generuje tuhle chybu (nezavolání callbacku). Vetšinou na to pak kápneš sám. Nebo je kód tak minimalistický že ho můžeš na sdílet tady na fóru aby ho mohlo prozkoumat víc lidí (víc lidí víc ví).

Když ten svůj router vyhodíš úplně a necháš tam standardní nette tak to funguje?

Editoval vrtak-cz (27. 6. 2010 11:07)

knyttl
Člen | 196
+
0
-

Presenter: http://pastebin.com/AKPW1EFP

Router (zkrácený): http://pastebin.com/6gNViUZB

Můžu potvrdit, že se standardním routerem vše funguje. Když dumpnu proměnné mého a defaultního routeru, tak v defaultním je navíc tenhle řádek v params:

„do“ ⇒ string(20) „editPlaceForm-submit“

Zkusil jsem tedy ručně přidat tohle do do params v mém routeru a tedy funguje. Nicméně tedy nevím, jak bych tohle mohl dělat nějak rozumně automaticky.

Díky.

Editoval knyttr (27. 6. 2010 11:29)

Patrik Votoček
Člen | 2221
+
0
-

Tak vidíš nakonec jsi na chybu přišel sám. 'do' => string(20) "editPlaceForm-submit" by ti měl vrátit Nette\Web\HttpRequest::getQuery() ale pozor ta část do je tam pouze pokud je formulář odeslán.

knyttl
Člen | 196
+
0
-

Tomu stejně nerozumím, protože to by ten <form> musel mít v target něco jako „…/?do=editPlaceForm-submit“ a to nemá. V url se mi po odeslání formuláře to „?do=…“ neobjeví a tak to getQuery ho asi ani nemá kde získat.

Patrik Votoček
Člen | 2221
+
0
-

To neco co by tam musel mít. Tam být má… To je totiž to co způsobuje volání callbacku. Takže ten tvůj router špatně generuje URL.

Editoval vrtak-cz (27. 6. 2010 14:07)