Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delay form submission until location is retrieved

I have an application that attempts to get locations settings from the browser, this tends to take a little while so I want it to run when the page loads. However, if you click the submit button before the location callback has run, you have no location data. My question is simple, how do I wait for my location success callback to finish before submitting my form? (without something silly like a sleep statement).
Ideally I'd like to flash a busy indicator and wait for the data. Is this possible? I have the code to make a busy indicator visible, but am not sure how I can elegantly wait for the data to be available.

$(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());
}
like image 705
rooftop Avatar asked May 02 '12 01:05

rooftop


2 Answers

Disable the submit button until the location data has been passed.

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

Then enable the submit button

$('input[type="submit"]').removeAttr('disabled');
like image 152
luke2012 Avatar answered Sep 21 '22 11:09

luke2012


If the location plugin you're using doesn't have a callback function available, then you would need to bind the results to the page somehow and check against it before the user submits.

One way is binding the results of the location to the form, then only allow the form to submit when there is a location there. Here is an example of using .data() to accomplish this.

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



    }

Added this code which checks every second for a value in from your location 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();
like image 37
Control Freak Avatar answered Sep 17 '22 11:09

Control Freak