Výsledek JavaScript funkce do presenteru

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
premek_k
Člen | 172
+
0
-

Zdravím,
stále pátrám v dokumentaci a na fóru, ale nemohu najít řešení tohoto problému, resp. nakopnutí, jak to udělat:
V šabloně mám button
<button class="moje-poloha" onclick="javascript:mojeFunkce()">Moje poloha</button>

po stisknutí by se měla zavolat ona mojeFunkce(), v níž by se měla zjistit aktuální geolokace a ta odeslat do Presenteru ke zpracování.

Tu funkci bych už i nějak zbastlil, jen nevím, jakým způsobem z JS zavolat signál (???) presenteru a předat ty lokační data.

Teďka to mám řešené pomocí formu a hidden fields, ale to je na ostudu. Navíc mi ten form rozbíjí layout – ale to jsem vzhledem k předchozímu ani hlouběji neřešil.

Děkuji

castamir
Člen | 629
+
0
-
<script>
	var link = "{link tvuj-signal!}";
</script>

pak už to stačí odeslat pomocí ajaxu

Edit: zde máš další ukázkový kód, který bys mohl využít pro odeslání.

Editoval castamir (21. 1. 2013 16:40)

patriksima
Člen | 58
+
0
-

například

<script>
function mojeFunkce()
{
   $.post("{!$control->link('signal!')}",
       {
          "{!$control->name}-properties":$('.properties').length}
       },
       function(data){
          // data.neco
       }
   );
}
</script>
mkoubik
Člen | 728
+
0
-

Lepší než dynamicky generovat javascript je použíta data-atributy.

<button class="moje-poloha" data-geolocation-to="{link signal!}">Moje poloha</button>

A pak poslat AJAXový request:

$('button[data-geolocation-to]').click(function(){
	$.ajax({
		url: $(this).attr('data-geolocation-to')
		...
	}).done(function(){
		...
	});
});
premek_k
Člen | 172
+
0
-

Omlouvám se, ale stále jsem mimo. Pořád nemůžu přijít na to, kde zavolat tu mou JS funkci a jak předat ty data z této funkce do presenteru.

Šablona:

<button class="moje-poloha" data-geolocation-to="{link signal!}">Moje poloha</button>

Javascript:

$('button[data-geolocation-to]').click(function(){
    $.ajax({
        url: $(this).attr('data-geolocation-to')
        ...
    }).done(function(){
        ...
    });
});

function mojeFunkce(){
  var vysledek = 10;
  return vysledek;
}

Presenter:

public function handleSignal($vysledek){
  echo $vysledek;
}

Možná to takhle vůbec nefunguje a jsem úplně mimo. Je mi líto, že takhle obtěžuji…

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

Dobrý kód :). Data se předají do ajaxového požadavku takto:

$('button[data-geolocation-to]').click(function(){
	$.ajax({
		url: $(this).attr('data-geolocation-to')
		data: {
			vysledek: mojeFunkce()
		}
	}).done(function(){
		...
	});
});

Jen na okraj, lze použít i kratší:

url: $(this).data('geolocationTo')
uestla
Backer | 799
+
0
-

<OT> Raději mějme $el.attr('data-xyz') nežli $el.data('xyz'), kteréžto magicky přetypovává… </OT>

premek_k
Člen | 172
+
0
-

Paráda, děkuji pánové. Uložím rodinu do postelí a jdu na to.

premek_k
Člen | 172
+
0
-

Ha, po trochu delším zkoušení, jak na to, jsem se dobral zdárného skoro konce. Měl jsem ještě trochu problém s tím, že zjištění geolokace běží asynchronně, tudíž zpracování signálu začalo dřív, než mi to api vrátilo data. Výsledný funkční kód je směsí vašich rad:

Latte:

    <script type="text/javascript">
    var ajaxLink = {plink signal!};
    </script>
:
:
    <button class="moje-poloha" id="xbut" onclick="getPosition();">Moje poloha</button>

JavaScript:

function getPosition(){
    if (navigator.geolocation) {
      var timeoutVal = 10 * 1000;
      navigator.geolocation.getCurrentPosition(
        storePosition,
        displayError,
        { enableHighAccuracy: true, timeout: timeoutVal, maximumAge: 0 }
      );
    }
    else {
      alert("Geolocation is not supported by this browser");
    }
}

function displayError(error) {
  var errors = {
    1: 'Permission denied',
    2: 'Position unavailable',
    3: 'Request timeout'
  };
  alert("Error: " + errors[error.code]);
}

function storePosition(position) {
$.ajax({
        url: ajaxLink,
        data: {
            gps: new Array(position.coords.latitude, position.coords.longitude)
        }
    }).done(function(){
    });
}

Presenter:

public function handleSignal(array $gps) {
    $this->storeGpsLocation($gps[0],$gps[1]);
    $this->redirect('Homepage:default');
}// end function

Poslední problém mám s tím $this->redirect(‚Homepage:default‘); v presenteru, který se (asi protože $this->isAjax() ) neprovede. Zřejmě to není standardní zpracování Ajax požadavku, ale já to tam po uložení GPS lokace potřebuju přesměrovat (v beforeRender tam spouštím celou logiku aplikace). Je tam nějaká možnost to přesměrovat? Nebo nějaké jiné řešení?

Děkuji velice.

Tabetha
Člen | 140
+
0
-

skúsiť to dať do toho … nenapadá ma jQuery ekvivalent
bud tam alebo do poslednej časti skriptu (ten ktorý posledný končí)

var homepageLink = {plink Homepage:default}
function storePosition(position) {
$.ajax({
        url: ajaxLink,
        data: {
            gps: new Array(position.coords.latitude, position.coords.longitude)
        }
    }).done(function(){
	window.location.href = homepageLink ;
    });
}

Editoval Tabetha (22. 1. 2013 20:41)

premek_k
Člen | 172
+
0
-

díky Tabetha, zrovna jsem chtěl tu část mého dotazu odmáznout, páč mě napadlo to stejné. Udělám to zřejmě takto.

patriksima
Člen | 58
+
0
-

premek_k napsal(a):

díky Tabetha, zrovna jsem chtěl tu část mého dotazu odmáznout, páč mě napadlo to stejné. Udělám to zřejmě takto.

doporučuji použít mnou uvedený $.post místo $.ajax, protože druhý má složitější zápis, ale hlavně má default GET, což ti bude způsobovat zbytečné trable, na které se velmi blbě přichází (strávil jsem nad takovýma chybama hodiny)

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

Dovolím si poznamenat, že doplněk nette.ajax.js má podporu pro Nettí redirect automaticky zapnutou :). Použití:

  1. přilinkovat po jQuery skript nette.ajax.js
  2. zavolat $(function () { $.nette.init(); });
  3. $.ajax() nahradit za $.nette.ajax() (pokud je potřeba POST, tak klasicky $.nette.ajax({ type: 'post'});)
premek_k
Člen | 172
+
0
-

Z důvodu implementace ajaxem plněných dvou závislých selektboxů jsem přilinkoval do projektu jquery.nette.js. Následně mi pak přestalo chodit to $.ajax odesílání.

Snažil jsem se to tedy předělat dle #vojtech.dobes, ale neumím vyřešit odchytnutí události po vykonání, tzn. tu původní sekci .done:

<script>
 $.nette.ajax({
            url: ajaxLink,
            data: {
                gps: new Array(l_latitude, l_longitude, l_accuracy, dbgPosition)
            }
        }).done(function(){alert('done');});
</script>

…kterou nutně potřebuji, protože tam řeším ještě nějakou logiku a následně i případné přesměrování. Právě s tím přesměrováním je problém, páč (zřejmě) proběhne současně s tím ajaxím požadavkem a kód ajaxího volání v presenteru se nevykoná.

Můžete mi někdo poradit? JS moc nerozumím. Děkuji

Editoval premek_k (26. 2. 2013 15:18)

premek_k
Člen | 172
+
0
-

Omlouvám se. Facku už jsem si dal…

<script>
 $.nette.ext('name', {
            complete: function () {
                 if(redirect){
                    window.location.href = homepageLink;
                 }//endif
                 $('#please-wait').hide();
            }
        });

        var x = $.nette.ajax({
            url: ajaxLink,
            data: {
                gps: new Array(l_latitude, l_longitude, l_accuracy, dbgPosition)
            }
        });
</script>
Vojtěch Dobeš
Gold Partner | 1316
+
0
-

Tzn. vyřešeno nebo nějaký problém stále přetrvává :) ?