Jak na extension a znovunabindování AJAXu?
- serten
- Člen | 55
Zdravím,
mám takovej menší problém s ajaxovým zpracováním. Mám formulář, který odesílám ajaxem. Bohužel po prvním překreslení se mi neprovedlo navázání ajaxu na prvky a další požadavek teda proběhl klasicky bez ajaxu.
Proto jsem po hedání na foru vytvořil takové pofidérní bindování:
$(document).ready(function(){
$("#frm-projectUsersForm.ajax").live("click", function (e) {
$.nette.ajax(this.href, this, e);
return false;
});
});
U tohoto byl problém v tom, že mi po překreslení přestalo úplně fungovat jQuery.
Zkoušel sem hledat dál a několikrát sem si zkoušel pohrát i s extensionama z knihovny nette.ajax.js , kterou používám, ale vždycky bez nějakýho výsledku. Nechápu co dělám špatně, ale ani jedna extensiona mi nefunguje, i když tam mám jen obyčejnej alert(). Takhle to vypadá v mém kódu:
<script src="{$basePath}/js/jquery.js"></script>
<script src="{$basePath}/js/netteForms.js"></script>
<!-- Core Javascript - via CDN -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.1.0/js/bootstrap.min.js"></script>
<script type="text/javascript" src="{$basePath}/js/main.js"></script>
<script type="text/javascript" src="{$basePath}/js/custom.js"></script>
<script type="text/javascript">
$(function () {
Core.init();
$.nette.init();
$.nette.ext({
complete: function (payload) {
$.nette.load();
alert('snippet complete');
},{
alert('blabla');
}
});
});
</script>
Bohužel ale v tomto druhém případě nefunguje AJAX vůbec. Ajaxové zpracování se kompletně vypne.
Dokázal by mi prosím někdo pomoct a poradit, jak to mám správně vyřešit? Budu vděčný za jakoukoliv pomoc, díky.
- Zax
- Člen | 370
$.live() je v aktuální verzi jQuery deprecated, použij $.on()
Ajaxové extension dej před $.nette.init(); (nejdřív zaregistruj rozšíření a až pak to všechno inicializuj ;-)
Chybí ti první parametr – název rozšíření. Nevím jestli je to přímo povinné, ale třeba to pomůže… např.:
$(document).ready(function() {
$.nette.ext('consoleLog', {
success: function(payload) {
console.log('Incoming payload!');
console.log(payload);
},
error: function(jqXHR, status, error) {
console.log('Ajax failed!');
console.log(error);
console.log(jqXHR);
}
);
$.nette.init();
});
(EDIT: nějak divně se to zbarvuje, asi tam mám syntax error někde, no hledat to nebudu :D )
Editoval Zax (11. 7. 2014 19:51)
- serten
- Člen | 55
Super, díky moc :-) Tvá odpověď mě nasměrovala ke správnýmu
řešení. Je ale teda zvláštní, že když místo .live() použiju .on() tak
mi to vůbec nefunguje. Ale s .live() je vše jak má být.
A ta chyba která se ti nechtěla hledat byla jen v poslední složené
závorce, která chyběla :-D
Tak ještě jednou díky ;-)
- Pavel Macháň
- Člen | 282
serten napsal(a):
Super, díky moc :-) Tvá odpověď mě nasměrovala ke správnýmu řešení. Je ale teda zvláštní, že když místo .live() použiju .on() tak mi to vůbec nefunguje. Ale s .live() je vše jak má být.
A ta chyba která se ti nechtěla hledat byla jen v poslední složené závorce, která chyběla :-DTak ještě jednou díky ;-)
.live bych nepoužíval, od 1.9 je deprecated
- David Kudera
- Člen | 455
Od 1.9 je dokonce pryč úplně, alespoň podle dokumentace. Mimochodem je
v ní i ukázka, jak přejít správně na on
.
- Pavel Macháň
- Člen | 282
David Kudera napsal(a):
Od 1.9 je dokonce pryč úplně, alespoň podle dokumentace. Mimochodem je v ní i ukázka, jak přejít správně na
on
.
@DavidKudera Teď na tu dokumentaci koukám a fakt že odstraněno. Takže nechápu jak mu může jít .live na 1.10 viz import jska co tam @serten má.
- David Kudera
- Člen | 455
No asi to má nějak „pošahané“, protože koukám, že jquery načítá 2×, což je mimochodem chyba.. Jednou od sebe a jednou z cdn. A v cdn ta funkce nikde není
- serten
- Člen | 55
Díky za upozornění, toho jsem si právě vůbec nevšiml. Ale právě jakmile nechám načítání pouze z CDN, tak mi to po předělání na .on() nefunguje. Moje konečná verze je:
$(document).ready(function(){
$( "#frm-reqInfoForm.ajax" ).on("click", function (e) {
$.nette.ajax(this.href, this, e);
return false;
});
});
protože to ještě vlastně pokaždé překresluju v snippetu. Ale bohužel to nefunguje jak má. Jenou se ten požadavek provede a podruhé už to není nabindovaný a provede se klasické přesměrování. Nevíte kde by mohla být chyba?
- David Kudera
- Člen | 455
zkus to změnit na:
$(document).on('click', '#frm-reqInfoForm.ajax', function(e) {
e.preventDefault();
$.nette.ajax(this.href, this, e);
});
kdyžtak na id vygenerovaná frameworkem by se spoléhat takhle v kódu
určitě nemělo. A místo return false by se mělo používat
raději e.preventDefault();
Edit: každopádně načítání dvou různých verzí je chyba a mělo by se to vyřešit ;-)
Editoval David Kudera (16. 7. 2014 12:04)
- serten
- Člen | 55
Tak verze sem samozřejmě promazal a na základě dotazu akadlece sem zvýšil verzi jQeury na nejaktuálnější 1.11.1. Ještě jsem zkusil druhý kód pro nabindování, co mi poradil David Kudera a zkusil jsem změnit selector na form.ajax, ale nic z toho nefunguje. Vyhodil jsem to nakonec i ze snippetu, aby se to pořád nepřekreslovalo.
Zajímavé ale je, že mám na stejné stránce ještě ajaxově zpracované komentáře, ale po prvním překreslení prvního formuláře ajaxové zpracování u komentářů dál funguje.
Nenapadá Vás čím by to mohlo být? Rád poskytnu další informace.
Díky
- David Kudera
- Člen | 455
zkus to ještě takhle:
$(document).on('click', 'form.ajax', function(e) {
e.preventDefault();
$.nette.ajax(this.href, this, e);
});
jo moment… to frm-reqInfoForm id je id formuláře ne?? Jestli jo, tak opravdu na něj chceš navěsit click událost? Nemělo by to být navěšené na submit toho formuláře?
$(document).on('click', 'form.ajax input[type="submit"]', function(e) {
e.preventDefault();
$.nette.ajax(this.href, this, e);
});
tohle se aplikuje na všechny submity ve formulářích s třídou .ajax
Edit: a nebo událost submit
(místo click) přímo na
tom formu
Editoval David Kudera (16. 7. 2014 15:59)
- serten
- Člen | 55
Je to celé nějaké zvláštní, všude jinde ajaxové zpracování funguje v pohodě, jen v tomto jednom případě ne. Právě že jsem nidke jinde toto bindování nemusel řešit, vše se nabindovalo znova samo. Když jsem použil všechny rady, které jste mi tu napsali, tak se mi vždy provedl první ajaxový požadavek, ale neprovedla se mi žádná akce v extension, což vypadá, jako by už s tím samotným ajaxovým zpracováním nebylo něco v pořádku. Zkoušel jsem otestovat, jestli mi to dělalo i u toho .live() a ono ne, tam všechno funguje jak má.
Mám někam nahodit zdrojové kódy presenteru a šablony, aby ste se na to mohli podívat líp?
- serten
- Člen | 55
Je to celé zvláštní, ale mám tam nahozenou pouze jednu a to nejnovější verzi jQuery. Tohle jsou jediné skripty, které tam vkládám. A zkoušel jsem to různě prohledávat, ale nic navíc jsem nenašel, pokud bych se náhodou přehlídl a dal to tam dvakrát.
<script src="/js/netteForms.js"></script>
<!-- Core Javascript - via CDN -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.0/jquery-ui.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.1.0/js/bootstrap.min.js"></script>
<!-- Plugins - Via CDN --
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js"></script>
<!--<script type="text/javascript" src="vendor/plugins/datatables/jquery.dataTables.min.js"></script> Local Option -->
<!-- Plugins -->
<script type="text/javascript" src="/vendor/editors/xeditable/js/bootstrap-editable.js"></script>
<script type="text/javascript" src="/vendor/plugins/chosen/chosen.jquery.min.js"></script>
<script type="text/javascript" src="/vendor/plugins/gritter/js/jquery.gritter.min.js"></script>
<script type="text/javascript" src="/js/uniform.min.js"></script>
<script type="text/javascript" src="/js/main.js"></script>
<script type="text/javascript" src="/js/custom.js"></script>
<script src="/js/nette.ajax.js"></script>
- David Kudera
- Člen | 455
No ale kde se ti tam teda jen tak bere to live? Schválně si takhle otevři neminifikovanou verzi jquery 1.11.1 a zkus si tam vyhledat přímo slovo „live“. Třeba to totiž způsobuje ten tvůj problém..
Editoval David Kudera (17. 7. 2014 12:02)
- serten
- Člen | 55
Tak to vážně netuším, kde se bere. jak mi poradil akadlec, tak sem projel http přenos, otevřel sem si všechny js soubory, které to natahuje a vyhledával v nich live a prostě nic. CHová se to nějak divně. Je pravda že jednu chvíli se mi v konzoli zobrazovalo že .live() je deprecated, ale to bylo jen v jednom případě a teď se k té chybě zase nemůžu dohrabat.
- David Kudera
- Člen | 455
Stačily by zatím klidně jen ty šablony jak píšeš a taky js soubor, kde tohle řešíš
Editoval David Kudera (21. 7. 2014 11:13)
- serten
- Člen | 55
Tak tady je odkaz na archiv s šablonami: http://uloz.to/…/sablony-zip
V otmto případě teda nemám JS kód oddělený v samostatných souborech.
Je v samostatných blocích na konci souboru, v případě layout šablony
jsou inicializační na konci HEAD tagu.
- David Kudera
- Člen | 455
No.. tak nějak tak nechápu, proč máš js zabalený ve snippetech.. Snippety by měli být útržky html bloků a určitě ne js kód
Editoval David Kudera (21. 7. 2014 12:21)
- David Kudera
- Člen | 455
Zkus tohle: link. Na začátku se provede to js a v alertu bude „snippet code called“, po 1s se to js jen tak překreslí a zobrazí hlášku „snippet code changed“. První hláška „snippet code called“ už se ale znovu nezavolá. Překreslený js kód se totiž takhle znovu sám nevolá
Editoval David Kudera (21. 7. 2014 13:48)
- David Kudera
- Člen | 455
Ano to se děje třeba když se události nabindují přímo na element.
$('input[type="submit"]').click(function() {
doSomething();
});
takhle je ta událost přidána přímo na ten daný prvek, když se ale překreslí (je úplně jedno jak), tak se ten předchozí vlastně smaže a vytvoří se nový prvek, který na sobě tyto události nemá.
Dřív se na to používalo live
$('input[type="submit"]').live('click', function() {
doSomething();
});
a nyní se používá jen on
$(document).on('click', 'input[type="submit"]', function() {
doSomething();
});
a to vlastně navěsí událost na celý document, ale vyfiltruje ji vždy znovu pro daný prvek, takže překreslení nevadí.
Jak už tu ale někdo psal, v základu si tohle dělá nette.ajax sám.
Editoval David Kudera (21. 7. 2014 16:20)
- David Kudera
- Člen | 455
Dalším krokem může být vyčlenění js ze šablon do samostatných .js souborů. Teď už to budeš moct udělat, když to není ve snippetech a nejsi tím omezován. Tak si to zpřehledníš ještě víc ;-)