views:

256

answers:

3

I'm having a JavaScript issue where I need a function to run and complete before another function is run.

Here's the code I need to run and complete first. As you can see, I'm looping through all address input fields in the form and geocoding them through the Google Maps API.

  $('#form input:text.address').each(function() {
    var address = $(this);
    var Geocoder = new google.maps.Geocoder();

    Geocoder.geocode({ 'address': address.val() }, function(results, status) {
      // Store the results in a hidden input field.
    });
  });

After this fully completes — that is, after all the responses from the Google Maps API have returned — I then need the form to submit. Here's the current ajax submit code I use:

  $('#form').ajaxForm(
    {
      success:
        function() {
          ...
        }
    }
  );

The problem I'm having is the form is submitted before the Google Maps API has responded. The ajaxForm() method allows a beforeSubmit callback function, but that still does not wait for the function to complete. I realize this is because JavaScript is asynchronous, but I'm unsure how to solve this particular issue.

Any help is appreciated! Thanks!

+7  A: 

Call the form submit from the success handler of Geocoder.geocode. Since you have many calls to the same function, set an indicator to indicate when the last call is finished and then submit the form.

Here is one way...

var count = $('#form input:text.address').size();
$('#form input:text.address').each(function() {
    var address = $(this);
    var Geocoder = new google.maps.Geocoder();

    Geocoder.geocode({ 'address': address.val() }, function(results, status) {
      // Store the results in a hidden input field.
      count--;
      if (count === 0) {
          //submit form here!
      }
    });
  });
Chetan Sastry
Interesting solution method...
Maxim Zaslavsky
Thanks, Chetan! That solution works.
Justin Stayton
A: 

I don't know JQuery, so please forgive me if I'm off base, but it seems to me that you can solve your problem by submitting the form inside the geocode results handler (where it says // Store the results in a hidden input field.) instead of from that other success handler (which I gather is supposed to be called when an AJAX query succeeds?). Is there something preventing you from doing it that way?

rmeador
A: 

The problem is that the form can still be submitted before all Google-functions have loaded their data? Then we need to disable the submit buttons from the start, load all the data, and then enable the forms again after it has completed loading.

Uing chetan-sastry's solution to check for when form has loaded things should look something like this.

var count = $('#form input:text.address').size();

$('#form input:text.address').each(function() {
  var address = $(this);
  var Geocoder = new google.maps.Geocoder();

  Geocoder.geocode({ 'address': address.val() }, function(results, status) {
    // Store the results in a hidden input field.

      count--;
      if (count === 0) {
         $('#form').ajaxForm( /* ... */);
         $('#form input:submit').attr('disabled', '0'); // Enable submit-buttons
      }
  });
});

Then to prevent the user to submit the form before stuff has been loaded you should set the submit to disabled when the page is loading.

<input type="submit" disabled="1" />
Morningcoffee
Thanks for your reply, Morningcoffee! The problem is, the addresses are geocoded when the form is submitted.
Justin Stayton
ah, I see. Maybe you should clear that out in your second code sample, that you are running your first code sample inside that one :)
Morningcoffee