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

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

Jo, pro plně Ajaxovou aplikaci je to ten správný přístup :). Naštěstí IE10 už bude History API podporovat… já teď dělám jednu full-ajax aplikaci, a tam mám taky ajax (ten pro přecházení mezi „stránkami“, tedy měnící URL) v IEčkách vypnutý (resp. vypnutý tam, kde:

!(window.history && history.pushState && window.history.replaceState && !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1–4]|WebApps\/.+CFNetwork)/)) (což jsou ty prohlížeče, které pushState nepodporují, nebo ho podporují blbě – je to lepší než vypínat přímo podle prohlížeče)

Já jsem na Githubu to vyřešil trošku jinak než ty, proto se ptám, jestli je ta moje oprava ok: vždy ten tagName kontroluju přímo na nativním objektu elementu.

Andrasin
Člen | 29
+
0
-

Ahoj, mám ajaxový paginator a chtěl bych, aby se po překreslení odscrolovalo na vrchol stránky. Koukal jsem že je na to na githubu doplněk, ale nevím, jak ho předělat tak, aby to fungovalo jen pro ten paginator a script se nespouštěl po každém ajaxovém požadavku. Lze to nějak udělat?

tmysik
Člen | 16
+
0
-

Ahoj, předem se omlouvám, JS moc neumím. Nevím jak nejlíp přepsat mou stávající metodu updateSnippet pro tento nový nette.ajax.js – jde o to, že před samotným nahrazením snippetu se ještě musí zavolat metoda na stávajících select boxech (neptejte se mne proč, nevím, HTML šablony jsem nedělal). Kód, který se volá hned potom, zavolat dokážu (pomocí vlastní extension).
Poradíte mi někdo, prosím? Předem děkuji.

Má stávající metoda:

<script>
        updateSnippet: function (id, html) {
            var element = $('#' + id);
            var elementSelects = $('#' + id + ' select');
            // destroy selectboxes
            elementSelects.selectBox('destroy');
            // insert response
            element.html(html);
            // load selectboxes, calendars etc.
            element.trigger('contentload');
        }
</script>
tmysik
Člen | 16
+
0
-

Nakonec jsem to vyřešil takto, ale ideální to rozhodně není :/

<script>
    var snippetsExt = $.nette.ext('snippets');
	snippetsExt['updateSnippet'] = function (id, html, back) {
		var $el = this.getElement(id);
		// Fix for setting document title in IE
		if ($el.get(0).tagName == 'TITLE') {
			document.title = html;
		} else {
            // destroy selectboxes
            $el.find('select').selectBox('destroy');
            // apply snippet
			this.applySnippet($el, html, back);
            // load selectboxes, calendars etc.
            $el.trigger('contentload');
		}
	};
</script>
Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Můžeš si na to napsat extenzi, která závisí na jiném rozšíření:

$.nette.ext({
	success: function (payload) {
		var snippets = this.ext('snippets', true);
		$.each(payload.snippets, function (id) {
			var $el = snippets.getElement(id);
			$el.find('select').selectBox('destroy');
			$el.trigger('contentload');
		});
	}
});
tmysik
Člen | 16
+
0
-

vojtech.dobes napsal(a):

Můžeš si na to napsat extenzi, která závisí na jiném rozšíření:

To bohužel nejde, destroy se musí volat před nahrazením snippetu, contentload zase po něm (to problém není). Ono by to šlo vyřešit, kdybych svou extension mohl dát před extension snippets, ale to nejde – možná námět na zamyšlení? ;)

Každopádně díky moc za tvou skvělou práci.

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

Ahá, už chápu… no, v tom případě to asi jinak než jak to máš ty nejde… ohledně ovlivnění pořadí extenzí: pracuje se na tom :).

Ačkoliv s těmi snippety se potýkám docela často, a možná by stálo za zamyšlenou, jestli by extenzi snippets neměla poskytovat vlastní širší API, pomocí kterého by šlo podobné speciální úkony zaregistrovat. Extenze extenze. Když už máme v Nette Extensions\ExtensionsExtension :).

Editoval vojtech.dobes (16. 11. 2012 12:07)

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

Trochu jsem doplnil dokumentaci: https://github.com/…er/readme.md#…

Ot@s
Backer | 476
+
0
-

vojtech.dobes napsal(a):

  • persistentní parametry (pro jejich uchovávání není třeba všechny odkazy obalovat do snippetů a invaliovat je, nové ajaxové požadavky vyvolané na původních odkazech budou automaticky o aktuální stav persistentních parametrů doplněny – jde o dokončení extenze state)

Mám praktické problémy s použitím $.nette.ext('state').

  1. Pokud se nějaký index v settings.data shoduje s indexem ve state, tak je přebit hodnotu ze serveru (přepsán tím, co mu pošle server v this.state). To se dá vyřešit pomocí $.extend(settings.data || {}, this.state) (prohození settings.data a this.state). Hmm…
  2. K tomu nechápu chování Application/UI/Presenter::getGlobalState(), které vrací prostřednictvím payload->state persistetní proměnné, které jsou ve výchozích hodnotách. To by se tak přece nemělo chovat (persistetní proměnná s výchozí hodnotu se do URL nedává).

Možná to celé nechápu, nicméne this.state se pro mě stalo nepřítelem a odstavil jsem ho. Možná někdo z výše uvedených bodů pochopí moje neporozumění problému a vysvětlí mi to. Dopředu díky.

pekelnik
Člen | 462
+
0
-

State obsahuje „stav“ tedy vcetne hodnot persistentnich parametru. To ze v URL nejsou je vec zcela jina a je to zalezitost routingu.

h4kuna
Backer | 740
+
0
-

Ve čtyři ráno nemám co dělat tak programuju a objevil jsem divné chování state dvě hoďky jsem se v tom šťoural a výsledek:

Dělám dotaz pomocí autocomplete, ten se provede, invaliduje se snippet a automaticky se nastaví state

"state":{"filter":null,"id":"2","lang":null,"imagePicker-folderId":"1","imagePicker-vp-page":null}

a mám VisualPaginátor který jsem si chci aby fungoval ajaxově, odkaz na stránku 2 je správně

/admin/products/photos/2/?imagePicker-vp-page=2&imagePicker-folderId=1&do=imagePicker-Paginator

A v momentě kdy na to kliknu, tak tato extenze mi znetvoří url a přidá tam parametry ze state což nechci.

/admin/products/photos/2/?imagePicker-vp-page=2&imagePicker-folderId=3&do=imagePicker-Paginator&filter=&id=2&lang=&imagePicker-folderId=3&imagePicker-vp-page=

Proto mi nejede stránkování, parametr imagePicker-vp-page je dvakrát, bez ajaxu funguje. Chtělo by to nějakou kontrolu je-li parametr v url tak ho tam nedávej.

Editoval h4kuna (29. 11. 2012 5:55)

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

Ad případ state: omlouvám se všem, komu způsobuje potíže. Proto tato „feature“ ještě zdaleka nebyla zařazena do stabilní verze. Jsem rád, že jste se s ní někteří poprali. Extenze by pochopitelně měla fungovat tak, aby zachovávala persistentní parametry i na odkazech, které nebyly s posledním požadavkem invalidované ve snippetu. Nicméně to vypadá, že state tak docela neobsahuje to, co by měl.

Přidávání parametrů jen tehdy, pokud nejsou v URL, může být problém u nějakých fancy rout. Naopak mě napadá potíž, že dost dobře s aktuální podobou tohoto rozšíření nelze zachovat odkaz, který by nějaký persistentní parametr měnil.

Zatímto to revertnu.

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

Verze 1.2.1

  • podpora pro nekonečné scrollování, resp. rozšiřování snippetu místo jeho přepisování (více zde)
  • zdroják obsahuje číslo verze
  • události success, error a complete dostávají tytéž parametry jako nativní události v jQuery
  • přidána nová událost prepare, která se volá ještě před before a dostává za parametr settings požadavku (událost by neměla záviset na tom, jestli požadavek proběhne, nebo ne)
  • rozšířil jsem API snippetového rozšíření – nyní je možné pracovat efektivně přímo se snippety:
$.nette.ext('snippets').before(function ($el) {
	// příležitost k odvázání událostí a dalšího smetí...
});
$.nette.ext('snippets').after(function ($el) {
	// ... a v již aktualizovaném snippetu možnost navázat haraburdí nové
});

Aktualizovaná je také dokumentace v readme.

Editoval vojtech.dobes (29. 11. 2012 17:48)

crempa
Člen | 198
+
0
-

Zdravim a diky za perfektni praci!
Mel bych jednu pripominku, pri pokusech nasadit Tve reseni jsem v projektu narazil na chybu TypeError: $el.get(...) is undefined v casti

// Fix for setting document title in IE
if ($el.get(0).tagName == 'TITLE') {

Jde o to ze Nette v urcitych pripadech posila prazdny snippet #snippet-name:"" a to i v pripade ze pri prvnim renderu stranky se dany blok kvuli podminkam nevygeneroval (tedy v DOM vubec neexistuje zadny prvek s ID snippet-name). Netusim zda je o chybu ci vlastnost Nette, ale stava se me to v pripadech zanorenych snippetu uvnitr podminek.

Obecne by tedy stacilo pridat kontrolu zda $el vubec existuje a pokud ne tak se nepokouset o nic dalsiho.

Ono neni problem si Tvuj kod rozsirit tak aby se to presne takhle chovalo, ale davam to jako namet na drobnou upravu.

Diky!

MW
Člen | 626
+
0
-

Zdravim, prosim o radu.

Lze nejak jednoduse hodit spinner do modalniho okna? Pouzivam ted tento:

Díky !

(function($, undefined) {
$.nette.ext('spinner', {
        init: function () {
                spinner = $('<div></div>', { id: "ajax-spinner" });
                spinner.appendTo("body");
        },
        before: function (xhr, settings) {
                $("#ajax-spinner").css({
                        visibility: "visible",
                        left: settings.nette.e.pageX,
                        top: settings.nette.e.pageY
                });
        },
        complete: function () {
                $("#ajax-spinner").css({
                        visibility: "hidden"
                });
        }
});
})(jQuery);
Vojtěch Dobeš
Gold Partner | 1316
+
0
-

@crempa Nechceš připravit pull request :)? Každopádně díky za upozornění, příště rovnou otevří issue na Githubu, to je nejlepší.

flr
Člen | 6
+
0
-

Ahoj, mám stránku s komentářema a hodnocením – oboje ajaxově funguje.

Mám kód:

<script>
$(function () {
	$.nette.ext('comments', {
		start: function (jqXHR, settings) {
			$('textarea,input').prop('disabled', true);
		},
		success: function (payload) {
			$.scrollTo($('#comments'), { duration: 500});
		}
	});
	$.nette.init();
});
</script>

Ten se ale vykoná jak při přidání komentáře tak i při ohodnocení.
Jak mám udělat to aby přidání komentáře a ohodnocení mělo svoje vlastní callbacky?
Můžete mi uvést nějaký příklad, javascriptu moc nerozumím.

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

Máš 2 možnosti. Buď můžeš na serveru do payloadu nastavit nějakou svoji hodnotu a v success callbacku kontrolovat její existenci. Anebo použit $.nette.ajax() metodu.

$('a.comments-rate').on('click', function (e) {
    $(this).netteAjax(e).done(function (payload) {
        // your code
    });
});

Editoval vojtech.dobes (17. 12. 2012 22:16)

flr
Člen | 6
+
0
-

Díky za nakopnutí, už mi to šlape odděleně. Akorát se vyskytl problém s netteForms.js – validiace se provádí dvakrát za sebou ale jakmile se formulář načte znovu ajaxově tak se pro změnu neprovede vůbec.

Napsal jsem to takto:

	// rating - to je v pohodě
	$(document).on('click', 'a.rateAjax', function (event) {
		console.log('rating click');
		$(this).netteAjax(event).done(function (payload) {
			console.log('rating success');
		}).always(function () {
			console.log('rating complete');
		});
	});

	// comment
	$(document).on('submit', 'form.addCommentAjax', function (event) {
		console.log('comment submit');
		$(this).netteAjax(event).done(function (payload) {
			console.log('comment success');
		}).always(function () {
			console.log('comment complete');
		});
	});
Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Udělej to jako extenzi a nevyužívej té live vlastnosti metody on. Ač to možná není zcela žádoucí, nette.ajax.js má vlastní způsob, kterým zajišťuje bindování callbacků.

$.nette.ext({
	load: function () {
		$('form.addCommentAjax').off('submit', this.callback)
		.on('submit', this.callback);
	}
}, {
	callback: function (event) {
		console.log('comment submit');
		$(this).netteAjax(event).done(function (payload) {
			console.log('comment success');
		}).always(function () {
			console.log('comment complete');
		});
	}
});
duskohu
Člen | 778
+
0
-

Ahoj, nevedel by si mi poradit? Mám selctBox na neho som si dal data atribút a napísal extenziu na onChange ktorá mi ajaxovo volá handle ktorý mi zmení další selectBox url si posielam v data tribúte. Problém je v tom že po zmene selectBoxu v firebugu sa mi posiela stale viac a viac požiadavok, stále +1. Nevieš mi poradiť čo mám zle?
form:

$form->addSelect('name', 'Typ', $grupType->fetchPairs("id", "name"))
        ->setAttribute('data-dependent-select-box', $this->link('changeName!'))

handle:

public function handleChangeName() {
    $form = $this->getComponent("form");
    // nastavim dalsiemu selectboxu nove data
    if ($this->presenter->isAjax()) {
        $this->invalidateControl();
    } else {
        $this->presenter->redirect('this');
    }
}

js:

$.nette.ext('data-dependent-select-box', {
    load: function () {
        $('select[data-dependent-select-box]').change(function(e){
            e.preventDefault();
            var url = $(this).data('dependentSelectBox');
            if(url !== 'undefined'){
                $.nette.ajax({
                    url: url
                });
            }
        });
    }
});
Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Ten callback registruj pomocí on('change', ... a vždy ho ještě před tím preventivně odregistruj pomocí off('change). Pokud chceš mít jistotu, že ti to off odváže jen tento callback, můžeš tu událost change namespacovat (je o tom kapitolka v jQuery dokumentaci).

flr
Člen | 6
+
0
-

vojtech.dobes napsal(a):

Udělej to jako extenzi a nevyužívej té live vlastnosti metody on. Ač to možná není zcela žádoucí, nette.ajax.js má vlastní způsob, kterým zajišťuje bindování callbacků.

$.nette.ext({
	load: function () {
		$('form.addCommentAjax').off('submit', this.callback)
		.on('submit', this.callback);
	}
}, {
	callback: function (event) {
		console.log('comment submit');
		$(this).netteAjax(event).done(function (payload) {
			console.log('comment success');
		}).always(function () {
			console.log('comment complete');
		});
	}
});

Tak bohužel i s tímto kódem se ta validace provádí pořád dvakrát. Nyní funguje i po znovu načtení formuláře, ale alert na mě prostě vždycky vyskočí dvakrát za sebou.

Editoval flr (20. 12. 2012 1:49)

duskohu
Člen | 778
+
0
-

nakoniec satcilo ze som to dal do init preco bol problem ked to bolo v load, to uz neviem

$.nette.ext('data-dependent-select-box', {
    init: function () {
        $('select[data-dependent-select-box]').on("change", function(e){
            e.preventDefault();
            var url= $(this).data('dependentSelectBox');
            if(url !== 'undefined'){
                $.nette.ajax({
                    url: url,
                });
            }
        });
    }
});
saimons
Člen | 293
+
0
-

Zkousel jsem predelat aplikaci a narazil jsem na problem, ktery nevim jak vyresit. Pres JQuery UI nacitam dialogove okno ve kterem je formular se tridou ajax. Ale odeslani se neprovede pres ajax. Kdyz jsem to zkusil na normalne vykreslene strance, vse fungovalo. Moc nevim v cem by mohl byt prolem, muzete prosim nekdo poradit?

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

To bude asi tím, že jQuery UI Dialog tam nějak hýbne s HTML, schválně ukaž HTML a JS kód, o který konkrétně jde. Ztratí se tam ajaxové navázání. Buď můžeš ajax znovu navázat (asi v události create, co Dialog nabízí), anebo si pozměnit výchozí ajaxizaci.

duskohu
Člen | 778
+
0
-

Cauko, vedel by si mi poradit? Ako presuvat nejaku hodnotu medzi 2 sekciami extenze?

takto mi to nejde:

load: function () {
    $('*[data-click-handle]').click(function(e){
        this.id = $(this).attr('id');
        e.preventDefault();
        var obj = $(this).data('clickHandle');
        $.nette.ajax({
            url: obj.url
        });

    });
},
success: function () {
  alert(this.id);
}
Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Zdravíčko, jdeš na to dobře, jen ta anonymní funkce předávaná jako callback na click ma jiný kontext než ten extenzní callback. Takže třeba takto:

load: function () {
	var that = this;
	$('*[data-click-handle]').click(function(e){
		that.id = $(this).attr('id');
		e.preventDefault();
		var obj = $(this).data('clickHandle');
		$.nette.ajax({
			url: obj.url
		});
	});
},
success: function () {
	alert(this.id);
}
vvoody
Člen | 910
+
0
-

Zdravím, potrebujem podariť so zajaxovaním formulára. Chcel by som ho odosielať <button> tagom kvôli jeho html obsahu:
latte:

<button n:input="send" class="btn ajax"><i class="icon-ok"></i></button>
{input send class=>btn}

html:

<button class="btn ajax" type="submit" name="send" id="frmform-send"><i class="icon-ok"></i></button>
<input class="btn" type="submit" name="send" id="frmform-send">

Bez ajaxu fungujú správne obe tlačítka, so zapnutým len <input> tlačítko. Po kliknutí na <button> vidím v konzole len GET XMLHttpRequest na aktuálnu url, tým pádom v response je celý html kód. Inicializáciu mám defaultnú. Robím niečo zle?

jetpack
Člen | 71
+
0
-

Nemá s tím něco dočinění to, že máš u obou elementů stejné ID: id=„frmform-send“ ?

vvoody
Člen | 910
+
0
-

Nie, ich správanie sa nezmení, aj keď vždy jeden z nich odstránim. Rozmýšľal som či nebude problém v tom, že defaultne sa na button nenavesuje callback (skúšal som upraviť button selector, zase bez efektu) ale to je asi nepodstatné, kedže callback je aj tak zavesený na odosielanie formulára a aj sa zrejme zavolá, len ajax request ide na nesprávnu url a nesprávnou metódou (GET). Kde by som mal hľadať chybu?

edit: už som myslím na správnej ceste :)

console.log(settings);
xhr = $.ajax(settings);

property url mam undefined, takže preto si jquery doplní aktuálnu url

edit2: tak som si doplnil isSubmit a všetko ide ako má.
row 161:

isSubmit: $el.is('input[type=submit], button[type=submit]'),

Je to správny fix? Alebo tam ten button nieje zámerne?

Editoval vvoody (1. 1. 2013 11:26)

medhi
Generous Backer | 255
+
0
-

Ahoj,

jak prosím zajaxuji dynamicky vložené HTML? (vložené například ajaxem).

Díky!

MW
Člen | 626
+
0
-

Zdravím,

pouzivam jquery.tooltip.js a pri pouziti:

$.nette.ext('tooltip', {
    load: function () {
	$(".tt").tooltip({
	    showURL: false,
	    track: true,
	    delay: 0
	});

    }
});

a naveseni pres class=„tt“ na odkaz, odkaz pak nefunguje. Zadna chyba, jen to neprejde. Netusite nekdo prosi, kde bych mohl hledat chybu?

Nebo jakou pouzivate podporu pro tooltip ?

EDIT: poznatek.. pokud nekliknu, ale drzim tlacito mysi na odkazu cca 2 vteřiny a pak pustim, na odkaz to prejde.. ale netusim s cim v tom tooltipu to muze byt v kolizi..

Diky

Editoval MW (3. 1. 2013 11:18)

bazo
Člen | 620
+
0
-

zdravim,

je mozne zavolat defaultnu succes funkciu pre snippety alebo rovno defaultnu success funkciu ktora by spracovala cely response z ineho ajax callbacku?

priklad:

pouzivam jRating pre hviezdickove hodnotenie, ktory ma vlastny event onSuccess, takze sa nespracuje response.

skusal som taketo varianty, ale vzdy dostanem error, ze success nie je funkcia

$('.star-rater').jRating({
           onSuccess: function(payload) {
                $.nette.ajax.success(payload)
                $.nette.ext('snippets').success(payload);
            }
 });

s jquery.nette.js doplnkom to ide jednoducho pomocou

jQuery.nette.success(payload);

Editoval bazo (3. 1. 2013 11:33)

nanuqcz
Člen | 822
+
0
-

Ahoj,
určitě dělám někde chybu, ale mě to rozšíření prostě nefunguje. U formulářů se neposílá hodnota tlačítka, kterým jsem formulář odeslal (takže Nette pak nespustí callback k formulářovému tlačítku přiřazený). Navíc se formulář odesílá při kliknutí na obyčejný <input type="text">, přestože třídu ajax jsem dával pouze submit buttonu.

Chyba nasimulovaná na sandboxu: http://ajaxtest.webshake.cz

Zdrojové kódy:

Celá aplikace v zipu: http://ajaxtest.webshake.cz/ajaxtest.zip

Kde může být chyba? Díky

miler
Člen | 75
+
0
-

Ahoj,
snažím se zprovoznit nějaké potvrzování akcí a na předchozí stránce se píše, že se to dá snadno řešit i pomocí nette.ajax.js.

V hlavičce layoutu mám:

<script type="text/javascript">
$(function () {
  $.nette.init();
});

$.nette.ext('data-ajax-confirm', {
  load: function () {
    $("a[data-ajax-confirm]").click(function (e) {
      if (!confirm($(this).data('ajax-confirm'))) {
        e.stopImmediatePropagation();
        return false;
      }
    });
  }
});
</script>

V šabloně pak:

<a class="ajax" n:href="delete! 5" data-ajax-confirm="Opravdu smazat?">Smazat</a>

Problém je v tom, že se to chová následovně:

  • kliknu na odkaz
  • provede se handle
  • zobrazí se dialog
  • kliknu na OK
  • dialog zmizí
  • kliknu na odkaz
  • zobrazí se dialog
  • kliknu na OK
  • provede se handle
  • kliknu znovu na OK
  • dialog zmizí

Okno vyskočí tolikrát, pokolikáté jsem kliknul na odkaz. Handle se provede před posledním dialogem.

V handleru je jen redirect na this (v případě že požadavek nebyl ajaxový).

Vidíte prosím někde problém? Děkuji.

Editoval miler (4. 1. 2013 23:03)

h4kuna
Backer | 740
+
0
-

miler napsal(a):
V handleru je jen redirect na this (v případě že požadavek nebyl ajaxový).

Vidíte prosím někde problém? Děkuji.

Dej sem presenter a v první chvíli bych řekl že ti v handle chybí:

<?php
if ($this->isAjax()) {
    $this->invalidateControl('snippet');
} else {
    $this->redirect('Presenter:action');
}
?>

Editoval h4kuna (5. 1. 2013 8:38)

h4kuna
Backer | 740
+
0
-

nanuqcz napsal(a):
Kde může být chyba? Díky

Ahoj tak jsem tomu chvilku dal a našel jsem. Oprav si extenzi init. Ještě pošlu pull Vojtovi.

$.nette.ext('init', {
	load: function (rh) {
		$(this.linkSelector).off('click.nette', rh).on('click.nette', rh);
		$(this.formSelector).off('submit.nette', rh).on('submit.nette', rh)
			.off('click.nette', ':image', rh).on('click.nette', ':image', rh)
			.off('click.nette', ':submit', rh).on('click.nette', ':submit', rh);
		$(this.buttonSelector).each(function () {
			$(this).off('click.nette')
				.on('click.nette', this, rh);
		});
	}
}, {
	linkSelector: 'a.ajax',
	formSelector: 'form.ajax',
	buttonSelector: 'input.ajax[type="submit"], input.ajax[type="image"]'
});

Editoval h4kuna (5. 1. 2013 11:39)

nanuqcz
Člen | 822
+
0
-

h4kuna: Díky, už jede :-) Akorát nějak nefunguje řádek $(this).off('click.nette', this, rh) (nepřišel jsem na to proč). Viz screenshot (zkoušel jsem FF a Chrome, problém je u obou).

Editoval nanuqcz (5. 1. 2013 10:34)

h4kuna
Backer | 740
+
0
-

Ten off uprav

.off('click.nette')

Upravil jsem i předchozí kód

Editoval h4kuna (5. 1. 2013 11:57)

nanuqcz
Člen | 822
+
0
-

h4kuna: Super, teď to funguje perfektně :-) Moc díky

h4kuna
Backer | 740
+
0
-

Není zač

miler
Člen | 75
+
0
-

h4kuna napsal(a):
Dej sem presenter a v první chvíli bych řekl že ti v handle chybí…

Původně jsem tam měl:

if (!$this->isAjax()) {
           $this->redirect('this');
}

Ale i když tu podmínku přepíšu podle tebe tak se to chová stejně (potvrzovací okno vyskočí, ale tolikrát po kolikáté jsem kliknul na ten odkaz, s tím že request na handle se odešle před zobrazením toho posledního).

<?php

namespace AdminModule;

class EditPresenter extends \BasePresenter {

    public function startup() {
        parent::startup();
    }

    public function renderDefault() {
        $this->template->data = $this->object->getAll();
    }

    public function handleDelete($param) {
        if ($this->isAjax()) {
            $this->invalidateControl('snippet');
        } else {
            $this->redirect('this');
        }
    }
}

Editoval miler (5. 1. 2013 14:18)

h4kuna
Backer | 740
+
0
-

miler napsal(a):
Ale i když tu podmínku přepíšu podle tebe tak se to chová stejně (potvrzovací okno vyskočí, ale tolikrát po kolikáté jsem kliknul na ten odkaz, s tím že request na handle se odešle před zobrazením toho posledního).

Chtěl jsem tím říct že ti chybí invalidace snippetu. Tvůj snippet se určitě nejmenuje snippet. Ten kód byla jen ukázka pro nakopnutí. Tak dej ještě šablonu

miler
Člen | 75
+
0
-

h4kuna: Diky, invalidaci jsem tam sice měl, ale měl jsem špatně udělaný snippet v šabloně (název jsem měl správně). Teď jsem to přepsal podle HosipLana a už se mi potvrzovací okna nenásobí.

Teď to mám tedy takto:

Šablona:

{snippet itemsList}
<table n:snippet="itemsContainer">
   <tr>
      <th>Položka</th>
      <th>Akce</th>
   </tr>

   {foreach $items as $id => $name}
   <tr n:snippet="item-$id">
      <td>{$name}</td>
      <td>
            <a class="ajax" n:href="delete! $id" data-ajax-confirm="Opravdu?">Delete</a>
      </td>
   </tr>
   {/foreach}
</table>
{/snippet}

Header:

<script type="text/javascript">
   $(function () {
      $.nette.init();
   });

   $.nette.ext('data-ajax-confirm', {
      load: function () {
         $("a[data-ajax-confirm]").click(function (e) {
            if (!confirm($(this).data('ajax-confirm'))) {
               e.stopImmediatePropagation();
               return false;
            }
         });
      }
   });
</script>

Presenter:

public function handleDelete($item) {
   // + volani do modelu
   if ($this->isAjax()) {
      $this->invalidateControl('itemsList');
   } else {
      $this->redirect('this');
   }
}

Handle se mi ale provede vždy i bez potvrzení akce, ve firebugu v odezvě je nový obsah snippetu itemsList, ale web se nepřekreslí. Díky za vaše nervy.

Editoval miler (6. 1. 2013 13:51)

duskohu
Člen | 778
+
0
-

ahoj, Vedel by si mi poradit ako by som vedel pri invalidovani konkretneho snippetu „mysnippet“ urobit extenzi kde by som vedel pouzit before a after?

$.nette.ext('snippets').before(function ($el) {

});
$.nette.ext('snippets').after(function ($el) {

});
bumprask
Člen | 59
+
0
-

Zdravím,
mám problém s nette.ajax.js v IE8. Mám nalinkované netteForm.js a po něm nette.ajax.js. Problém se týká ajaxizace odkazů a formulářů pomocí extenze a funkce $.nette.load() v nette.ajax.js. Ve firefoxu a chrome proběhne ajaxový požadavek bezproblémů, ovšem v IE8 jsou vráceny dvě odpovědi, nejdříve je vrácena odpověď s json obsahem, ovšem záhy je přestíněna odpovědí s hlavičkou text/html. Co může způsobovat v IE toto zrádné chování?

Editoval bumprask (8. 1. 2013 22:22)

kudlajz
Člen | 70
+
0
-

miler: Musíš tu část s $.nette.ext(…) volat ještě před $.nette.init();

Editoval kudlajz (9. 1. 2013 15:06)

enumag
Člen | 2118
+
0
-

kudlajz: Což volá. $.nette.init(); má obalené v $(function() {…}); takže vnitřek té fce se provede až později.

kudlajz
Člen | 70
+
0
-

Aha, tak to se omlouvám.

No já to jsem to zkoušel dát normálně do:

$(document).ready(function() {
	$.nette.ext('data-ajax-confirm', {
		load: function () {
			$("a[data-ajax-confirm]").click(function (e) {
				if (!confirm($(this).data('ajax-confirm'))) {
					e.stopImmediatePropagation();
					return false;
				}
			});
		}
	});

	$.nette.init();
});

A funguje mi to.