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\Control
nemá 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)