nette.ajax.js – alt. obsluha pro AJAX s jQuery
- Kurtas
- Člen | 109
Ahoj,
tapu s nasledujicim problemem, mam odkaz
<a href="/nekam" class="ajax popupdialog">odkaz</a>
V initu nette.ajax mam
$.nette.ext('init').linkSelector = 'a.ajax';
takze odkaz se vola ajaxove, ale ted potrebuji pro male rozliseni (mobily atp) zakazat ajax a otevrit odkaz v nove zalozce tak jsem si napsal js funkci ktera odebere class ajax a prida atribut target=„_blank“ ale ono to stejne vola ajaxove ikdyz to tu class jiz nema … nevite nekdo jak to resit?
Tu je ten JS kod co to odebira
if(smallResolution){
$('.popupdialog').each(function(i, obj) {
$(this).removeClass('ajax');
$(this).attr("target","_blank");
});
}else{
$('.popupdialog').each(function(i, obj) {
if($(this).hasClass('ajax') == false){
$(this).addClass('ajax');
}
$j(this).removeAttr("target");
});
}
Diky Mira
- Kurtas
- Člen | 109
Ano volam to az po registraci nette ajax, musi to resit i resize okna, takze to mam v
$(document).ready(function(){
$(window).resize(function() {
...
});
)};
a unbind pomohl. Muzes mi prosim jeste poradit jak znova pak nabidodvat vsechny ty odkazy zpatky na nette ajax jakmile dojde k resizu okna?
Diky
- Kurtas
- Člen | 109
Nakonec jsem to vyresil takto
Chci se zeptat Vojty Dobese jestli je to tak ok?
$.nette.ext('resolution', {
load: function () {
$('.dialogpopup').unbind("click").on('click', function (e){
var $this = $(this);
var w = $(window).width();
var h = $(window).height();
if(w<1000 || h<550){
window.open($this.attr('href'), '_blank');
return false;
}else{
$.nette.ajax({
url: $this.attr('href'),
type: 'POST'
});
return false;
}
});
}
});
Diky Mira
- Vojtěch Dobeš
- Gold Partner | 1316
Jen na zamyšlenou: potřebuješ nutně brát v potaz
resize
? Nestačí výchozí rozlišení při otevření? Možná
k tomu máš jasné důvody, ale pokud je to třeba jen kvůli mobilní verzi,
tak bych spoléhal na úvodní rozlišení.
$.nette.ext({
init: function () {
this.updateResolution();
$(window).resize(function () {
$.nette.load();
});
},
load: function () {
this.updateResolution();
if (this.isResolutionSmall) {
$('.dialogpopup').off('.nette');
}
}
}, {
isResolutionSmall: null,
updateResolution: function () {
this.isResolutionSmall = $(window).width() < 1000 || $(window).height() < 550;
}
});
Jen to asi bude chtít nějakou optimalizaci pomocí setTimeout
,
teď se při každé mikrozměně velikosti okna vykoná docela
dost kódu…
Editoval vojtech.dobes (7. 3. 2013 16:25)
- Kurtas
- Člen | 109
Vojto to tvoje reseni mi nejak nechce fungovat, prosim, vcem je ten muj navrh spatne?
Bohuzel potrebuju resit ten resize to popup okno ma sirku 900px a tak tak se tam vejde vse co je treba tzn kdyz user otoci tablet na vysku tak bych chtel aby mu to automaticky otevrelo v novem tabu, nebo jako odkaz (neajaxove) to je asi jedno.
Editoval Kurtas (7. 3. 2013 15:29)
- Vojtěch Dobeš
- Gold Partner | 1316
Pokud ti to tvoje funguje, není to špatně :). Ale není to moc
systémové, zbytečně otevíráš odkaz pomocí Javascriptu, když to lze
nechat na prohlížeči atd. Ten můj kód počítá s tím, že těm odkazům,
kterých se to týká, dáš atribut target="_blank"
přímo.
Co ti na tom mém nefunguje? Zkoušel jsi to trošku
„proconsole.log
ovat“?
- akadlec
- Člen | 1326
@vojtech.dobes
prosímtě můžeš poradit? zkouším použít přímo metodu nette.ajax
následujícím způsobem:
$.nette.ajax({
url: sSource,
data: aoData,
off: {
unique: false
}
}).done(function (data) {
// ...
});
a problém je ten že pokud ty requesty se spustí za sebou tak se pozabíjejí a jede jen jeden :( Používám to pro načtení DataTables kdy se načítají dvě a více tabulek, jenže se mě načte jen ta poslední. Co dělám špatně?
nette.ajax.js jsem si pro jistotu sosnul teď z mastru a výsledek pořád stejný
- Vojtěch Dobeš
- Gold Partner | 1316
Verze 1.2.2
- aktualizace na nové netteForms.js
- opraveny některé bugy (např.:
history
extenze v Chrome by neměla zobrazovat JSON odpověď) - automatické volání
load
extenze vyčleněno zinit
- přidána metoda
$('.foo').netteAjaxOff()
pro odstranění ajaxifikace z elementu - automaticky je zajaxifikován i
<button type=submit>
element - přidána rozšíření:
confirm.ajax.js
pro[data-confirm]
ga.ajax.js
pro Google AnalyticsfidRemove.ajax.js
pro automatické odstranění_fid
parametru
Editoval vojtech.dobes (10. 3. 2013 16:08)
- akadlec
- Člen | 1326
@vojtech.dobes: supr dík moc, přitom stačilo se kouknout o pár postů dále kde jsi se opravit při odpovídání;)
nicméně měl bych na tebe ještě jeden dotaz ;) snad tu nebyl už
zodpovězen ;)
Když dělám to volání pomocí nette.ajax potřebuju provést nějaké akce
před requestem, je tam tedy nějká možnost zavolat before?
$.nette.ajax({
url: sSource,
data: aoData,
off: ['unique', 'spinner']
}).done(function (data) {
// ... tady to je ok akce po dokonceni
});
po dokončení je to jasné ale potřebuju ještě něco před. Mám to použité v datagridu pomocí datatables a před odesláním akce potřebuju udělat check kolik je vybraných řádků, či vyžádat od usera confirmaci akce atd…
- Vojtěch Dobeš
- Gold Partner | 1316
Určitě :). V tomto se skript drží originálního API z jQuery:
$.nette.ajax({
...,
beforeSend: function (xhr, settings) {
}
});
Pokud ti nevadí, že onen callback proběhne těsně (milisekundy) po
zahájení requestu (např. zobrazení spinneru je typický případ), můžeš
místo toho použít klíč start
:
$.nette.ajax({
...,
start: function (xhr, settings) {
}
});
- Vojtěch Dobeš
- Gold Partner | 1316
Ne :). Byla by to zbytečná režie pro něco, co je z povahy asi lepší řešit jinak než extenzi (proč by to jinak bylo primárně vypnuté).
- pekelnik
- Člen | 462
tahle myšlenka je tady už delší dobu:
https://github.com/…js/issues/35
zatím to řeším validací elementu v before eventu…
Editoval pekelnik (11. 3. 2013 13:15)
- akadlec
- Člen | 1326
@vojtech.dobes: ahoj, promiň že zase otravuju, ale právě zajaxovávm tu appku a co jde tak přehazuju na nette.ajax a narazil jsem na zvláštní problém. Když kliknu na link co má vypsat uložené články tak se tento link neuloží do historie a nezmění se url v adresním řádku. všechny ostatní linky zatím ok.
Všechny akce v tom presenteru končí stejné, invaliduje se snippet pro tělo té stránky, hlavička atd. Když se podívám na odpověď co vrátí server tak jak v případě kdy to neuloží tak i v případě kdy to uloží do historie je odpověď stejná (samo až na obsah invalidovaných snippetů)
Co je tedy rozdíl, tak to že je tam extension onsuccess která inituje na té stránce datatables plugin. Žeby se to nějak bilo s nette ajax?
A obecný dotaz, používá někdo z vás easyTabs pro jquery? (http://os.alfajango.com/easytabs) tenhle plugin mi totiž taky dělá ve spojení s nette.ajax bordel :(, a to konkrétně při kliku na záložku se spustí ajax request. Nemůže to spouštět to že při kliku na záložku se přidá do url hash s id té záložky?
- akadlec
- Člen | 1326
Takže k tomu uložení do historie…když sem přidal delay při načtení stránky před spuštěním inicializace DataTables tak to začalo makat, nicméně s těmi datatables se objevily další problémy. V datagridu jsou klasicky buttony na editaci záznamu který je načten přes ajax. Někdy se ty ajax akce na button bez problému pověsí a někdy ne. Dá se nějak zavolat reinit zavěšení akcí?
A problém s easyTabs vyřešilo zakázání přidávání hashe do url při kliku na tab (updateHash: false)
- akadlec
- Člen | 1326
Jde nějak zavolat konkrétní extension? Věc se má tak že pomocí nette.ajax načtu data, ale při tomhle requestu mám vypnuty skoro všechny extension. Získáná data se předají dataTables která je pak postupně nahází do tabulky a já potřebuju aby se po tom nahazení nějak spustil extension co mi aktivuje tooltipy. Když se ta extension spustí po zpracování requestu je to brzo, protože tabulka ještě není nalitá v DOMu. Jedním řešením je dát do té extension co registruje tooltipy malé zpoždění ale to mi nepříjde moc košér, další je že to prostě vyhodím z nette extensions a bude to mimo a v extension si to jen budu volat, ale to taky nechci, resp co jde tak dávám do těch extensions abych to měl hezky po ruce. Takže jde nějak externě spustit ta vybraná extensions, nějaký reinit?
- Vojtěch Dobeš
- Gold Partner | 1316
Myslím že naprosto architektonicky nejlepší řešení je to, které jsi navrhnul: vyčlenit samotnou funkcionalitu tooltipů někam ven, a pouze ji v té extension volat. Extension nemusí být kompletní celek, pořád je to jen (komplexní) hook do ajaxového životního cyklu. Takže já bych to udělal právě takto. A v případě těch datatables to zavolal sám zcela mimo extension.
- Vojtěch Dobeš
- Gold Partner | 1316
Znamená „reinit zavěšení akce“ ajaxifikaci elementů? Lze to, stačí
ručně zavolat $.nette.load();
. Znovu to navěsí callbacky na
všecky elementy se CSS třídou ajax
.
- Vojtěch Dobeš
- Gold Partner | 1316
Jenže $.nette.load(); provede init všech extension ne?
Ne :). Zavolá load
všech extension. Máš pravdu, že to by
mohly být komplikace.
Zajímalo by mě, proč se ti ajaxifikace někdy navěsí, a někdy ne…
jinak řešil bych to opět stejně, vyčlenil bych obsah init
extenze někam ven a ručně si ho zavolal.
- Vojtěch Dobeš
- Gold Partner | 1316
Bude to asi tím, že po úspěšném doběhnutí požadavku se znovu zajaxifikují všechny elementy, ale ty DataTables jsou aktualizovány až poté.
Klidně jej zahoď (zdaleka to není jen nějaká bokovka, automaticky řeší spoustu příjemných maličkostí), já tento přístup rozhodně považuju za pěknou architekturu.
- Stic
- Člen | 28
Zdravim,
chcem sa opat po case spytat zrejme na prkotinu…
Potrebujem aby ked dam uzivatelovi link na jeho profil v aplikacii, tak aby po vyziadani prihlasenia redirectlo spat na tento odkaz (uz ako prihlaseneho).
To mi vsetko ide a pracuje, vyuzil som storeRequest a restoreRequest. mam prihlasovanie cez socialne siete a klasicky login formular. Socialne siete su len tlacitka bez ajaxu, restoreRequest prebehne v poriadku.
Login formular mam ale ajaxovy, je to formular v komponente, kde mam metodu:
<?php
public function loginFormSubmitted(Form $loginForm)
{
$values = $loginForm->getValues();
$this->loginType = $values->loginType;
try {
$user = $this->presenter->getUser();
if ($values->remember) {
$user->setExpiration('+ 14 days', FALSE);
} else {
$user->setExpiration('+ 20 minutes', TRUE);
}
$user->login($values->mm_id, $values->password);
$this->presenter->flashMessage('Successfully logged in!', 'alert-success');
$this->presenter->restoreRequest($this->presenter->backlink);
$this->presenter->redirect('Screen:');
} catch (\Nette\Security\AuthenticationException $e) {
$loginForm->addError($e->getMessage());
if ($this->presenter->isAjax() ) {
$this->invalidateControl();
}
}
}
?>
Problem je, ze vidim ze restoreRequest prebehne, v konzole vidim vratenu celu stranku s uzivatelovym profilom, ale ma prebehnut redirect a ten neprebehne.
Co treba upravit v javascripte aby fungoval redirect z restoreRequestu?
Dakujem.
- yogiman321
- Člen | 11
Ahojte, chcel by som vás poprosiť o radu pri riešení mojej situácie, ktorá je definovaná takto:
Mám hlavné menu s tlačtkami(class="ajax-flow) a po kliknutí na odkaz chcem zabaliť obsah stránky pod menu pomocou fadeOut, a po získani snippetov a aktualizácií DOM chcem zobraziť obsah pomocou fadeIn.
Teraz to mam spravené cez $.ajax a funguje. Ale akonahle zmenim na $.nette.ajax tak sa to javí akoby sa požiadavka vykonala dvakrát.
$(function () {
$('.ajax-flow').on('click', function(e){
e.preventDefault();
var href = $(this).attr('href');
var active = $(this).hasClass('active');
if (active == true) {
return false;
}
var old_pos = $("a.active").attr('data-position');
var this_pos = $(this).attr('data-position');
$("a.active").removeClass('active');
$(this).addClass('active');
var obr_width = 950;
var kolko1 = (($(document).width() - obr_width)/2)+950;
if (old_pos < this_pos) {
var kam1 = '-'+kolko1;
var kam2 = kolko1+'px';
} else {
var kam1 = kolko1
var kam2 = '-'+kolko1+'px';
}
$.nette.ajax({
type: 'GET',
url: href,
success: function(data){
$('#snippet--body').slideUp('slow', function() {
$('#snippet--body_top').animate({
opacity: 0.0,
left: kam1
}, 750, function() {
$('#snippet--body_top').css('left', kam2);
for (var i in data.snippets){
var $el = $('#' + i.replace(/[\!"#\$%&'\(\)\*\+,\.\/:;<=>\?@\[\\\]\^`\{\|\}~]/g, '\\$&'));
$el.html(data.snippets[i]);
};
$('#snippet--body_top').animate({
opacity: 1.0,
left: '0'
}, 750, function() {
$('#snippet--body').slideDown('slow');
});
});
});
}
});
return false;
})
});
Aké použitie eventov, by bolo v tomto prípade to správne?
A taktiež očakávam aby sa po ajaxovom „prepnutí“ stránky, zmenila aj
URL v prehliadači.
Teraz sa to nemení aj keď mám .ajax alebo .nette.ajax.
Vďaka za radu.
Editoval yogiman321 (27. 3. 2013 10:10)
- duskohu
- Člen | 778
Ahoj, Nevedel by si mi poradit ako by sa dal vyuzit tento confirm dialog, bez pouzitia live, aby to slo aj ajaxovo aj neajaxovo? Samozrejme ide mi o to ako by sa to dalo pouzit ako extenze pre tvoj doplnok.
- josef.sabl
- Člen | 153
Báječný, u starýho jquery.nette.js jsem měl problém, že pokud se klikalo na ajax odkazy příliš rychle, některé se nezaznamenaly, přechodem na tuhle knihovnu vše automaticky začalo fungovat. Díky!
- Gaprielko
- Člen | 42
Zdravim, chcem sa spytat, ci uz niekto riesil / vyriesil tento problem https://forum.nette.org/…jax-s-jquery?p=7 ??
Prip. nejaky napad, ako by sa do dalo poriesit?
- Vojtěch Dobeš
- Gold Partner | 1316
@motorcb, @JAM3SoN a @Gaprielko: vyzkoušejte novou podporu (na masteru).
$.nette.ext('snippets').complete(function () {
alert('All snippets were updated!');
});
Pokud to nebude fungovat, můžeme ladit dál :).
- Gaprielko
- Člen | 42
ok, funguje to, alert stacilo nahradit $.nette.load(); :) – ja som do javascriptu totalny puk..
no funguje mi, ze alert v skripte nizsie, sa vykona az po skonceni
efektu, ale ako si re-inicializujem novy html kod, ktory mi vrati ajax? Linky
v aktualizovanom html sa stale nevykonavaju ajaxovo..
$.nette.ext('snippets').complete(function () {
alert('All snippets were updated!');
});
Editoval Gaprielko (5. 4. 2013 9:19)
- Gaprielko
- Člen | 42
@vojtech.dobes: vdaka, za tu predchadzajucu upravu, no narazil som este na jeden problem.. mam tabulku, v ktorej mam niekolko zaznamov a v kazdom riadku mam tl. pre odstranenie konkretneho zaznamu.. ak ajaxovo odstranim zaznam (handle motoda) a v aktualizovanom html kode dostanem vsetky polozky okrem vymazanej, tak sa nevykona complete event
$.nette.ext('snippets').complete(function () {
// nevykona sa ..
}
sprava sa to rovnako s effektom pri update snippetu ako aj bez neho.. (zistil som to tak, ze mi nezmizne spinner)
Pokial vsak tym istym klikom len aktualizujem zaznam v tabulke a v aktualizovanom html vratim ci uz vsetky polozky alebo len aktualizovanu, tak to ide ok
- TOMeek
- Člen | 64
duskohu napsal(a):
Ahoj, Nevedel by si mi poradit ako by sa dal vyuzit tento confirm dialog, bez pouzitia live, aby to slo aj ajaxovo aj neajaxovo? Samozrejme ide mi o to ako by sa to dalo pouzit ako extenze pre tvoj doplnok.
To by se mi také hodilo. Dva dny se to při chvílích snažim napsat, ale buď se mi požadavek provede vždy, aniž by čekal na kliknutí nebo se mi neprovede vůbec :-/
- Glottis
- Člen | 129
kudlajz napsal(a):
Zdravim, muzete mi poradit, jak zajaxovat nove vytvorene elementy, ktere jsem ajaxove nahral do modalniho okna?
treba nejak takto?
$.nette.ext('name', {
load: function () {
$('.datepicker').datepicker({
format: "yyyy-mm-dd",
language: "cs"
});
$('.selectbox').select2({
width: "resolve"
});
$('.chosen-select').chosen();
}
});
- akadlec
- Člen | 1326
@vojtech.dobes
hele zkouším vypnout rozšíření přes data atribut a nějak se tomu nechce
fachčit :(
<form id="frm-blockForm-1" method="post" action="--url--" data-ajax-off="snippets" class="ajax" novalidate="">
... telo formu
</form>
cílem je že po zpracování formu aby to nereplacovalo snippety. Když to dám přímo do JS do volání tak to funguje ale tady v html ne :( nějaký bug? nebo dělám něco špatně?
edit:
asi teda moje chyba, to musí být na tom buttonu kterým se to vyvolává
že ;)
Editoval akadlec (16. 4. 2013 19:24)
- Jakub Šulák
- Člen | 222
Měl bych dotaz k extension „history“. V Chromu se po načtení stránky provádí updateSnippet na řádku 32 skriptu history.ajax.js. V případě, že mám následující kód:
<?php
...
{snippet neco}
<script>
alert("test");
</script>
{/snippet}
...
?>
Pak se ve firefoxu a IE alert vypíše jen jednou, ale v Chromu dvakrát (hned po načtení stránky). Nevím přesně proč se provádí updateSnippet ve skriptu history.ajax.js. Nesetkali jste se někdo s tímto problémem?
- pepakriz
- Člen | 246
V situacích, kdy je potřeba spustit několik AJAX dotazů, lze ochranu proti více požadavkům vypnout následovně:
$.nette.ajax({
url: ...,
off: ['unique']
});
Požadavky běží a ve stejný čas kliknu na ajaxový odkaz, který mě zavede na jinou stránku. Za nějaký čas doběhnou i dříve spuštěné úlohy, které vrátí již zastaralé snippety. V některých situacích se může stát, že budu vrácen na původní stránku, záleží, jaké snippety se odešlou.
Bylo by dobré, kdyby existovala možnost, jak přerušit probíhající
requesty, které nebyly rozšířením unique
obslouženy. Ostatně
i v komentáři se píše: abort last request if new started
,
tedy očekával bych, že se přeruší jakýkoliv předchozí request.
- Vojtěch Dobeš
- Gold Partner | 1316
pepakriz Nechápu přesně čeho je třeba dosáhnout.
Užití off: ['unique']
vyjme daný request z rušení
požadavků. Pokud chceš, aby byl požadavek zabit dalším, tak je třeba ho
nechat běžet s unique
.