2012-05-02 7 views
8

Ho un'applicazione che tenta di ottenere le impostazioni delle posizioni dal browser, questo tende a richiedere un po 'di tempo quindi voglio che venga eseguito quando la pagina viene caricata. Tuttavia, se si fa clic sul pulsante di invio prima dell'esecuzione della richiamata sulla posizione, non si dispone di dati sulla posizione. La mia domanda è semplice, come posso aspettare che il callback della mia posizione sia terminato prima di inviare il mio modulo? (senza qualcosa di sciocco come una dichiarazione di sonno).
Idealmente mi piacerebbe lampeggiare un indicatore occupato e attendere i dati. È possibile? Ho il codice per rendere visibile un indicatore occupato, ma non sono sicuro di come posso aspettare con eleganza che i dati siano disponibili.Invio del modulo di ritardo fino a quando non viene recuperata la posizione

$(document).ready(function(){ 
    var lat = ""; 
    var lng = ""; 
    var accuracy = ""; 
    var locationFound = false; 

    if(navigator.geolocation){ 
     navigator.geolocation.getCurrentPosition(function positionSuccess(loc){ 
      lat = loc.coords.latitude; 
      lng = loc.coords.longitude; 
      accuracy = loc.coords.accuracy; 
      locationFound = true;    
     }); 
    }else{ 
     alert("I'm sorry, your jerk browser doesn't support geolocation"); 
     locationFound = true; 
    } 

$('#locForm').submit(function(e){ 

     $('#lat').val(lat); 
     $('#lng').val(lng); 
     $('#boundary').val($('#boundary-select').val()); 
} 

risposta

1

Disabilitare il pulsante di invio fino a quando non sono stati passati i dati di posizione.

$('input[type="submit"]').attr('disabled','disabled'); 

quindi attivare

$('input[type="submit"]').removeAttr('disabled'); 
+0

Credo che questo sia un buon ripiego, ma mi piacerebbe molto meglio che il pulsante abilitato e introdurre un ritardo dopo aver fatto clic sul pulsante piuttosto che dover avere il pulsante disabilitato per un po 'al caricamento della pagina. – rooftop

1

il pulsante di invio Se la posizione plugin che si sta utilizzando non dispone di una funzione di callback disponibile, allora si avrebbe bisogno di legare i risultati alla pagina in qualche modo e di controllo contro di esso prima che l'utente invia.

Un modo è vincolare i risultati della posizione al modulo, quindi consentire solo al modulo di inviare quando c'è un luogo lì. Ecco un esempio dell'utilizzo di .data() per ottenere ciò.

$(document).ready(function(){ 
     var lat = ""; 
     var lng = ""; 
     var accuracy = ""; 
     var locationFound = false; 

     if(navigator.geolocation){ 
      navigator.geolocation.getCurrentPosition(function positionSuccess(loc){ 
       lat = loc.coords.latitude; 
       lng = loc.coords.longitude; 
       accuracy = loc.coords.accuracy; 
       locationFound = true; 

       //bind the results to the form object using data() 
       $("#locForm").data('lat' , lat) 
       $("#locForm").data('lng' , lng) 
       $("#locForm").data('accuracy' , accuracy) 
       $("#locForm").data('locationFound' , locationFound) 

      }); 
     }else{ 
      alert("I'm sorry, your jerk browser doesn't support geolocation"); 
      locationFound = true; 
     } 

    $('#locForm').submit(function(e){ 

      e.preventDefault(); //prevents the normal submit 

      if ($("#locForm").data('lat') == "" || 
       $("#locForm").data('lng') == "" || 
       $("#locForm").data('accuracy') == "" || 
       $("#locForm").data('locationFound') == "" 
       ) { 
      alert("Please wait for the browser to detect your location."); 
      return false; 
       } 
      else {  
       $.post($(this).attr('action'), $(this).serialize(), function(data){ 
         // your callback data from the submit here 
       }); 
      } 



    } 

aggiunte questo codice che controlla ogni secondo per un valore dalla posizione plugin:

function wait4location() { 

      if ($("#locForm").data('lat') == "" || 
       $("#locForm").data('lng') == "" || 
       $("#locForm").data('accuracy') == "" || 
       $("#locForm").data('locationFound') == "" 
       ) { 
        x = setTimeout('wait4location()',1000) //every second 
       } else { 
        $("#loading").hide(); 
        return false; 
       } 
    } 

    $("#loading").show(); 
    wait4location(); 
+0

Il problema qui è che ti stai affidando a dire all'utente "per favore riprova" preferirei molto a un indicatore di occupato e attendere i dati. È possibile? Ho il codice per rendere visibile un indicatore occupato, ma non sono sicuro di come posso aspettare con eleganza che i dati siano disponibili. – rooftop

+0

È possibile impostare un timer su questo, altrimenti, di nuovo, se il plugin che recupera la posizione non ha una funzione 'CALLBACK' (che probabilmente fa, guarda la documentazione). –

+0

Ho aggiunto un codice che fa ciò che hai detto e verificherò ogni secondo fino a quando tutti i campi saranno popolati. –

0

Utilizzare due semafori:

var geoLoaded = false, 
    submittingForm = false; 

function LoadGeoData() { 
    // .. your load code 
    geoLoaded = true; 
    ReallySubmitForm(); 
} 

$('form').submit(function(e) { 
    // .. your code 
    submittingForm = true; 
    ReallySubmitForm(); 
}) 

function ReallySubmitForm() { 
    if (submittingForm && geoLoaded) { 
     // .. your submit code 
    } else { 
     // .. trigger loading code 
    } 
} 

questo modo, l'utente vedrà il carico immagine solo se i dati geografici non sono stati caricati completamente al momento dell'invio del modulo. Noterai che non importa quale evento viene innescato per primo, passerà solo quando entrambi saranno stati eseguiti.

0

HTML

<form id="form" action="" method="POST"> 

Javascript

function getLocation() { 
    if (navigator.geolocation) { 
     navigator.geolocation.getCurrentPosition(showPosition); 
    } else { 
     x.innerHTML = "Geolocation is not supported by this browser."; 
    } 
} 
function showPosition(position) { 
    x.innerHTML = "<input type=hidden name=lat id=lat value=" + 
     position.coords.latitude + "><input type=hidden name=lng id=lng value=" 
     + position.coords.longitude + ">"; 
    document.getElementById("form").submit(); 
}