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

flexroad
Člen | 117
+
0
-

Pratele,

potreboval bych pred samotnym volanim ajaxu spustit nejake funkce a pockat na jejich provedeni.
Tusite prosim nekdo jak na to? V nasledujicim pripade po uspesnem „complete“ uvedene velocity animace.

(function($, undefined) {
    $.nette.ext('modules', {
	    before: function () {
		$('.left-panel').velocity({
		    left: -200
		}, {
		    duration: 1500,
		    complete: function(elements) {
				//AZ TADY BYCH POTREBOVAL VOLAT SAMOTNY REQUEST
		    }
		});
	    },
	    start: function () {
		    console.log('start');
	    },
	    complete: function () {
		    console.log('complete');
	    }
    });
})(jQuery);

Diky za cokoliv,

@flexroad

akadlec
Člen | 1326
+
0
-

Tady bych to asi řešil tak že se prvně zavolá nějaká funkce co ti provede tu animaci a až tam pak zavoláš nette.ajax()

MartinitCZ
Člen | 580
+
0
-

Zkoušel jste někdo stímto doplnkem uploadovat soubory?
Mám jednoduchá formulář s jedním inputem a buttonem.
Do inputu vložim soubor a odešlu tlačítkem.

Pokud je zapnutý ajax, tak se na server odešle prázdné pole „file“.
Pokud ajax vypnu, tak upload funguje.

Hidden inputy se v obou případech odešlou správně.

Nenapadá vás řešení?

matopeto
Člen | 395
+
0
-

Niekedy som to riesil: https://forum.nette.org/…pomoci-ajaxu#… (vysledok je tu: https://github.com/…ette.ajax.js) akurat neviem ako je to aktualne, pretoze stale mam fork starej verzie. Kazdopadne pozeram do novych komitov a tam je podobna uprava uz integrovana: https://github.com/…26fb62322770 mozno len este nie je popisana.

MartinitCZ
Člen | 580
+
0
-

@matopeto Díky. Použít master verzi nette.ajax a pluginu co zminuje @akadlec byl dobrý tip. Okamžitě to funguje. :)

Editoval MartinitCZ (27. 10. 2014 14:24)

akadlec
Člen | 1326
+
0
-

tak když už to přidali do master verze je supr, aspoň budu moci zase klasicky updatovat ;)

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

Děkuji všem za trpělivost. Dnes jsem vydal novou stable verzi 2.0.0 (totožná s aktuálním masterem), tak nechť dobře slouží :). Posun v major verzi je proto, že History extenze byla vyčleněna do samostatného repozitáře.

mpis
Člen | 65
+
0
-

Díky za novou verzi.
Díval jsem se dovnitř souboru nette.ajax.js a je tam uvedena verze * @version 1.2.2.

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

mpis napsal(a):

Díky za novou verzi.
Díval jsem se dovnitř souboru nette.ajax.js a je tam uvedena verze * @version 1.2.2.

Díky, fixed.

fronty
Člen | 16
+
0
-

Ahoj,

díky za super skript. S Nette pracuji teprve týden a z toho jsem 2 dny řešil problém s nefunkčním nette.ajax.js, kdy se i přes třídu .ajax u odkazu stránka přenačetla na adresu signálu. Celý problém byl v zapnutém $absoluteUrls v BasePresenteru.
Nikde se mi to nepodařilo najít, doporučuji to pro začátečníky jako jsem já doplnit do readme.

Teyras
Člen | 81
+
0
-

Zdar,

vynikající práce, star na githubu jsem ti nedal jen abych nezkazil těch 99 :) Nicméně, nedaří se mi vyřešit jednu věc – řekněme, že mi někdo (jquery.fileupload třeba) nadělí jqXHR, a já bych si na něj rád navěsil handlery z nette.ajax. Teď to řeším tak, že si prostě sám zavolám updateSnippets, ale to není ono. Zkoušel jsem to prostě předhodit $.nette.handleXHR, ale nezabralo to. Dělám to špatně?

Andre
Člen | 24
+
0
-

Snažím se za použijí nette.ajax a live validation doplňku udělat takový formulář, kdy na základě zadání textu do jednoho prvku formuláře se pak doplní obsah dalších prvků. Jakmile se však načtou hodnoty do dalších prvků, ve formuláři přestane fungovat validace. Ten stejný problém mám pak pokud používám Kdyby/replicator a snažím se pomocí ajaxu ubírat formulářové prvky. Jakmile se ubere prvek, přestane fungovat validace.

Co by se s tím dalo udělat?

Latte

{snippet newOrderFormSnippet}
	{form newOrderForm}
		{$form}
	{/form}
{/snippet}

<script type="text/javascript">
{include #jsCallback, input => ic, link => icChange}
</script>

{define #jsCallback}
$('#{$control["newOrderForm"][$input]->htmlId}').on('change', function() {
    $.nette.ajax({
        type: 'GET',
        url: '{link {$link}!}',
        data: {
            'value': $(this).val(),
        }
    });
});
{/define}

Presenter

	public function renderDefault() {
		$this->template->_form = $this['newOrderForm'];
	}

	public function handleIcChange($value) {
		if ($this->isAjax() and $value) {

				$this['newOrderForm']['ic']->setValue($value);
				$this['newOrderForm']['dic']->setValue($value);

			$this->invalidateControl('newOrderFormSnippet');
		}
	}

	public function createComponentNewOrderForm() {

		$form = new Form;

		$form->addText('ic', 'IČ')->setRequired('Zadejte prosím IČ.');
		$form->addText('dic', 'DIČ')->setRequired('Zadejte prosím DIČ.');
		$form->addSubmit('submit', 'Objednat');

		$form->onValidate[] = $this->NewOrderFormValidated;
		$form->onSuccess[] = $this->NewOrderFormSucceeded;

		$removeEvent = callback($this, 'NewOrderFormRemoveItemClicked');

		$users = $form->addDynamic('users', function (Container $user) use ($removeEvent) {
			$user->addText('service', 'Služba');
			$user->addSubmit('remove', 'odebrat')
							->setValidationScope(FALSE) # disables validation
					->onClick[] = $removeEvent;
		}, 1);

		return $form;
	}

	public function NewOrderFormRemoveItemClicked(Nette\Forms\Controls\SubmitButton $button) {

		$users = $button->parent->parent;
		$users->remove($button->parent, TRUE);

		if ($this->isAjax()) {
			$this->invalidateControl('newOrderFormSnippet');
		}
	}

Editoval Andre (26. 11. 2014 23:41)

Mares
Člen | 3
+
0
-

Ahojte, pokouším se tímto rozšířením informovat uživatele o probíhající akci na pozadí.

V presenteru mám v handle metodě něco jako

$this->payload->notify = (object) array(
	'show' => true,
	'before' => 'Lorem Ipsum',
	'complete' => 'Ipsum Lorem'
);

a v JS mi v success přijde také object notify, jak se k němu ale dostanu v metodě before?

<script type="text/javascript">
$.nette.ext('notify', {
    before: function (settings, ui, e) {
        ** Dostanu se zde k notify.before? **
    },
    complete: function (payload) {
        console.log(payload.notify.complete);
    }
});
</script>

Snažím se docílit toho, abych na určitém místě informoval o probíhající akci (spinner + text) a následné potvrzení uložení, etc..

Editoval Mares (28. 11. 2014 12:57)

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

nette.ajax.js pouze zapouzdřuje klasické $.ajax(). Událost before se volá ještě před tím, než ajaxový požadavek začne, takže tam se k payloadu určitě dostat nená. Na nějaké průběžné informace z probíhajícího ajaxového požadavku by myslím mělo sloužit toto, ale nikdy jsem to nepoužil a neimplementoval, takže s tím nemám žádnou zkušenost.

Zax
Člen | 370
+
+2
-

Díky za verzi 2.0.0, naprostá pecka že už můžeme uploadovat pomocí ajaxu! Dá se nějak vytáhnout info o uploadovaných souborech? Zkoušel jsem toto:

<script>
$.nette.ext('uploadProgress', {
	start: function(jqXHR, settings) {
		alert('start');
		jqXHR.onprogress = function(e) {
			alert('xhr progress');
		};
		if(jqXHR.upload) {
			jqXHR.upload.onprogress = function (e) {
				alert('xhr.upload progress');
			};
		}
	}
});
</script>

při odeslání formuláře se soubory vyskočí pouze alert(‚start‘), nevím, jak správně navěsit onprogress event, abych si mohl vyzobnout potřebné informace :-/. Bohužel má úroveň JS je na úrovni pokus-omyl, takže budu rád za jakékoliv nakopnutí.


EDIT o dva dny později: Chachá! Konečně jsem na to přišel:

<script>
$.nette.ext('uploadProgress', {
	init: function() {
		$.ajaxSettings.xhr = function() {
			var xhr = new window.XMLHttpRequest;
			xhr.upload.addEventListener('progress', function(e) {
				console.log(e.loaded / e.total * 100);
			}, false);
			return xhr;
		};
	}
});
</script>

Editoval Zax (6. 12. 2014 7:11)

flexroad
Člen | 117
+
+1
-

Ahoj,

resim re-bindovani. Musim vzdy po nacteni snippetu znovu bindovat vsechny elementy v nem obsazene?

Mam napriklad nasledujici funkci:

<script>
	$(".lightboxClose").on("click", function(e) {
          $("#lightboxCover").addClass('hide');
    });
</script>

Toto funguje, pokud stranku poprve nactu. Pokud ale samotny element s tridou „.lightboxClose“ nactu ve snippetu, akce onClick uz nefunguje :(

Vim, ze muzu pridat extenzi a tam potom volat neco jako:

<script>
$.nette.ext('rebind', {
	complete: function () {
		$(".lightboxClose").on("click", function(e) {
          	$("#lightboxCover").addClass('hide');
    	});
	}
});
</script>

Cetl jsem ale nekde neco o tom, ze by si to mel nette.ajax resit sam, jen nevim, jak na to :(

Diky za cokoliv,

@flexroad

jiri.pudil
Nette Blogger | 1029
+
0
-

nette.ajax.js si řeší jen nabindování vlastních listenerů, tzn. třeba když máš ve snippetu odkaz .ajax, bude fungovat ajaxově i po překreslení snippetu. Cokoliv jiného si už musíš zařídit sám buďto nějakým takovýmhle rozšířením, nebo navěšením listeneru na nějaký nadřazený prvek:

$(document).on('click', '.lightboxClose', function (e) { ... });
flexroad
Člen | 117
+
0
-

jiri.pudil napsal(a):

nette.ajax.js si řeší jen nabindování vlastních listenerů, tzn. třeba když máš ve snippetu odkaz .ajax, bude fungovat ajaxově i po překreslení snippetu. Cokoliv jiného si už musíš zařídit sám buďto nějakým takovýmhle rozšířením, nebo navěšením listeneru na nějaký nadřazený prvek:

$(document).on('click', '.lightboxClose', function (e) { ... });

to @jiri.pudil,

myslel jsem si ze to nejak tak bude. Nakonec jsem si pro to napsal rozsireni ktere po complete vola funkci na rebind.

Kazdopadne moc dekuji za reakci!

@flexroad

akadlec
Člen | 1326
+
+1
-

sice sem do js až tak moc nedělal, ale není bindovaní nad samotným celým dokumentem neefektivní? Není lepší to vztáhnout k nějakému konkrétnímu elementu?

David Matějka
Moderator | 6445
+
0
-

@akadlec pak by prave po prekresleni nefungoval ten listener…

bazo
Člen | 620
+
0
-

no ale nemusi to byt priamo na document, staci na parent element, ktory sa ajaxom nemeni

akadlec
Člen | 1326
+
0
-

@matej21 no nefungoval…samo záleží kde jej navěsíš. Ale jak jsem psal, ruku do ohně za to nedám, ale pokud takto navěsíš X listenerů na document, tak to docela žere paměť ale pokud se pletu tak mě opravte, já to řešil kdysi dávno kdy mě JS zabíjel appku ;)

flexroad
Člen | 117
+
0
-

Ja tam ten listener navesim jen pokud uz tam neni. Treba takhle:

<script>
$.fn.once = function(a, b) {
    return this.each(function() {
        $(this).off(a).on(a,b);
    });
};

function rebindAllObjects(){ //tuto funci volam po kazdem ajaxovem success volani
    $($('.lightboxClose')).once('click', function(){
        $("#lightboxCover").addClass('hide');
    });
    $($('#signup-nickname')).once('keyup', checkNickname);
}

</script>
ParallelUniv3rse
Člen | 13
+
0
-

Zdravím,

Dělám na webu kde bych rád měl modal ve kterém se bude načítat content pomocí ajaxu.
Modal mám ve snippetu, který bych rád po kliknutí na tlačítko updatoval novými hodnotami, které by mi předal presenter z databáze. A nakonec success zavolat $(„.modal“).modal(‚show‘); (stavím na bootstrapu).

Přečetl jsem už mraky topiců zde na fóru i dokumentaci ale stále nemůžu ani za nic přijít na to jak na to.
Ukázal by mi někdo cestu?
Díky za pomoc :)

Handle:

public function handleModalRequest($id) {
        if ($this->isAjax()) {
            $this->template->workModalContent = $this->database->table('procedures')->where('id', $id);
            $this->redrawControl('workModal');
        }
    }

Snippet modalu:

{snippet workModal}
        <div class="modal fade" role="dialog" id="workModal" aria-labelledby="workModalLabel" aria-hidden="true">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;<span class="sr-only">Close</span></button>
                        <h3 class="modal-title">
                            <span id="workModalLabel">{$workModalContent->label}</span>
                        </h3>
                    </div>
                    <div class="modal-body">
                        {$workModalContent->text}
                    </div>
                    <div class="modal-footer">
                        <a href="#" data-dismiss="modal" class="btn btn-danger">close</a>
                    </div>
                </div>
            </div>
        </div>
{/snippet}

Editoval ParallelUniv3rse (4. 1. 2015 16:58)

akadlec
Člen | 1326
+
0
-

a s čím máš tedy problém?

ParallelUniv3rse
Člen | 13
+
0
-

akadlec napsal(a):

a s čím máš tedy problém?

S použitím celé knihovny.

  • Je nutné před použitím $.nette.ext(… zavolat i $.nette.init(); ?
  • Jak mám upravit defaultní extension co updatuje snippety tak, aby otevřel modal? Nebo si musím vytvořit vlastní a tím napsat znovu i celý updating snippetu?

(Pokud jsem vůbec správně z dokumentace pochopil jak snippety fungují.. )

  • Když bych měl na jedné stránce více elementů s ajaxem, jak přidělím danému elementu správnou extension?
  • Rád bych rozuměl i tomu co a jak se dá vrátit z presenteru funkci (v dokumentaci je pouze o JSONu a definice „poslat klientovi ve formátu, kterému bude obslužný JavaScript rozumět.“ mi toho také moc v dokumentaci nesdělí.. Arrrgh).

Editoval ParallelUniv3rse (4. 1. 2015 18:22)

akadlec
Člen | 1326
+
0
-
  1. nette.init() se vola na konci nastavování, vytváření extension atd…prostě když už máš vše připraveno tak to initneš
  2. tak můžeš si napsat vlastní extension co bude dělat to otvírání modalu
  3. nijak, leda by sis v success metodě dělal nějak kontrolu na IDčko, každopádně pokud tě chápu dobře tak ext. chápeš špatně.
  4. a co ti na tom není jasné? z presenteru si vrátíš prakticky cokoliv co si dáš do payloadu – to ti pak pošle samotné nette a nebo si to uděláš po svém a presenter ukončíš sám
Vojtěch Dobeš
Gold Partner | 1316
+
0
-
$.nette.ext('modals', {
	init: function () {
		this.ext('snippets', true).before($.proxy(function ($el) { // $el je element snippetu
			if (this.shouldTry && $el.children('.modal').length === 1) {
				$el.find('.modal').modal('show');
				this.shouldTry = false;
			}
		}, this));
	},
	success: function (payload) {
		this.shouldTry = true;
	}
}, {
	shouldTry: true
});
ParallelUniv3rse
Člen | 13
+
0
-

Díky moc! :)
Teď už tomu rozumím víc a nějak si s tím poradím.

Teyras
Člen | 81
+
0
-

Zdar, snažím se v navázat událost na submit formuláře tak, aby se tam upravila jedna hodnota a pak se to ajaxově odeslalo. Ten první callback napojuju přes jquery (jako první), ale provede se jen ten nette ajax submit, tušíte, co dělám špatně?
Zdá se, že se tam používá Nette.addEvent, a to nevidí ten jquery handler – console.log(original) vypíše null

Siam
Člen | 54
+
0
-

Ahoj, pokouším se přijít na to, jak volat handle metodu z externího scriptu. Původní funkční html řádek byl

<a n:href="showReplyForm! $comment->id" class="ajax">Odpovědět</a>

a já ho přepsal na:

<a href="#" class="ajax myAjax" data-comment-reply-url="{link showReplyForm! $comment->id}">Odpovědět</a>

Bohužel script, který má volat tu handle metodu mi nefunguje. Script jem zapsal takto:

$.nette.ext({
    load: function () {
        $('a.myAjax').click(function(e){
            e.preventDefault();
        		var commentReplyUrl = $(this).data('comment-reply-url');
            $.nette.ajax({
                url: commentReplyUrl
            });
        });
    }
});

Poradí mi prosím vás někdo kde jsem udělal v tom scriptu chybu?

akadlec
Člen | 1326
+
0
-

Co tohle:

$(this).data('commentReplyUrl');

resp co ten skript teď dělá?

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

Siam napsal(a):

Poradí mi prosím vás někdo kde jsem udělal v tom scriptu chybu?

Vzhledem k tomu, že vlastně už nepoužíváš defaultní ajaxifikaci, ale zařizuješ si ji po svém (myAjax), tak bych z toho odkazu komplet odstranil CSS třídu ajax.

akadlec napsal(a):

Co tohle:

$(this).data('commentReplyUrl');

resp co ten skript teď dělá?

Varianta s pomlčkami by měla být v pořádku.

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

Taky můžeš udělat následující:

$.nette.ext({
    load: function () {
        $('a.myAjax').click(function (e) {
            $(this).netteAjax(e, {
                url: $(this).data('comment-reply-url')
            });
        });
    }
});

Editoval vojtech.dobes (17. 1. 2015 12:51)

Siam
Člen | 54
+
0
-

Díky za odpovědi. Snažím se docílit toho, aby se mi u každého komentáře zobrazil po kliknutí na odkaz odpovědět formulář pro přidání odpovědi pro ten konkrétní komentář. Nechci k tomu volání handle metody ovšem použít standardní odkaz n:href, ale
volat jí ze scriptu. Jednoduše, potřebuji poslat unikátní formulář a ten vykreslit.

Uvědomuji si, že ten způsob asi není zrovna ideální, protože při nejmenším zbytečně generuje prázdné snipped divy a invaliduje všecny komentáře. To se pokusím změnit až budu schopný volat tu handle metodu ve svém js. Jsem bohužel noob.

V šabloně komponenty mám tento kód:

{snippet comments}
  {foreach $comments as $comment}
    <div>Obsah komentáře...</div>

    <a href="#" class="myAjax" data-comment-reply-url="{link showReplyForm! $comment->id}">Odpovědět</a>

      {snippet commentsReplyForm-$comment->id}
        {if isset ($showReplyFormId) && $showReplyFormId == $comment->id}
          {control formAddComment-$comment->id}
        {/if}
      {/snippet}

  {/foreach}
{/snippet}

V obsluze té komponenty pak tento kód:

<?php
    public function handleShowReplyForm($id)
    {
        $this->template->showReplyFormId = $id;
        $this->redrawControl('comments');

    }

  public function createComponentFormAddComment()
  {
        return new Multiplier(function ($commentId) {
            $form = new Form;
            // zbytek kódu pro formulář
          return $form;
        });
  }
?>

Edit: v konzoli mi to píše „TypeError: settings.nette is undefined“

Editoval Siam (17. 1. 2015 16:59)

Jan Mikeš
Člen | 771
+
0
-

Ahoj, upravil jsem si metodu applySnippet tak, abych mel krasny super cool efekt pomoci transitions:

	applySnippet: function ($el, html, back) {
		if (!back && $el.is('[data-ajax-append]')) {
			$el.append(html);
		} else if (!back && $el.is('[data-ajax-prepend]')) {
			$el.prepend(html);
		} else {
			if ($el.attr("id") == "snippet--content") {
				$el.addClass("transition");
				window.setTimeout(function() {
					$el.html(html).removeClass("transition");
				}, 1000);
			} else {
				$el.html(html);
			}
		}
	}

Vse je ok, prekreslovani funguje paradne, ALE… provadi se jeden XHR pozadavek vzdy, i pri refreshi (i bez ajaxoveho pozadavku, proste kdyz zadam localhost/xxx, tak hned po nacteni stranky se provede request).

Nevim jestli se to tu uz nahodou neresilo, ale nenasel jsem, diky.

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

Lexi napsal(a):

Vse je ok, prekreslovani funguje paradne, ALE… provadi se jeden XHR pozadavek vzdy, i pri refreshi (i bez ajaxoveho pozadavku, proste kdyz zadam localhost/xxx, tak hned po nacteni stranky se provede request).

Nemyslím, že by to mohlo souviset s úpravou metody applySnippet.

Určitě bych doporučil nepřepisovat nette.ajax.js. Rozšíření jsou schválně navržená tak, aby se jejich části daly neinvazivně předefinovat. Tj.:

$.nette.ext('snippets').applySnippet = ... // your version
Jan Mikeš
Člen | 771
+
0
-

@vojtech.dobes diky za inspiraci, to vypada mnohem lepe.

Kazdopadne pri vypnuti history extension se tento podivny XHR pozadavek na sebe samu neprovadi. Zkusim zjistit vice.

edit: tak jsem prisel na to, ze to dela pouze v Safari :)

Editoval Lexi (21. 1. 2015 20:03)

Jan Mikeš
Člen | 771
+
0
-

Pri postupnem odmazavanim kodu a logovanim jsem dosel k tomu, ze to dela v history extension v init metode tento kus kodu:

	// radky 63-68
	history.replaceState(this.initialState = {
		nette: true,
		href: window.location.href,
		title: document.title,
		ui: this.cache ? findSnippets() : null
	}, document.title, window.location.href);

Pokud tento kousek smazu, snippety se neprekresluji i pri neajaxovem pozadavku pri refreshi a vse ostatni funguje normalne bez znamky nejake chyby – i historie prohlizece pri ajaxu a vse ostatni.

Nejake napady?

Edit: tak jsem udelal poradek v kodu, prepsal jsem to dle doporuceni od @vojtech.dobes dale jsem pouzil extensions namisto hackovani jiz existujicich metod a problem se vyresil :) treba vysledek nekomu pomuze:

<script>
	$.nette.ext('snippetTransition', {
		before: function (jqXHR, settings) {
			this.transitionElements.addClass(this.transitionClass);
		},
		complete: function(jqXHR, status, settings) {
			var that = this;
			window.setTimeout(function() {
				that.transitionElements.removeClass(that.transitionClass);
			}, that.duration)
		}
	}, {
		duration: 1000,
		transitionElements: $("[data-transition]"),
		transitionClass: "transition"
	});

	var originalApplySnippet = $.nette.ext("snippets").applySnippet;

	$.nette.ext("snippets").applySnippet = function ($el, html, back) {
		if ($el.is("[data-transition]")) {
			var contentTransition = this.ext('snippetTransition', true);
			window.setTimeout(function() {
				$el.html(html);
			}, contentTransition.duration);
		} else {
			originalApplySnippet($el, html, back);
		}
	};
</script>

Omlouvam se tedy za plany poplach

Editoval Lexi (22. 1. 2015 14:15)

iguana007
Člen | 970
+
0
-

Ahoj,
řešil jsem včera několik hodin zajímavý problém, ale bohužel se mi jej nepodařilo vyřešit, proto to zkusím tady. Pokusím se tedy problém co nejvíce popsat:

  • mám úplně jednoduchou mini aplikaci v Nette 2.2.7, která se mi načítá uvnitř Windows gadgetu na ploše
  • jelikož se jedná o korporátní laptop s centralizovanou správou software, tak nejsem schopen ovlivnit verzi IE, která obstárává render gadgetu – v tomto případě se jedná o verzi IE 8.0.7601.17514
  • gadget mi vykresluje pouze několik odkazů (v podstatě jde jen o switche se stavy on/off), které volají ajaxově handle. Klasický odkaz se mi nepodařilo rozchodit, protože jej gadget otevírá v okně prohlížeče namísto uvnitř gadgetu, proto to musí být ajaxově
  • všechny tyto ajaxové odkazy jsou uvnitř snippetu, který se invaliduje po každém kliku na jeden z odkazů
  • Problém: když kliknu na jakýkoli odkaz, tak se zcela bez problémů ajaxový požadavek vykoná, ale jakýkoli další klik se již vykonává bez ajaxu a tím pádem mi to otevře daný link v browseru
  • zkoušel jsem aplikaci i přímo v prohlížeči (výše zmíněné IE8) a tam se to chová stejně
  • browser nehlásí žádné JS chyby
  • v prohlížečích jako Chrome, FF apod. to funguje jak má a každý z kliků se provede ajaxem
  • jelikož se jedná o úplně jednoduchou aplikaci, tak načítám pouze následující JS: jQuery 1.11.2, nette.ajax.js, spinner.ajax.js a následně volám $.nette.init(); – co se týče verzí, tak jsem vše stáhnul včera z gitu apod.
  • prolézal jsem zdejší fórum a pokusil se uvnitř snippetu znovu navázat ajax na invalidované linky, ale taky nepomohlo, viz.:
<script>
	$(function(){
		$('#switchesBlock').on('click', '.ajax', function(e){
			e.preventDefault();
			//alert('foo'); - toto se zavolá, jakmile se snippet invaliduje a normálně to vyhodí alert
			$.nette.ajax(this.href, this, e);
		});
	});
</script>

Neví někdo prosím, co s tím?
Děkuji za jakoukoli radu/tip ;)

iguana007
Člen | 970
+
0
-

Ještě bych rád doplnil, že jsem zkoušel uvnitř snippetu po invalidaci zavolat také toto:

<script>
	$(function(){
		$.nette.load()
	});
</script>

… a nepomohlo :(
viz.: https://github.com/…s/issues/105

akadlec
Člen | 1326
+
0
-

a jak vypadá odpověď po tom prvním requestu? nenačte se ti celá stránka?

Jan Mikeš
Člen | 771
+
0
-

@iguana007 mel jsem stejny problem vyresil jsem to upravou INIT extension primo v nette.ajax.js (link handler) na:

<script>
$("body").off('click.nette', this.linkSelector, rh).on('click.nette', this.linkSelector, rh);
</script>

Toto mi pomohlo, zkus to a uvidis :)

iguana007
Člen | 970
+
0
-

díky za reakce, nechal jsem to v práci, takže to nemám jak vyzkoušet, ale hned ráno se na to podívám a dám vědět oběma @akadlec @Lexi

iguana007
Člen | 970
+
0
-

@akadlec – po prvním kliku se mi vrací normálně JSON se snippetem, takže tím to nejspíš nebude
@Lexi – prosím o upřesnění co s tím mám udělat? Nechápu tu část ohledně „upravou INIT extension primo v nette.ajax.js“ – co tam mám upravit? Díky
Edit: @Lexi – tak toto také můj problém nevyřešilo, druhý klik už je neajaxový :(

Editoval iguana007 (12. 2. 2015 10:10)

akadlec
Člen | 1326
+
0
-

A přepisuješ jen části dokumentu nebo celý? Máš tam třídu pro navázání ajaxu?

iguana007
Člen | 970
+
0
-

@akadlec ta šablona vypadá takto:

{block content}
{snippet switches}
	<div id="switchesBlock">
	{foreach $switches as  $s}
		<p class="row">
		{if $s->type=="switch"}
			<span>{$s->name}:&nbsp;</span>
			{if $s->value=='on'}
				{var $newState = 'off'}
			{else}
				{var $newState = 'on'}
			{/if}
			<a n:href="updateSwitch! switchId => $s->id, newState => $newState" class="ajax switch">
				<img src="{$basePath}/images/{$s->value}.png">
			</a>
			<br>
		{else}
			<span>{$s->name}:&nbsp;</span><strong>{$s->value}</strong><br>
		{/if}
		</p>
	{/foreach}
	<span id="lastUpdate">Last update at: {=date('Y/m/d H:i:s')}</span>
	</div>
	{ifset $isAjax}
	<script>
		$(function(){
			$.nette.load();
			$('#switchesBlock').on('click', '.ajax', function(e){
				(event.preventDefault) ? event.preventDefault() : event.returnValue = false;
				$.nette.ajax(this.href, this, e);
			});
		});
	</script>
	{/ifset}
{/snippet}
{/block}
iguana007
Člen | 970
+
0
-

Tam bude evidentně jen nějaký problém s navázáním click handle v IE po invalidaci snippetu, protože jak jsem již psal výše, tak v Chrome a FF to šlape jak švýcary, jen v tom IE8 funguje ajax pouze před ivalidací snippetu, jakmiule se invaliduje, tak všechny odkazy s třídou ajax uvnitř snippetu již nejsou ajaxové + ten kousek JS co mám na konci snippetu to nevyřeší, i když by imho měl…

akadlec
Člen | 1326
+
0
-

pokud překresluješ celý snippet „switches“ tak máš imho i blbě napsané to JS dole. Zbytečně zavěšuješ ty akce pomocí on, když ten element celý přepíšeš. Volání nette.ajax taky není na správném místě. A další věc co můžeš zkusit je kouknout se do konzole IE zda tam není nějaká chyba

iguana007
Člen | 970
+
0
-

@akadlec Předpokládám, že ohledně špatného umístění volání nette.ajax si myslel $.nette.init();, které volám na konci body v @layout.latte:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
	<meta charset="utf-8">
	<title>Some Title</title>
	<link rel="stylesheet" media="screen,projection,tv" href="{$basePath}/css/screen.css?{=time()}">
	<link rel="shortcut icon" href="{$basePath}/favicon.ico">
</head>
<body>
	<div id="header">
		<a href="#" onclick="window.location.reload(true);return false;">
			<img src="{$basePath}/images/logo.png" alt="Logo">
		</a>
	</div>
	<div n:foreach="$flashes as $flash" class="flash {$flash->type}">{$flash->message}</div>
	{include content}
	<script src="{$basePath}/js/jquery.js"></script>
	<script src="{$basePath}/js/nette.ajax.js"></script>
	<script src="{$basePath}/js/spinner.ajax.js"></script>
	<script>
		$(function(){
			$.nette.init();
		});
	</script>
</body>
</html>

psal si, že mám „blbě to js dole“ – a jak by tedy podle tebe mělo být správně? To že mám něco blbě vím, ale nevím co :)
Díky

Editoval iguana007 (12. 2. 2015 12:04)