nette.ajax.js – alt. obsluha pro AJAX s jQuery

Kurtas
Člen | 109
+
0
-

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

akadlec
Člen | 1326
+
0
-

a nevoláš tu změnu class a přidání targetu až po tom co se zaregistruje nette ajax, tudíž už je ten button nabindovany? Zkus tam třeba přidat .unbind(„click“)

Kurtas
Člen | 109
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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.logovat“?

Kurtas
Člen | 109
+
0
-

Vojto diky, uz mi funguje i ten tvuj kod mel jsi tam

if (this.isSmallResolution)
spravne ma byt isResolutionSmall, takove prepleky se blbe hledaji :)

Pouziji tve resene, diky moc

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Fixed i v mém příspěvku pro časy příští :). Rádo se stalo.

akadlec
Člen | 1326
+
0
-

@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
+
0
-

Místo off: {unique: false} použij jen off: ['unique'].

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Verze 1.2.2

Tag, Diff

  • 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 z init
  • 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 Analytics
    • fidRemove.ajax.js pro automatické odstranění _fid parametru

Editoval vojtech.dobes (10. 3. 2013 16:08)

akadlec
Člen | 1326
+
0
-

@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
+
0
-

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) {
	}
});
akadlec
Člen | 1326
+
0
-

supr, skvělá práce ;) a asi tedy ještě jeden dotaz :D ty rozšíření sou supr, fajn je že se dají vypínat, ale co takhle zadefinovat rozšíření co je v defaultu vypnuto a pak jen při zvoleném requestu se zapne? tak jak máš off: [exten] tak udělat i on: [exten] ? co?

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

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é).

akadlec
Člen | 1326
+
0
-

No to byla jen taková úvaha ;) že třeba mám dvě a více volání na různých místech co využívají část společnou, ale ta se zase nehodí globálně ;)

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Ukaž konkrétní kód, třeba mě přesvědčíš :).

akadlec
Člen | 1326
+
0
-

:D no bohužel tyhle trumfy v rukávu nemám ;) v předchozí appce jsem to řešil vlastními $.ajax requesty co jsem si podle toho zadefinoval. Jen to byla taková úvaha ;) a je možná snažší to odhandlovat jinak bokem než přes ty extensions ;)

pekelnik
Člen | 462
+
0
-

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
+
0
-

pekelník: ale jak koukam tak ji vojta hodil jako closed ;)

akadlec
Člen | 1326
+
0
-

@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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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.

akadlec
Člen | 1326
+
0
-

Jenže $.nette.load(); provede init všech extension ne? Tudíž to spustí vše co se inituje a to by nadělalo zase bordel :( nejdě nějak spustit jen init zavěšení ajaxifikace?

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

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.

akadlec
Člen | 1326
+
0
-

No mě by to teda taky zajímalo. Zřejmě proto že ty elementy ještě nejsou v DOMu když se spustí ten init. Vyčleněním všeho z initu se zase dostanu do stavu kdy je nette.ajax jen bokovka na handling ajax udalosti, tj. můžu jej celý zahodit a dělat to postaru ;)

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

@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
+
0
-

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
+
0
-

@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
+
0
-

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 :-/

kudlajz
Člen | 70
+
0
-

Zdravim, muzete mi poradit, jak zajaxovat nove vytvorene elementy, ktere jsem ajaxove nahral do modalniho okna?

Glottis
Člen | 129
+
0
-

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
+
0
-

@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)

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Pokud má ten button taky třídu ajax, tak jo.

akadlec
Člen | 1326
+
0
-

Ne, tu třídu ajax má jen ten element FORM, ale když sem si logoval co se děje při kliku na submit tak to ten data atribut bralo právě z toho buttonu.

Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Tohle omrknu, díky.

akadlec
Člen | 1326
+
0
-

nz, ale jako možná bych to tak nechal, aspoň se dají modifikovat jednotlivé buttony ;)

Jakub Šulák
Člen | 222
+
0
-

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
+
0
-

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
+
0
-

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.

pepakriz
Člen | 246
+
0
-

@vojtech.dobes: Chci mít možnost spustit několik požadavků paralelně (vypnu unique) a následně chci při kliknutí na odkaz předchozí paralelní požadavky zrušit.