Aplikování AJAXU do projektu
- .:M@rt!n:.
- Člen | 201
Chtěl jsem si zkusit zakomponovat do své aplikace AJAX, ale trochu se v tom ztrácím. Chtěl bych proto požádat o radu, co mám špatně?
latte:
{block #content}
{snippet form}
{form menuForm class => ajax}
<table bordercolor="white">
<tr>
<td>{label datum/}</td>
<td> {input datum}</td>
</tr>
<tr>
<td>{label polevka/}</td>
<td>{input polevka}</td>
</tr>
<tr>
<td>{label jidlo1/}</td>
<td>{input jidlo1}</td>
</tr>
<tr>
<td>{label jidlo2/}</td>
<td> {input jidlo2}</td>
</tr>
<tr>
<td>{input create}</td><td> {input cancel}</td>
</tr>
</table>
{/form}
{/snippet}
<div>
<table cellspacing="0">
{foreach $menu as $menu}
<tr>
<td class="bold">Datum: </td>
<td class="volna_bunka"></td>
<td>{$menu->datum|date:'j. n. Y'}</td>
<td><a class="edit" n:href="edit, $menu->id"><img src="{$basePath}/images/edit.png" alt="Editovat" /></a></td>
<td><a class="delete" n:href="delete, $menu->id"><img src="{$basePath}/images/delete.png" alt="Vymazat" /></a></td>
</tr>
<tr>
<td class="bold">Polévka: </td>
<td class="volna_bunka"></td>
<td>{$menu->polevka}</td>
</tr>
<tr>
<td class="bold">1. jídlo: </td>
<td class="volna_bunka"></td>
<td>{$menu->jidlo1}</td>
</tr>
<tr>
<td class="bold">2. jídlo: </td>
<td class="volna_bunka"></td>
<td>{$menu->jidlo2}</td>
</tr>
<tr>
<td> <br /> </td>
</tr>
{/foreach}
</table>
</div>
{/block}
potvrzení formu v presenteru:
public function menuFormSubmitted(Form $form) {
$this->menu->createMenu()->insert(array(
'datum' => $form->values->datum,
'polevka' => $form->values->plevka,
'datum' => $form->values->datum,
'jidlo1' => $form->values->jidlo1,
'jidlo2' => $form->values->jidlo2,
));
$this->flashMessage('Jídlo přidáno.', 'success');
if (!$this->isAjax()) {
$this->redirect('this');
} else {
$form->setValues(array(), TRUE);
$this->invalidateControl('form');
}
}
Po kliknutí na tlačítko Přidat se ale nic nestane. Zkouším to podle quickstartu…
- .:M@rt!n:.
- Člen | 201
Ano, podle quickstartu. Kod je tento:
jQuery.ajaxSetup({
cache: false,
dataType: 'json',
success: function (payload) {
if (payload.snippets) {
for (var i in payload.snippets) {
$('#' + i).html(payload.snippets[i]);
}
}
}
});
// odesílání odkazů
$('a.ajax').live('click', function (event) {
event.preventDefault();
$.get(this.href);
});
// odesílání formulářů
$('form.ajax').live('submit', function (event) {
event.preventDefault();
$.post(this.action, $(this).serialize());
});
- Vojtěch Dobeš
- Gold Partner | 1316
Viz žlutý rámeček hned pod odkázaným nadpisem. Je třeba si stáhnout nějaký solidní skript z doplňků, který řeší, kterým tlačítkem byl formulář odeslán.
- .:M@rt!n:.
- Člen | 201
Už to odesílá. Ale nepozoruji žádnou změnu, oproti tomu, když to bylo klasicky bez AJAXu… Co by se mělo změnit??
- Vojtěch Dobeš
- Gold Partner | 1316
Vůbec nechápu otázku.
Skripty z doplňků by měly například odesílat informaci o odeslaném tlačítku.
Editoval vojtech.dobes (7. 5. 2012 12:33)
- Vojtěch Dobeš
- Gold Partner | 1316
Tak že se odešle AJAXový požadavek :) Lze sledovat kupříkladu ve
Firebugu, stránka zůstane still a na formulář se odešle napozadí.
Na serveru pak lze odeslání AJAXem detekovat metodou presenteru
$this->isAjax()
.
- .:M@rt!n:.
- Člen | 201
Takže jestli to dobře chápu, data co uložím přes AJAX form by se mě měli na stránce ukázat bez kompletního reloadnutí stránky??
- Vojtěch Dobeš
- Gold Partner | 1316
O tom je AJAX: první A ve zkratce znamená Asynchronní. Stránku na začátku načteš klasickým požadavkem, ale formulář odešleš asynchronně (AJAXem), „na pozadí“. Obslužný JS skript pak vrácenou odpověď (která je JSON) nějak zpracuje – typicky nahrazením vrácených snippetů v DOMu na správné místo.
Stačí jeden otazník ;)
Editoval vojtech.dobes (7. 5. 2012 13:29)
- .:M@rt!n:.
- Člen | 201
No a právě, že mě se stejně reloadne celá stránka a data se načtou až potom. Proto se ptám co mám špatně?
- Vojtěch Dobeš
- Gold Partner | 1316
Ahá… nu, a předtím s tím krátkým skriptem ti to fungovalo? Máš na formuláři třídu ajax?
Promiň, máš, to už jsi psal. Máš tam stále ty poslední řádky, kde se pomocí live to ajaxové zpracování navazuje?
Editoval vojtech.dobes (7. 5. 2012 13:37)
- .:M@rt!n:.
- Člen | 201
Předtím to nefungovalo vůbec. V prezenteru u potvrzení formu mám toto:
public function menuFormSubmitted(Form $form) {
$this->context->createMenu()->insert(array(
'datum' => $form->values->datum,
'polevka' => $form->values->polevka,
'datum' => $form->values->datum,
'jidlo1' => $form->values->jidlo1,
'jidlo2' => $form->values->jidlo2,
));
$this->flashMessage('Jídlo přidáno.', 'success');
if (!$this->isAjax()) {
$this->redirect('this');
} else {
$form->setValues(array(), TRUE);
$this->invalidateControl('form');
}
}
čili jestli dobře chápu podmínku, tak ten kód si myslí, že tam AJAX
není a přesměruje mě normálně bez něj(reload celé stránky)…
form vypadá takto:
{snippet form}
{form menuForm class => ajax}
<table bordercolor="white">
<tr>
<td>{label datum/}</td>
<td> {input datum}</td>
</tr>
<tr>
<td>{label polevka/}</td>
<td>{input polevka}</td>
</tr>
<tr>
<td>{label jidlo1/}</td>
<td>{input jidlo1}</td>
</tr>
<tr>
<td>{label jidlo2/}</td>
<td> {input jidlo2}</td>
</tr>
<tr>
<td>{input create}</td><td> {input cancel}</td>
</tr>
</table>
{/form}
{/snippet}
- Vojtěch Dobeš
- Gold Partner | 1316
První otázka je, jestli se ti ten formulář vůbec ajaxově odesílá. To poznáš tak, že to budeš třeba ve Firebugové konzoli sledovat.
- Vojtěch Dobeš
- Gold Partner | 1316
Ve Firebugové konzoli se vypisují všechny požadavky, když si ho rozklikneš, tak tam jsou jednotlivé záložky (mrkni na záložku JSON, myslím).
Editoval vojtech.dobes (7. 5. 2012 15:14)
- .:M@rt!n:.
- Člen | 201
:) při rozkliknutí záložky síť mám: Vše, HTML, CSS, JS, XHR, Obrázky, Falsh a Média. Když kliknu na JS tak mě to vypíše všechny js které mám přilinkovaný a u všech je status „200 OK“
- Vojtěch Dobeš
- Gold Partner | 1316
Já ty AJAXové požadavky sleduju v panelu Konzole. Tam pak po rozkliknutí jsou ty podrobné informace (nicméně jak se dívám, tak v té Síť je to taky). Pak mě zajímá, jaké informace máš v těch podrobnostech onoho requestu.
- .:M@rt!n:.
- Člen | 201
Snad je to to, co potřebuješ :)
Hlavičky:
Cache-Control no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection Keep-Alive
Content-Type text/html; charset=utf-8
Date Mon, 07 May 2012 13:48:38 GMT
Expires Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive timeout=5, max=100
Location http://127.0.0.1:8888/TNPW2/admin/menu/?_fid=gnlq
Pragma no-cache
Server Apache/2.2.17 (Win32) PHP/5.3.4
Set-Cookie PHPSESSID=fcdbmj319h5fmg5peu3gj5gui3; path=/; httponly nette-browser=v2z6fbrnwo; path=/; httponly
Transfer-Encoding chunked
X-Frame-Options DENY
X-Powered-By Nette Framework
Hlavičky požadavkuzobrazit zdroj
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language cs,en-us;q=0.7,en;q=0.3
Connection keep-alive
Cookie PHPSESSID=fcdbmj319h5fmg5peu3gj5gui3; nette-browser=v2z6fbrnwo
Host 127.0.0.1:8888
Referer http://127.0.0.1:8888/TNPW2/admin/menu/?_fid=7mjg
User-Agent Mozilla/5.0 (Windows NT 6.1; rv:12.0) Gecko/20100101 Firefox/12.0
Request Headers From Upload Stream
Content-Length 102
Content-Type application/x-www-form-urlencoded
Post:
_token_ 7mh0ulwltt
create Přidat
datum 07.05.2012
jidlo1 sfgtxdtg
jidlo2 xdghzxdtz
polevka xghdtr
Zdroj
datum=07.05.2012&polevka=xghdtr&jidlo1=sfgtxdtg&jidlo2=xdghzxdtz&create=P%C5%99idat&_token_=7mh0ulwltt
Odezva:
Reload the page to get source for: http://127.0.0.1:8888/TNPW2/admin/menu/?do=menuForm-submit
- Vojtěch Dobeš
- Gold Partner | 1316
Nechápu to úplně poslední :)
Reload the page to get source for: http://127.0.0.1:8888/TNPW2/admin/menu/?do=menuForm-submit
To mě přesně zajímá :) Jinak další způsob debugování (ta kapitola
v dokumentaci vážně chybí, že?) je firelogování. Do Firebugu je třeba
si doinstalovat doplněk Firelogger. A pak lze v PHP volat
Nette\Diagnostics\Debugger::fireLog($whatever);
a v záložce
Firelogger si tyhle dumpy prohlížet (je to jak barDump()
, ale
pro AJAX).
Tobě se to nakonec vždycky přesměruje? Pokud jo, zakomentuj si ten redirect (pro jistotu, pokud tam někde nemáš zapnuté persistování konzole, tak se ti po redirectu resetne).
Editoval vojtech.dobes (7. 5. 2012 16:01)
- .:M@rt!n:.
- Člen | 201
Redirect zakomentován, ale stejně se mě reloadne celá stránka a akorát form zůstane vyplněnej. Asi tam toho bude víc co je špatně tak to večír zkusim udělat znovu podle tohoto tutoriálu
- Vojtěch Dobeš
- Gold Partner | 1316
Máš tam pořád někde tento kód?
// odesílání odkazů
$('a.ajax').live('click', function (event) {
event.preventDefault();
$.get(this.href);
});
// odesílání formulářů
$('form.ajax').live('submit', function (event) {
event.preventDefault();
$.post(this.action, $(this).serialize());
});
- .:M@rt!n:.
- Člen | 201
Jo tak ten mě tam chyběl :) ale teď se form po potvrzení vymaže a data se neukáží. Stránka už se nereloaduje.
- Vojtěch Dobeš
- Gold Partner | 1316
Co znamená, že se form vymaže? Vyprázdní se políčka, nebo formulář úplně zmizí?
- Vojtěch Dobeš
- Gold Partner | 1316
Tak to je přesně to, co chceš, ne? Voláš setValues
, kterým
vyresetuješ všechna pole a invaliduješ snippet.
Jinak schválně se teď mrkni do toho panelu Konzole, rozklikni si ten AJAXový požadavek (POST) – bude tam podzáložka JSON, kde si můžeš prohlédnout, jak se ty snippety posílají.
- .:M@rt!n:.
- Člen | 201
Jo to sice potřebuji, ale jak vypsat ještě ty uložený data, bez reloadu stránky?
Jo jinak už v konzoli JSON je.
Editoval .:M@rt!n:. (7. 5. 2012 16:36)
- Vojtěch Dobeš
- Gold Partner | 1316
Já nechápu, na co se mě ptáš. Snaž se prosím víc specifikovat, čeho chceš přesně dosáhnout.
- .:M@rt!n:.
- Člen | 201
No po potvrzení formuláře by se mě měly vypsat data, které jsem pomocí formuláře uložil do db, bez reloadu stránek. Jenže data se po odeslání formuláře uloží do db ale už se nevypíší(musím sám reloadnout stránku aby se vypsaly). Čili jak k tomu ještě dodělat, aby se data vypsaly po potvrzení formuláře?
- Vojtěch Dobeš
- Gold Partner | 1316
Už chápu. No, pokud chceš nějak ovlivnit výpis těch dat, co tam máš, tak ten musí být taky ve snippetu. Takže obalit do snippetu a invalidovat.