[LRUG] Geocoding and form submission

James Coglan jcoglan at googlemail.com
Fri Apr 10 06:17:44 PDT 2009


2009/4/10 James Coglan <jcoglan at googlemail.com>

>
>
> 2009/4/10 Dan Webb <dan at danwebb.net>
>
>> On Fri, Apr 10, 2009 at 11:58 AM, Andrew Stewart
>> <boss at airbladesoftware.com> wrote:
>> >> An alternative would be to replace the submit button with an <input
>> >> type="button"> so that the submission is entirely under your control.
>> If you
>> >> don't have to worry about non-JS fallback (which it sounds like is a
>> >> non-problem) that should be worth a try.
>>
>> That's not a good solution.  Aside from the form not being submittable
>> without JS, there are other problems associated.  Your forms won't
>> submit when you press return as many users expect.  Don't ever change
>> the mark up from what it should be just because you want to get a
>> particular effect with JavaScript.  Especially in this case where
>> there is no need at all.
>>
>> A possible more solid way of architecting something like this is to
>> have the gecoding service go through your application and you get the
>> result via Ajax.  Then if the form is submitted without that field
>> being gecoded then your application can do the geocoding...then you
>> get your non-JS fallback for free.
>
>
>
> You'd just need your geocoding function to take a callback to indicate what
> to do next. Some "pseudocode" (this is real code but uses a library that's
> not well-known -- you'll need to translate this to Prototype, jQuery, or
> whatever you're using):
>
> // I'm assuming you have some Ajax backend that returns JSON.
> // You'll need to modify this to call Google or whatever
> var geocode = function(addr, callback) {
>     $.HTTP.GET('/geocode', {address: addr}, function(response) {
>         callback(response.parseJSON());
>     });
> };
>
> var form    = $('#myForm'),
>      address = form.descendants('[name=address]'),
>     lat     = form.descendants('[name=lat]'),
>     lng     = form.descendants('[name=lng]');
>
> var updateLatLng = function(callback) {
>     geocode(address.node.value, function(data) {
>         lat.set({value: data.lat});
>         lng.set({value: data.lng});
>         if (typeof callback == 'function') callback();
>     });
> };
>
> address.on('blur', updateLatLng);
>
> form.on('submit', function(form, evnt) {
>     evnt.stopDefault();
>     updateLatLng(function() { form.node.submit() });
> });
>
>
> Hope that's of some use.



Just realised I mis-read what Dan was saying, that the action that processes
the form submission on the server side should call the geocoder if necessary
before saving the record. Matter of fact, this might be a better way to go
if you can do it on the server, you should only be using JS if you need some
UI feedback for the geocoding. What I often do is put together a Google Maps
widget that lets people search for an address and drag a marker around, and
this saves the current marker position into some hidden form fields -- then
the user gets accurate control of location data.

Still, the above code shows a useful technique known as 'continuation
passing style', where instead of returning a value directly, each function
takes a callback to call with the data when it becomes available. It's
really useful for combining async functions without tightly
coupling/duplicating bits of code.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lrug.org/pipermail/chat-lrug.org/attachments/20090410/3882c024/attachment-0003.html>


More information about the Chat mailing list