Jednoduchy ajax formular – zacatecnicka otazka
- hotline
- Člen | 41
Ahoj vsem. Chtel bych se zeptat na jednu zacatecnickou drobnost u ajaxu.
Koukal jsem se na dva priklady na planette a oba se lisi v tom, jestli se
neco nastavuje v js nebo ne.
https://doc.nette.org/…ication/ajax –
zde se nastavi jen zaklad – nette.init (to mam) a nic vice
https://pla.nette.org/…ivajici-ajax#… –
zde se nastavuje preventdefault u odeslani formulare a nejake dalsi veci
V kterych pripadech je tedy nutne nastavovat to rucne a v kterych to resi samo nette?
Mam jednoduchou komponentu, ktera obsahuje metody:
public function render()
{
$template = $this->template;
$template->setFile(__DIR__ . '/Login.latte');
$form = new \Nette\Application\UI\Form();
$form->addText('name', 'Emailová adresa');
$form->addPassword('password', 'Heslo');
$form->addSubmit('send', 'Přihlásit se');
$form->onSuccess[] = $this->processForm;
$template->form = $form;
$template->render();
}
public function processForm($form)
{
if ($this->isAjax()) {
$template->error = "test";
$this->redrawControl('login_result');
}
}
A k ni lattecko:
{snippet login_result}{ifset $error}<div class="alert alert-danger alert-dismissable login-error">{$error}</div>{/ifset}{/snippet}
{snippet login_control}{$form}{/snippet}
Problem je v tom, ze po odeslani formulare se normalne nacte stranka, tedy nejedna se o ajax (v konzoli neni zadna chyba). V koznoli se po odeslani objevi akorat toto:
XHR Loaded (nazev - 200 OK - 230.56699999142438ms - 16.747KB)
VM4967:3 http://url.cz/xxx?name=a&password=&send=P%C5%99ihl%C3%A1sit+se
VM4968:3 Object {startedDateTime: "2015-05-31T15:07:03.800Z", time: 230.56699999142438, request: Object, response: Object, cache: Object…}
Kazdopadne promenna $error je vzdy prazdna. I kdyz to upravim takto:
public function processForm($form)
{
if ($this->isAjax()) {
$template->error = "test";
$this->redrawControl('login_result');
}
$template->error = "test";
$this->redrawControl('login_result');
}
Kde jsem mohl udelat chybu? Je v tomto pripade rucne upravit JS tak, aby tam byl preventdefault a dalsi veci pro znovuvykresleni snippetu? Hlavne nechapu, proc je promenna $error prazdna, i kdyz se formular odeslal.
Predem diky za radu, pekny zbytek vikendu vsem.
Editoval hotline (31. 5. 2015 17:16)
- Lukeluha
- Člen | 130
- Potřebuješ celému formuláři nastavit
class=ajax
– jinak by knihovna nevěděla, že se má formulář odesílat AJAXem – o nic jiného by ses neměl starat. - Formulář vytvářej v továrničce
createComponentForm
a v šabloně poté formulář vykreslíš{control form}
. - Druhý tutoriál je 5 let starý, ještě neexistovala knihovna od Honzy Dobeše – máš ji správně includnutou?
- Pokud se odešle formulář klasicky a zavoláš redrawControl, nevím,
jestli to nezpůosíb nějakou neplechu (v
processForm
by mělo býtif ($this->isAjax()) ... else pouze nastav proměnnou
- Používej flash message :)
Editoval Lukeluha (1. 6. 2015 9:11)
- hotline
- Člen | 41
Perfektni, diky moc za odpoved, nastavil jsem to jak pises (krome flashek, v tomto pripade to resim trosku jinak) a formular se odesila ajaxove. Jeste tam ale nekde bude nejaka chybka v metode processForm($form), protoze po odeslani dostavam 500 error.
500 Internal Server Error
609ms
jquery.min.js (řádek 6)
exception 'Nette\MemberAccessException' with message 'Call to undefined method LoginControl::isAjax(
).' in /site/vendor/nette/utils/src/Utils/ObjectMixin
.php:96
Stack trace:
#0 /site/vendor/nette/utils/src/Utils/Object
.php(77): Nette\Utils\ObjectMixin::call(Object(LoginControl), 'isAjax', Array)
#1 /site/app/components/Login.php(85): Nette
\Object->__call('isAjax', Array)
#2 /site/app/components/Login.php(85): LoginControl-
>isAjax()
#3 [internal function]: LoginControl->processForm(Object(Nette\Application\UI\Form), NULL)
#4 /site/vendor/nette/utils/src/Utils/Callback
.php(67): call_user_func_array(Object(Closure), Array)
#5 /site/vendor/nette/forms/src/Forms/Form
.php(420): Nette\Utils\Callback::invoke(Object(Closure), Object(Nette\Application\UI\Form), NULL)
#6 /site/vendor/nette/application/src/Application
/UI/Form.php(137): Nette\Forms\Form->fireEvents()
#7 /site/vendor/nette/application/src/Application
/UI/Presenter.php(326): Nette\Application\UI\Form->signalReceived('submit')
#8 /site/vendor/nette/application/src/Application
/UI/Presenter.php(207): Nette\Application\UI\Presenter->processSignal()
#9 /site/vendor/nette/application/src/Application
/Application.php(148): Nette\Application\UI\Presenter->run(Object(Nette\Application\Request))
#10 /site/vendor/nette/application/src/Application
/Application.php(88): Nette\Application\Application->processRequest(Object(Nette\Application\Request
))
#11 /site/www/index.php(11): Nette\Application
\Application->run()
#12 {main}
(stored in /site/app/../log/exception-2015-06-01-10-23-28-b456a513f9c150292508bbdc53f88995
.html)
Kdyz odeberu podminku na $this-isAjax(), dostavam:
500 Internal Server Error
234ms
jquery.min.js (řádek 6)
exception 'ErrorException' with message 'Creating default object from empty value' in site/app/components/Login.php:86
Stack trace:
#0 /site/app/components/Login.php(86): Tracy
\Debugger::errorHandler(2, 'Creating defaul...', '/site/...', 86, Array)
#1 [internal function]: LoginControl->processForm(Object(Nette\Application\UI\Form), NULL)
#2 /site/vendor/nette/utils/src/Utils/Callback
.php(67): call_user_func_array(Object(Closure), Array)
#3 /site/vendor/nette/forms/src/Forms/Form
.php(420): Nette\Utils\Callback::invoke(Object(Closure), Object(Nette\Application\UI\Form), NULL)
#4 /site/vendor/nette/application/src/Application
/UI/Form.php(137): Nette\Forms\Form->fireEvents()
#5 /site/vendor/nette/application/src/Application
/UI/Presenter.php(326): Nette\Application\UI\Form->signalReceived('submit')
#6 /site/vendor/nette/application/src/Application
/UI/Presenter.php(207): Nette\Application\UI\Presenter->processSignal()
#7 /site/vendor/nette/application/src/Application
/Application.php(148): Nette\Application\UI\Presenter->run(Object(Nette\Application\Request))
#8 /site/vendor/nette/application/src/Application
/Application.php(88): Nette\Application\Application->processRequest(Object(Nette\Application\Request
))
#9 /site/www/index.php(11): Nette\Application
\Application->run()
#10 {main}
(stored in /site/app/../log/exception-2015-06-01-10-30-05-ad5e74bfe66298d61444b69e303bfd4b
.html)
Login.php:86 je $template->error = "test";
Pokousim se najit
pricinu, ale kdybyste ji tam rychlym pohledem do kodu videli, reknete prosim.
Postupoval jsem podle tohoto tutorialu.
- David Matějka
- Moderator | 6445
$this->isAjax()
⇒
$this->presenter->isAjax()
$template->error
⇒
$this->template->error
- hotline
- Člen | 41
Skvele, diky. Posledni otazka: kdyz jsem resil ajax rucne bez frameworku a potreboval jsem zjistovat, jake tlacitko uzivatel stisknul pri odeslani formulare (v jednom formualari jich mam vice), defaultne se hodnota tlacitka vubec neodesilala a musel jsem to resit nejak takhle:
var values = $(this).closest('form').serialize() + '&' + this.name;
Viz. treba Ajax post serialize() does not include button name
and value
Nesetkali jste se s tim nekdo v Nette? Vse mi funguje v poradku, data si
vytahnu pres $values = $form->getValues(TRUE);
, ale
$values['send']
neexistuje. Ostatni pole ano.
Editoval hotline (1. 6. 2015 13:22)