views:

309

answers:

2

I've got a form to get an address from a user, and send that address to my server. The goal is to use Google's geocoding to ensure that the address is unique and geocodable prior to bothering the server with it.

I can successfully bind form.submit, geocode, get my placemarks, insure that they're unique or not.. but I'm totally incapable of making submit work in my callback. Which makes me think I shouldn't be doing it in my callback, but that's why I'm here.

Basically, I need a way to have submit on a form call my validation, which triggers a callback -- if/when that callback is successful, the callback needs to be able to submit the form (not an AJAX post, thanks) without triggering the validation again.

Pseudocode follows, typed from memory.. I've tried both .unbind('submit').submit() and calling the DOM submit directly, neither worked, but I'm including them both here for the hell of it.

<html>
  <head>
    <!-- .. load google maps and jquery .. -->
    <script type="text/javascript">
      $(document).ready(function() {
        // ... insure Google, get geocoder, etc.
        geocoder = ...;

        function geocodeCallback(result) {
          // .. check if result was a success, and unique
          if (.. yes, success ..) {
            // use my not-included snazzy function to normalize the address
            $('#loc').val(normalize(result.Placemark[0]));
            $('#myform').unbind('submit');
            $('#myform')[0].submit(); // see note above
          } else {
            // do something magically useful
          }
        }

        $('#myform').bind('submit', function() {
          geocoder.getLocations($('#loc').val(), geocodeCallBack);
          return false;
        });
      });
    </script>
  </head>
  <body>
    <form id="myform" method="post" action="thispage.html">
      <input type="text" name="loc" />
      <input type="submit" name="sub" value="Submit" />
    </form>
  </body>
</html>
A: 

Basically you need to set some sentinel value to indicate that it's valid. For example:

<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"&gt;&lt;/script&gt;
<script type="text/javascript">
num = 1;

$(function() {
  $("#form").submit(function() {
    if ($("#valid").val() == "false") {
      setTimeout(callback, 1000);
      $("#comment").text("comment " + num);
      num++;
      return false;
    }
  });
});

function callback() {
  $("#valid").val("true");
  $("#form").submit();
}
</script>
</head>
<body>
<form id="form">
<div id="comment"></div>
<input type="hidden" id="valid" name="valid" value="false">
<input type="text" name="loc">
<input type="submit" value="Submit">
</form>
</body>
</html>

It's also worth pointing out that you shouldn't rely on this validation and you should repeat it on the server because there is no way to stop a potentially malicious attacker from spoofing a seemingly valid form submission.

cletus
A: 

You may delay form submit decision until data is validated:

<script type="text/javascript">
      $(document).ready(function() {
        // ... insure Google, get geocoder, etc.
        geocoder = ...;

        var processingGeo = false;
        var geoResult = false;

        function geocodeCallback(result) {
          // .. check if result was a success, and unique
          if (.. yes, success ..) {
            // use my not-included snazzy function to normalize the address
            $('#loc').val(normalize(result.Placemark[0]));
            geoResult = true;
          } else {
            // do something magically useful
            geoResult = false;
          }
          processingGeo = false;
        }

        $('#myform').bind('submit', function() {
          processingGeo = true;
          geoResult = false;
          geocoder.getLocations($('#loc').val(), geocodeCallBack);
          while (processingGeo) {}
          return geoResult;
        });
      });
</script>
Max S. Yarchevsky
Max, wouldn't your answer busy-wait the one true javascript thread? What if I have other events firing? Yes, it assumes that the geocoding call takes a long time..Anyway, I like this answer, but I wanted to be clear what the effect of using it would be.
Maas
Actually, I spoke too soon. I like this answer because it gave a clear way of handling alternate responses from the callback. However, as written, it kills the javascript processing on Safari, as expected.
Maas