Nedaří se mi zprovoznit formulář s ajaxem

- kejlicz
 - Člen | 201
 
Ahoj všichni.
Nedaří se mi rozchodit ajax ve formuláři. Již déle používám ajax při obsluze signálů a to mi funguje dobře. Dnes se již několik hodin snažím rozchodit formulář a nechápu, proč to nejde. Na stejné stránce je i tlačítko na zajaxovaný signál a to šlape.
Mám to jako Control a pod ním je formulář.
nette.ajax.js mám nahraný a zinicializovaný.
Po kliknutí na odesílací tlačítko ajaxový požadavek normálně proběhne a v odpovědi se vrátí celá stránka(již tam jsou např. vypsané chyby, takže se form odeslal), ale nic se nepřekreslí.
Neajaxově to funguje.
{snippet responseForm}
<h2></h2>
<form class="form-horizontal ajax" n:name="responseForm">
    <div n:foreach="$form->errors as $error" class="alert alert-danger">
        {$error}
    </div>
		... kód formuláře .....
    <div class="form-group">
        <div class="col-md-9 col-md-offset-2">
            <input n:name="submit" class="btn btn-primary" value="Odeslat odpověď" />
        </div>
    </div>
</form>
{/snippet}
Formulář po zpracování refrešnu takto
		if (!$this->isAjax())
		{
			$this->redirect('this');
		}
		else
		{
			$this->redrawControl("responseForm");
			$form->setValues([], TRUE);
		}
Díky moc za pomoc.
Martin

- kejlicz
 - Člen | 201
 
Lexi napsal(a):
Kde konkrétně ten
redrawControl()voláš? V presenteru? Pošli prosím více kódu.
<?php
namespace Kejzlar\Components;
class Response extends \Nette\Application\UI\Control
{
	/** @var \Kdyby\Doctrine\EntityManager  */
	private $em;
	/** @var \App\Facades\RegionFacade  */
	 ..... inicializace ......
	public function __construct(\Kdyby\Doctrine\EntityManager $em, ...........)
	{
		 ..... přiřazování hodnot ......
	}
	public function render()
	{
       ..... přiřazování hodnot ......
		$this->template->setFile(__DIR__ . "/Response.latte");
		$this->template->render();
	}
	public function createComponentResponseForm()
	{
		$form = new \Nette\Application\UI\Form;
		$form->addText("name");
		$form->addText("email")->setRequired("Je nutné vyplnit Váš email")
			->addRule(\Nette\Application\UI\Form::EMAIL, "Email není ve správném formátu. Prosím překontrolujte zadání.");
		// Nastavení předvyplněného emailu pokud je uživatel přihlášen
		if($this->dbUser instanceof \App\Entities\User)
		{
			$form["name"]->setDefaultValue($this->dbUser->getName());
			$form["email"]->setDefaultValue($this->dbUser->getUsername());
		}
		$form->addTextArea("content")->setRequired("Není vyplněn text odpovědi");
		$form->addUpload("file", "Soubor");
		$form->addCheckbox("success", NULL)->setRequired("Je třeba souhlasit v podmínkami webu zaškrtnutím 'Souhlasím'");
		$form->addSubmit("submit", "Uložit");
		$form->onSuccess[] = array($this, "proccessResponseForm");
		return $form;
	}
	public function proccessResponseForm($form)
	{
		$values = $form->getValues();
		.... ZPRACOVÁNÍ FORMULÁŘE  ........
		$this->flashMessage("Vaše odpověď byla úspěšně odeslána", "success");
		if (!$this->isAjax())
			$this->redirect('this');
		else {
			$this->getPresenter()->redrawControl("responseForm");
			$this->redrawControl("flash");
			$form->setValues([], TRUE);
		}
	}
}
				
- kejlicz
 - Člen | 201
 
Asi jo. Jsem se v tom nějak zamotal. Jsem to osekal na minimum. Taky jsem upravil ověřování
!$this->isAjax()
na
!$this->getPresenter()->isAjax()
což by mělo podle testování fungovat.
Ale pořád jsem tak nějak na stejném místě. Jen jsem se trochu posunul
v tom, že když je formulář v pořádku vyplněný, odešle se ajaxem a
zobrazí se flash a obnoví se formulář.
Pokud ale má form nějakou chybu, zůstává stejná situace jako na začátku.
Formulář se ajaxově odešle a přijde odpověď, v níž je komplet web
stránka. Žádný snippety.
Chápu, že z tohodle popisu se blbě radí. Není někde funkční ukázka takového formu v komponentě? Abych to porovnal.
Díky
Lexi napsal(a):
Nette\Application\UI\Controlnemá metoduisAjax(), přiděláváš si ji tam nějak?
Nemůže být chyba v tom, že mixuješ snippety komponenty a snippety presenteru a neinvaliduješ správný?
Editoval kejlicz (7. 10. 2016 1:32)

- kejlicz
 - Člen | 201
 
Tak jsem se stylem pokus / omyl dostal k funkčnímu řešení. Nebylo mi jasné co se děje při validaci, aby se to odeslalo ajaxem. Tak jsem zkusil přidat
	public function validateResponseForm($form)
	{
		if (!$this->getPresenter()->isAjax())
		{
			$this->redirect('this');
		}
		else {
			$this->redrawControl("responseForm");
			$this->redrawControl("flash2");
		}
	}
a ono všechno funguje jak má. Takhle se to má dělat nebo jsem jen něco obešel?

- GEpic
 - Člen | 566
 
Příště zkus:
{snippet responseForm}
<h2></h2>
<form class="form-horizontal" n:name="responseForm">
    <div n:foreach="$form->errors as $error" class="alert alert-danger">
        {$error}
    </div>
        ... kód formuláře .....
    <div class="form-group">
        <div class="col-md-9 col-md-offset-2">
            <input n:name="submit" class="ajax btn btn-primary" value="Odeslat odpověď" />
        </div>
    </div>
</form>
{/snippet}
					Editoval GEpic (7. 10. 2016 3:18)

- Jan Mikeš
 - Člen | 771
 
@GEpic neměl by být rozdíl, jestli ajax class přidá
formu nebo submitu.
Je to jak píše @CZechBoY
@kejlicz ještě by jsi mohl zkusit dát ten redrawControl()
úplně pryč z formuláře, nechat tam pouze
	if (!$this->getPresenter()->isAjax())
    {
        $this->redirect('this');
    }
A redrawControl() přesunout do attached() což si
myslím, že je i vhodnější způsob ;) Napadlo mě ještě to dát do
render() componenty, ale u toho ti nejsem v tuto chvíli schopen
říct, že bude fungovat, každopádně to můžeš vyzkoušet.
edit: ještě abych vysvětlit, formuláři by totiž mělo být úplně šumák jak ho zpracováváš a nějaké překreslování snippetů není jeho zodpovědnost, měla by se o to starat komponenta/presenter a tedy je i snaha umístit „na správné místo“ invalidaci snippetů
Editoval Lexi (7. 10. 2016 9:44)

- kejlicz
 - Člen | 201
 
@GEpic : To je opravdu to samé
@CZechBoY : To mi taky vrtalo hlavou, ale nějak jsem nemohl najít na
netu funkční ukázku
@Lexi : Udělal jsem to jak píšeš (redrawControl do attached()) a
šlape to. V render() metodě to nešlo.
Díky MOC za pomoc.
Editoval kejlicz (7. 10. 2016 10:41)

- GEpic
 - Člen | 566
 
kejlicz napsal(a):
@GEpic : To je opravdu to samé
@CZechBoY : To mi taky vrtalo hlavou, ale nějak jsem nemohl najít na netu funkční ukázku
@Lexi : Udělal jsem to jak píšeš (redrawControl do attached()) a šlape to. V render() metodě to nešlo.Díky MOC za pomoc.
To sice je, ale třídu buttonu můžeš nastavit už jednoduše v PHP, a můžeš tak nastavit zda-li bude formulář ajaxový nebo ne rovnou v PHP, pak můžeš s ledovým klidem klidně vypsat formulář přes control, namísto ručně (pokud k tomu jednou dojdeš).

- kejlicz
 - Člen | 201
 
GEpic napsal(a):
kejlicz napsal(a):
@GEpic : To je opravdu to samé
@CZechBoY : To mi taky vrtalo hlavou, ale nějak jsem nemohl najít na netu funkční ukázku
@Lexi : Udělal jsem to jak píšeš (redrawControl do attached()) a šlape to. V render() metodě to nešlo.Díky MOC za pomoc.
To sice je, ale třídu buttonu můžeš nastavit už jednoduše v PHP, a můžeš tak nastavit zda-li bude formulář ajaxový nebo ne rovnou v PHP, pak můžeš s ledovým klidem klidně vypsat formulář přes control, namísto ručně (pokud k tomu jednou dojdeš).
To můžu i u formuláře
$form->getElementPrototype()->class('ajax');
Renderování přes {control xxx} je sice fajn, ale na nějaké složitější formuláře je pro mne určitě lepší renderovat ručně.
Editoval kejlicz (7. 10. 2016 12:19)