views:

78

answers:

2

hi,

I'm using the jQuery form plugin to call a function before submitting the form. This function call google geocoder service, that finds the coordinates of an address, and set the value of a hidden coordinates field in the form. It seems that the form is submitted before the beforeSubmit callback finishes. Is that normal? Isn't the form supposed to wait for the beforeSubmit callback to be finished? What's the best way to do that?

Thanks

javascript

$(function(){
    $("#submit").click(function() {  
        var options = { 
            beforeSubmit:  getPosition,  // pre-submit callback 
            success:       showResponse  // post-submit callback             
        }; 

        // bind form using 'ajaxForm' 
        $('#addresto').ajaxForm(options); 
    });  
});

function getPosition() {

    var geocoder =  new GClientGeocoder();

    var country = $("#id_country").val();
    var city = $("#id_city").val();
    var postal_code = $("#id_postal_code").val();
    var street_number = $("#id_street_number").val();
    var street = $("#id_street").val();
    var address = street_number+", "+street+", "+postal_code+", "+city+", "+country;

    geocoder.getLatLng( address, function(point) {
        if (point) {
            alert(point);
            $("#id_latitude").val(point.lat())
            $("#id_longitude").val(point.lng())
        } else {
          alert("Geocode was not successful");
        }
    });
    return true;
}

function showResponse() {
    alert('response');
}

HTML

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

<!-- some city, country, street... fields -->

<input type="Submit" id="submit" value="Submit" />
</form>
+2  A: 

I believe the geocoder's getLatLng() is called asynchronously. This means it isn't waiting for a response before continuing on to the return true; line.

With that in mind, there are basically two ways around it:

  1. You can call getLatLng() before the submit is ever triggered, like during an onchange event for the address and store the values for submitting. Or,
  2. You can add a flag that tells whether you've got a geocoding response yet or not, and return false; in beforeSubmit() if you don't have it yet. Then you could trigger a submit from the code when you get the response.
Jason
Good answer, you're right with the getLatLng().Solution 1 is a bit hackish and not entirely bulletproof, for instance, what if the function takes real long all of a sudden and the user submits before that?I'll elaborate on the second solution in a new answer.
Niels Bom
+2  A: 

@Jason's second solution is almost all the way there.

Chronologically:

  • A form input with the name LatLongAvailable is 0 by default
  • User enters location details
  • jQuery fires off getLatLng(), when getLatLng() returns the value, the form element LatLongAvailable is set to 1
  • jQuery calls a function that starts polling the form field LatLongAvailable
  • if the submit is clicked, first check whether LatLongAvailable == 1, if not, show a waiting sign,keep on trying every odd second, if it is 1, submit the form

More info on polling with Javascript can be found in a question I had.

Niels Bom