Formulář se neodesílá AJAXEM

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

Zdravím Vás,
zase jsem se po delší době dostal k Nette a mám problém s AJAXovým odesláním formuláře. Nevím v čem je problém.
Form:

$form = $this->formFactory->create(); //new \Nette\Application\UI\Form;
$form->getElementPrototype()->class('ajax');
...
$form->addSubmit('send', 'Submit');
$form->onSuccess[] = [$this, 'reportFormSucceeded']; //funkce existuje, ale je prázdná

V šabloně ho vygeneruji normálně {control reportForm}, vygeneruje se s class=„ajax“

<form action="/game/?id=069b5bb83d" method="post" class="ajax" id="frm-reportForm">

Formulář se prostě ajaxově neodešle, přestože u odkazu, který mám nad formulářem <a n:href="test!" class="ajax">Test</a> se požadavek pošle normálně ajaxem. Nevíte, kde by mohl být zakopaný pes?

thm
Člen | 147
+
0
-

Nenapadá někoho něco prosím?

GEpic
Člen | 566
+
0
-
$form = $this->formFactory->create(); //new \Nette\Application\UI\Form;
$form->getElementPrototype()->class('ajax');

Tohle dělat nemusíš – smaž to. A přidej ajax třídu tomu tlačítku ve formuláři.

$form->addSubmit('send', 'Submit')
	->setAttribute("class", "ajax");

Editoval GEpic (5. 11. 2017 15:07)

thm
Člen | 147
+
0
-

Už není třeba dávat class=„ajax“ formuláři?

GEpic
Člen | 566
+
0
-

thm napsal(a):

Už není třeba dávat class=„ajax“ formuláři?

Uf si odpověděl rychle, máš to v původním příspěvku – Třídu ajax jsem k formuláři nikdy neuváděl, jen ke tlačítkům.

thm
Člen | 147
+
0
-

Jo, už jsem se zorientoval :) Díky za radu. Já zase nikdy nedával třídu ajax tlačítku. Nicméně snad by mělo být oboje možné. Button se vygeneruje <input type="submit" name="send" class="ajax button" value="Submit"> – takže podle mě v pořádku. Přesto se stránka refreshne (požadavek se ajaxem neodešle).

Hned pod/nad formulářem mám <a n:href="reportGame!" class="ajax">{_messages.reporter.demoBroken}</a> a to se ajaxem normálně odesílá…

Editoval thm (5. 11. 2017 15:19)

thm
Člen | 147
+
0
-

Nezačal jsem svůj poslední přípsěvek vhodně, vypadalo to, že je vyřešeno. Ale není. Pokud máte ještě někdo nějaký tip, prosím napište.

chemix
Nette Core | 1310
+
0
-

Ahoj

  • Jakou js knihovnu pouzivas?
  • objevi se nejaka chyba v consoli kdyz odesles form?
  • opravdu se vygeneruje form s tridou ajax?
  • mas posledni verze?
  • deje se to napric prohlizecema?
rkor
Člen | 62
+
0
-

A máš nalinkován netteForms.js?

GEpic
Člen | 566
+
0
-

Pokud používá nette.ajax.js tak netteForms.js nepotřebuje. A omlouvám se @thm ale jak si psal tak třída ajax na formu by měla taky fungovat…

Editoval GEpic (6. 11. 2017 9:39)

rkor
Člen | 62
+
0
-

GEpic napsal(a):

Pokud používá nette.ajax.js tak netteForms.js nepotřebuje. A omlouvám se @thm ale jak si psal tak třída ajax na formu by měla taky fungovat…

Nemám otestováno, ale našel jsem tohle, tak mě napadla souvislost:
https://github.com/…s/issues/148

GEpic
Člen | 566
+
0
-

rkor napsal(a):

GEpic napsal(a):

Pokud používá nette.ajax.js tak netteForms.js nepotřebuje. A omlouvám se @thm ale jak si psal tak třída ajax na formu by měla taky fungovat…

Nemám otestováno, ale našel jsem tohle, tak mě napadla souvislost:
https://github.com/…s/issues/148

Používám nette.ajax.js a netteForms.js k němu nepotřebuješ, poté použiju inicializaci a již ajax funguje.

Editoval GEpic (7. 11. 2017 11:06)

thm
Člen | 147
+
0
-

Díky za pomoc @GEpic, @rkor a @chemix. @GEpic není vůbec za co se omlouvat.
Zkusil jsem to na novém projektu znovu.

  • Stáhnul jsem si web-project composer create-project nette/web-project forms
  • Součástí web-project je v @layout.latte nalinkovaný <script src="https://nette.github.io/resources/js/netteForms.min.js"></script>, zakomentuji, protože není třeba
  • Stáhnu jQuery
  • Stáhnu nette.ajax (2.3.0)

Můj @layout.latte vypadá nyní takto:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width">

	<title>{ifset title}{include title|stripHtml} | {/ifset}Nette Web</title>
</head>

<body>
	<div n:foreach="$flashes as $flash" n:class="flash, $flash->type">{$flash->message}</div>

	{include content}

	{block scripts}
	{*<script src="{$basePath}/js/netteForms.min.js"></script>*}
	<script src="{$basePath}/js/jquery-3.2.1.min.js"></script>
	<script src="{$basePath}/js/nette.ajax.js"></script>
	<script>
		$(function () {
			$.nette.init();
		});
	</script>
	{/block}
</body>
</html>

V presenteru vytvořím toto:

<?php

namespace App\Presenters;
use Nette;

class HomepagePresenter extends Nette\Application\UI\Presenter
{
	/** @persistent */
	public $value = 1;

	public function renderDefault()
	{
		$this->template->value = $this->value;
	}

	public function handleIncreaseValue()
	{
		++$this->value;
		$this->isAjax() ? $this->redrawControl('value') : $this->redirect('this');
	}

	public function createComponentForm()
	{
		$form = new \Nette\Application\UI\Form;
		$form->addText('newValue');
		$form->addSubmit('send')
			  ->setAttribute('class', 'ajax');
		$form->onSuccess[] = [$this, 'formSucceeded'];
		return $form;
	}

	public function formSucceeded(\Nette\Application\UI\Form $form, $values)
	{
		$this->value = $values->newValue;
		$this->isAjax() ? $this->redrawControl('value') : $this->redirect('this');
	}
}

A nakonec šablona default.latte

{block content}
{snippet value}
	{$value}
{/snippet}
<a n:href="increaseValue!" class="ajax">Increase value</a>
{control form} {* vygeneruje třídu ajax u submitu <input type="submit" name="send" class="ajax button">*}

V této konfiguraci se mi odesílá ajaxově pouze <a n:href="increaseValue!" class="ajax">Increase value</a>, formulář se redirectne.

@chemix při posílání požadavku se v consoli objeví chyba (omlouvám se jsem JS totalmimoň):

Uncaught ReferenceError: Nette is not defined
    at Object.before (nette.ajax.js:319)
    at Function.<anonymous> (nette.ajax.js:42)
    at Function.each (jquery-3.2.1.min.js:2)
    at Object.fire (nette.ajax.js:40)
    at Object.settings.beforeSend (nette.ajax.js:215)
    at Function.ajax (jquery-3.2.1.min.js:4)
    at nette.ajax (nette.ajax.js:225)
    at HTMLInputElement.requestHandler (nette.ajax.js:48)
    at HTMLFormElement.dispatch (jquery-3.2.1.min.js:3)
    at HTMLFormElement.q.handle (jquery-3.2.1.min.js:3)

Jakmile ale odkomentuji {*<script src="{$basePath}/js/netteForms.min.js"></script>*} tak i formulář se odesílá ajaxově!
Takže je zde nějaká závislost na netteForms.js (jak píše @rkor).

Další otázka – tentokrát za zlatého bludišťáka:
Mimochodem, pokud klikám na Increase value po prvním ajaxu se překreslí value na 2, po každém dalším kliknutí se překresluje zase s hodnotou 2. Přitom jsem přesvědčen, že kdysi mi toto fungovalo a hodnota value by se o jedno zvětšovala. Pokud odeberu třídu ajax odkazu, tak vše funguje normálně (value se načítá o 1). Co to?

vladimir.biro
Člen | 163
+
0
-

thm napsal(a):

Díky za pomoc @GEpic, @rkor a @chemix. @GEpic není vůbec za co se omlouvat.
Zkusil jsem to na novém projektu znovu.

  • Stáhnul jsem si web-project composer create-project nette/web-project forms
  • Součástí web-project je v @layout.latte nalinkovaný <script src="https://nette.github.io/resources/js/netteForms.min.js"></script>, zakomentuji, protože není třeba
  • Stáhnu jQuery
  • Stáhnu nette.ajax (2.3.0)

Můj @layout.latte vypadá nyní takto:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width">

	<title>{ifset title}{include title|stripHtml} | {/ifset}Nette Web</title>
</head>

<body>
	<div n:foreach="$flashes as $flash" n:class="flash, $flash->type">{$flash->message}</div>

	{include content}

	{block scripts}
	{*<script src="{$basePath}/js/netteForms.min.js"></script>*}
	<script src="{$basePath}/js/jquery-3.2.1.min.js"></script>
	<script src="{$basePath}/js/nette.ajax.js"></script>
	<script>
		$(function () {
			$.nette.init();
		});
	</script>
	{/block}
</body>
</html>

V presenteru vytvořím toto:

<?php

namespace App\Presenters;
use Nette;

class HomepagePresenter extends Nette\Application\UI\Presenter
{
	/** @persistent */
	public $value = 1;

	public function renderDefault()
	{
		$this->template->value = $this->value;
	}

	public function handleIncreaseValue()
	{
		++$this->value;
		$this->isAjax() ? $this->redrawControl('value') : $this->redirect('this');
	}

	public function createComponentForm()
	{
		$form = new \Nette\Application\UI\Form;
		$form->addText('newValue');
		$form->addSubmit('send')
			  ->setAttribute('class', 'ajax');
		$form->onSuccess[] = [$this, 'formSucceeded'];
		return $form;
	}

	public function formSucceeded(\Nette\Application\UI\Form $form, $values)
	{
		$this->value = $values->newValue;
		$this->isAjax() ? $this->redrawControl('value') : $this->redirect('this');
	}
}

A nakonec šablona default.latte

{block content}
{snippet value}
	{$value}
{/snippet}
<a n:href="increaseValue!" class="ajax">Increase value</a>
{control form} {* vygeneruje třídu ajax u submitu <input type="submit" name="send" class="ajax button">*}

V této konfiguraci se mi odesílá ajaxově pouze <a n:href="increaseValue!" class="ajax">Increase value</a>, formulář se redirectne.

@chemix při posílání požadavku se v consoli objeví chyba (omlouvám se jsem JS totalmimoň):

Uncaught ReferenceError: Nette is not defined
    at Object.before (nette.ajax.js:319)
    at Function.<anonymous> (nette.ajax.js:42)
    at Function.each (jquery-3.2.1.min.js:2)
    at Object.fire (nette.ajax.js:40)
    at Object.settings.beforeSend (nette.ajax.js:215)
    at Function.ajax (jquery-3.2.1.min.js:4)
    at nette.ajax (nette.ajax.js:225)
    at HTMLInputElement.requestHandler (nette.ajax.js:48)
    at HTMLFormElement.dispatch (jquery-3.2.1.min.js:3)
    at HTMLFormElement.q.handle (jquery-3.2.1.min.js:3)

Jakmile ale odkomentuji {*<script src="{$basePath}/js/netteForms.min.js"></script>*} tak i formulář se odesílá ajaxově!
Takže je zde nějaká závislost na netteForms.js (jak píše @rkor).

Další otázka – tentokrát za zlatého bludišťáka:
Mimochodem, pokud klikám na Increase value po prvním ajaxu se překreslí value na 2, po každém dalším kliknutí se překresluje zase s hodnotou 2. Přitom jsem přesvědčen, že kdysi mi toto fungovalo a hodnota value by se o jedno zvětšovala. Pokud odeberu třídu ajax odkazu, tak vše funguje normálně (value se načítá o 1). Co to?

Skus to takto:

<?php
{block content}
{snippet value}
    {$value}
	<a n:href="increaseValue!" class="ajax">Increase value</a>
{/snippet}
{control form} {* vygeneruje třídu ajax u submitu <input type="submit" name="send" class="ajax button">*}
?>

Myslim, ze ten button by sa tiez mal nacitat nanovo, ked chces, aby robil nieco ine (kedze zakazdym zvysuje hodnotu value, tak ma zakazdym inu funkciu). Takze button by tiez mal byt v snippete a mal by byt nanovo vracany presenterom. Ked z procesu odstranis ajax, tak sa ti rfresne cela stranka a tym padom aj button a tym padom to funguje :)

Daj vediet ci to pomohlo.

thm
Člen | 147
+
0
-

@vladimir.biro Máš pravdu, fakt je to tím :) – ono to vlastně musí vygenerovat nový odkaz – to jsem si vůbec neuvědomil. Díky moc, máš u mě toho bludišťáka ;) (pokud mi pošleš kontaktní údaje na e-mail – teď jsem koukal, že ho fakt prodávají, tak musím dostát svých slibů)

Editoval thm (7. 11. 2017 20:52)

vladimir.biro
Člen | 163
+
+1
-

thm napsal(a):

@vladimir.biro Máš pravdu, fakt je to tím :) – ono to vlastně musí vygenerovat nový odkaz – to jsem si vůbec neuvědomil. Díky moc, máš u mě toho bludišťáka ;) (pokud mi pošleš kontaktní údaje na e-mail – teď jsem koukal, že ho fakt prodávají, tak musím dostát svých slibů)

Ajej .. to je hodne oskliva vec … Dik, nechci! :D

chemix
Nette Core | 1310
+
+1
-

@thm Ano je tam zavislost pokud pracujes s formularem, tak ho nette.ajax chce validovat skrze Nette.forms viz https://github.com/…ette.ajax.js#L323