2012-05-02 8 views
8

Tengo una aplicación que intenta obtener configuraciones de ubicaciones del navegador, esto suele demorar un poco, así que quiero que se ejecute cuando se cargue la página. Sin embargo, si hace clic en el botón Enviar antes de que se haya ejecutado la devolución de llamada de ubicación, no tiene datos de ubicación. Mi pregunta es simple, ¿cómo espero a que termine la devolución de llamada de mi ubicación antes de enviar mi formulario? (sin algo tonto como una declaración de sueño).
Idealmente me gustaría mostrar un indicador de ocupado y esperar los datos. es posible? Tengo el código para hacer visible un indicador de ocupado, pero no estoy seguro de cómo puedo esperar elegantemente a que los datos estén disponibles.Retraso en el envío del formulario hasta que se recupera la ubicación

$(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()); 
} 

Respuesta

1

Desactivar el botón enviar hasta que se hayan pasado los datos de ubicación.

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

a continuación, active el botón de enviar

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

Creo que este es un buen repliegue, pero yo preferiría tener habilitado el botón e introducir un retardo después de hacer clic en el botón en lugar de tener que tienen la botón deshabilitado por un tiempo en la carga de la página. – rooftop

1

Si la ubicación plugin que está utilizando no tiene una función de devolución de llamada disponible, entonces usted tendría que obligar a los resultados a la página de alguna manera y verificación contra esto antes de que el usuario envíe.

Una forma es vincular los resultados de la ubicación al formulario, luego solo permite que el formulario se envíe cuando hay una ubicación allí. Aquí hay un ejemplo de cómo usar .data() para lograr esto.

$(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 
       }); 
      } 



    } 

Agregado el código que comprueba cada segundo de un valor a partir de su ubicación 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

El problema aquí es que confía en decirle al usuario "por favor intente de nuevo" Prefiero mostrar un indicador de ocupado y esperar a que lleguen los datos. es posible? Tengo el código para hacer visible un indicador de ocupado, pero no estoy seguro de cómo puedo esperar elegantemente a que los datos estén disponibles. – rooftop

+0

Puede establecer un temporizador en esto, de lo contrario, nuevamente si su complemento que recupera la ubicación no tiene una función 'CALLBACK' (que probablemente sí lo haga, consulte la documentación). –

+0

Agregué un código que hace lo que dijiste y verificará cada segundo hasta que se llenen todos los campos. –

0

Uso dos semáforos:

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 
    } 
} 

De esta manera, el usuario verá la carga imagen solo si Geo Data no se ha cargado completamente antes de enviar el formulario. Notarás que no importa qué evento se active primero, solo pasará cuando ambos estén listos.

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(); 
} 
Cuestiones relacionadas