Robert Dodd
Robert Dodd

Reputation: 2187

jQuery Validate Address - Google Places API

I have a simple form where the user enters an address.

Before the form is submitted I perform a TextSearch using the Places Api and put this data into a hidden input field in the form, and then submit it.

I want to use jQuery Validate to the validate the form, but I dont know how to get the Places data together with it.

I think I have to use the submitHandler with Validate, but im not sure how to put my code in here:

$("#myform").validate({
 submitHandler: function(form) {
   form.submit();
 }
});

Here is my code I have without the Validate plugin:

<!DOCTYPE html>
<html>
    <head>
        <title>Maps Test</title>
        <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
        <style type="text/css">
            html { height: 100% }
            body { height: 100%; margin: 0; padding: 0 }
            #map_canvas { height: 100% }
        </style>
        <script type="text/javascript"src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
        <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?libraries=places&sensor=false"></script>
        <script src="http://code.jquery.com/jquery-latest.js"></script>
        <script type="text/javascript">
            var map;
            var service;
            var infowindow;
            var service;
            var validated = false;

            function initialize() {
                var pyrmont = new google.maps.LatLng(-33.8665433,151.1956316);

                map = new google.maps.Map(document.getElementById('map_canvas'), {
                        mapTypeId: google.maps.MapTypeId.ROADMAP,
                        center: pyrmont,
                        zoom: 15
                    });

                service = new google.maps.places.PlacesService(map);
            }

            function textsearchcallback(results, status) {
                if (status == google.maps.places.PlacesServiceStatus.OK) {
                    var place = results[0];
                    var request = {
                        reference: place.reference
                    };
                    service.getDetails(request, getdetailscallback);
                } else {
                    alert("ERROR: NO RESULTS FOUND!");
                }
            }

            function getdetailscallback(place, status) {
                if (status == google.maps.places.PlacesServiceStatus.OK) {
                    $("#placeinfo").val(JSON.stringify(place));
                    validated = true;
                    $("#search-form").submit();
                    validated = false;
                    $("#placeinfo").val("");
                } else {
                    alert("ERROR");
                }
            }

            function validateForm() {
                var searchfield = $("#search-field").val();
                if (searchfield == null || searchfield == "") {
                    alert("Please enter address");
                    return false;
                }
                if (validated) {
                    return true;
                } else {
                    var request = {
                        query: searchfield
                    };
                    service.textSearch(request, textsearchcallback);
                    return false;
                }
            }
        </script>
    </head>

    <body onload="initialize()">
        <form id="search-form" name="input" action="html_form_action.asp" method="get" onsubmit="return validateForm()">
            <input autocomplete="off" placeholder="Address, Airport or Postcode..." id="search-field" size="50" type="text"><br>
            <input type="hidden" name="placeinfo" id="placeinfo">
            <input type="SUBMIT" value="Search" /><br>
        </form>

        <div id="map_canvas" style="width:600px; height:400px"></div>
    </body>
</html>

EDIT:

Here is a Fiddle with the working code: http://jsfiddle.net/robertdodd/txqnL/26/

Upvotes: 1

Views: 8295

Answers (2)

Robert Dodd
Robert Dodd

Reputation: 2187

Option 1 - Client side validation

This method is messy and a bit of a hack, I DO NOT recommended this unless you have no other way. I recommend using another validation library or writing your own, which is what I plan to do myself.

Simple demo: http://jsfiddle.net/robertdodd/txqnL/27/

Heres step by step what happens:

  1. User clicks submit
  2. Form is validated by jQuery
  3. In the submit handler I prevent the form from submitting and look up the address with google
  4. When google returns I fill the hidden input and set validated = true
  5. I then resubmit the form, and this time it submits because validated == true

Option 2 - Server side validation:

The other option is server side validation, which I recommend as a backup anyway. Here is how to use it with the validate plugin.

  1. Use remote validation method to get a response from server
  2. Use dataFilter to retrieve the Maps info from the response, put it into hidden input, then change response by returning either '"true"' or '"error message"' because remote validation requires a certain string (read here)

Heres my html code:

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" src="http://jzaefferer.github.com/jquery-validation/jquery.validate.js"></script>
<script type="text/javascript">
  
  function initialize() {
    $("#search-form").validate({
      rules: {
        searchfield: {
          required: true,
          remote: {
            url: "/validate",
            type: "get",
            dataFilter: function(data) {
              var json = JSON.parse(data);
              var placename = json.placename;
              $('#placename').val(placename);
              return '"' + json.result + '"';
            }
          }
        }
      }
    });
  }
</script>
</head>
  
  <body onload="initialize()">
    <form id="search-form" >
      <input autocomplete="off" placeholder="Enter a location" name="searchfield" id="searchfield" type="text" /><br/>
      <input type="hidden" name="placename" id="placename" />
      <input type="submit" value="Search" /><br/>
    </form>
    <div id="successmessage"></div>
  </body>
</html>

I hope this helps someone!

Upvotes: 1

Sparky
Sparky

Reputation: 98738

If I understand you correctly, you just want to integrate jQuery Validation in place of your own manual validation. Yes, you would call your functions from within the plugin's submitHandler, but there is too much code missing from your OP for a working demo of your Maps functions.

This is something like what you'd need to do.

$(document).ready(function () {
    $('#myform').validate({ // initialize the plugin
        // your rules and options,
        ignore: [], // this option is required if you need to validate hidden inputs
        submitHandler: function (form) { 
            // your functions here
            form.submit(); // to submit the form when you're ready
        }
    });
});

Alternatively, if you need to use ajax to submit the form without a page redirect...

$(document).ready(function () {
    $('#myform').validate({ // initialize the plugin
        // your rules and options,
        ignore: [], // this option is required if you need to validate hidden inputs
        submitHandler: function (form) { 
            // ajax functions here
            return false; // to block the normal form submit since you just did it with ajax
        }
    });
});

HTML:

You will also need to remove the onsubmit event handler from your HTML since that's already built into the jQuery Validate plugin.

<form id="search-form" name="input" action="html_form_action.asp" method="get" 
onsubmit="return validateForm()">

would become...

<form id="search-form" name="input" action="html_form_action.asp" method="get">

Simplified Demo: http://jsfiddle.net/wbdvc/


EDIT:

Regarding the jsFiddle demo in the OP's edit:

The following if/then conditional will never work properly. By definition, the submitHandler is the callback for a valid form. In other words, the only time the submitHandler function will run is after the form has already tested "valid" and just before the actual form submit.

submitHandler: function(form) {
    if (validated) { 
        // address is validated and hidden input filled, so submit the form
        alert('valid form submitted');
        validated = false;
    } else { 
        // address is not validated yet, look up on Google Maps
        var request = {
            query: $("#searchfield").val()
        };
        service.textSearch(request, textsearchcallback);
    }
    return false;
}

Instead of placing that logic inside of submitHandler, you could place it within addMethod...

http://docs.jquery.com/Plugins/Validation/Validator/addMethod#namemethodmessage

This creates a new rule that you would use like any other predefined Validate plugin rule.

Upvotes: 0

Related Questions