1
\$\begingroup\$

The rules for this script are simple:

  • If geocode is hit, then just geocode
  • If geocode and submit is hit, then geocode and then submit
  • If an autosuggest link is hit, then geocode instantly
  • In this case, do not re-geocode later when the button is hit

This is my code, based on help and advice from here:

http://jsfiddle.net/spadez/Jfdbz/14/

$(function () {
    var lastQuery = null,
        lastResult = null, // new!
        autocomplete,
        processLocation = function (callback) { // accept a callback argument
            var input = $("#loc"),
                lat = $("#lat"),
                long = $("#lng");
            var query = $.trim(input.val()),
                geocoder;
            // if query is empty or the same as last time...
            if (!query || query === lastQuery) {
                if (callback) {
                    callback(lastResult); // send the same result as before
                }
                return; // and stop here
            }

            lastQuery = query; // store for next time

            geocoder = new google.maps.Geocoder();
            geocoder.geocode({
                address: query
            }, function (results, status) {
                if (status === google.maps.GeocoderStatus.OK) {
                    lat.val(results[0].geometry.location.lat());
                    long.val(results[0].geometry.location.lng());
                    lastResult = true; // success!
                } else {
                    alert("Sorry - We couldn't find this location. Please try an alternative");
                    lastResult = false; // failure!
                }
                if (callback) {
                    callback(lastResult); // send the result back
                }
            });
        },
        ctryiso = $("#ctry").val(),
        options = {
            types: ["geocode"]
        };

    if (ctryiso !== '') {
        options.componentRestrictions = {
            'country': ctryiso
        };
    }
    autocomplete = new google.maps.places.Autocomplete($("#loc")[0], options);

    google.maps.event.addListener(autocomplete, 'place_changed', processLocation);

    $('#search').click(function (e) {
        var form = $(this).closest('form');
        e.preventDefault(); // stop the submission

        processLocation(function (success) {
            if (success) { // if the geocoding succeeded, submit the form
                form.submit();
            }
        });
    });

    $('#geosearch').click(function (e) {
        var form = $(this).closest('form');
        e.preventDefault(); // stop the submission
        processLocation();
    });
});

I think I have reached the point where it works correctly, and I can't seem to make it any more structured, any more readable, any more efficient or compact. However, I am new to javascript and I would be really open to hear if anyone feels that they can improve on this.

I must admit I a bit pedantic and get a lot of satisfaction out of the refining process!

EDIT: I pasted the code wrong - fixed

\$\endgroup\$
1
\$\begingroup\$

Just a few things in no particular order:

  • Don't use long as a variable name. It's a reserved word in Javascript and can cause confusion.
  • If you're going to disable the country input in your form, you should probably just put the US keyword straight in your code. That is if you don't intend on enabling it.
  • You set ctryiso = $("#ctry").val() and then test ctryiso !== ''. Since you hard coded the country value in, that will always be true. Therefore, unnecessary test.
  • You don't need to initialize your lastQuery and lastResult to null. Any falsy value will do just fine in JS, including undefined.
  • If you look at the jQuery source code you'll see that the .click() simply calls another method and passes the values on. You can save a few function calls if you just call that other method directly.

Like so:

$('#search').click(function (e) {
    //Do stuff
}

//Do this one instead
$('#search').on('click', function (e) {
    //Do stuff
}

The 'click' can be replaced with any event of you're choosing. This gives you enormous power and control when setting up custom events.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.