Address Auto-Complete Form

Address Form with Auto-Complete by Google

by jeremy_tactical

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<div id="notification" class="container-fluid text-center" style="display:none;">

  <div class="row">
    <div class="col-xs-12 col-sm-6 col-sm-offset-3">
      <div class="new-message-box">
        <div class="new-message-box-danger">
          <div class="info-tab tip-icon-danger" title="error"><i></i></div>
          <div id="msg" class="tip-box-danger">
            <p>Enter an address</p>
          </div>
        </div>
      </div>
    </div>
  </div>

</div>
<div class="container">

  <div class="panel panel-primary">


    <div class="panel-heading">
      <h3 class="panel-title">Address</h3>
    </div>
    <div class="panel-body">
      <form action="?" method="post">
        <label class="control-label" id="addressLine1Input-label">Address (No PO Box)</label>
        <input id="addressLine1Input" name="shippingAddress.address1" placeholder="Enter your address" onFocus="geolocate()" type="text" class="form-control" onblur="validateAddress()" required>
        <br />
        <div id="address">
          <div class="row">
            <div class="col-md-6">
              <label class="control-label">Suburb</label>
              <input class="form-control" id="addressLine2Input" disabled="true">
            </div>
          </div>
          <div class="row">
            <div class="col-md-6">
              <label class="control-label">City</label>
              <input class="form-control field" id="cityInput" disabled="true">
            </div>
            <div class="col-md-6">
              <label class="control-label">State</label>
              <input...

CSS

.container {
  margin-top: 20px;
}

@charset "UTF-8";
/*==================================================
=            Bootstrap 3 Media Queries             =
==================================================*/
/*==========  Mobile First Method  ==========*/
/* Custom, iPhone Retina */
/* Extra Small Devices, Phones */
/* Small Devices, Tablets */
/* Medium Devices, Desktops */
/* Large Devices, Wide Screens */
/*==========  Non-Mobile First Method  ==========*/
/* Large Devices, Wide Screens */
/* Medium Devices, Desktops */
/* Small Devices, Tablets */
/* Extra Small Devices, Phones */
/* Custom, iPhone Retina */
/*=====================================================
=            Bootstrap 2.3.2 Media Queries            =
=====================================================*/
/* default styles here for older browsers. 
   I tend to go for a 600px - 960px width max but using percentages
*/
@media only screen and (min-width: 960px) {
  /* styles for browsers larger than 960px; */
}
@media only screen and (min-width: 1440px) {
  /* styles for browsers larger than 1440px; */
}
@media only screen and (min-width: 2000px) {
  /* for sumo sized (mac) screens */
}
@media only screen and (max-device-width: 480px) {
  /* styles for mobile browsers smaller than 480px; (iPhone) */
}
@media only screen and (device-width: 768px) {
  /* default iPad screens */
}
/* different techniques for iPad screening */
@media only screen and (min-device-width: 481px) and (max-device-width: 1024px) and (orientation: portrait) {
  /* For portrait layouts only */
}
@media only screen and (min-device-width: 481px) and (max-device-width: 1024px) and (orientation: landscape) {
  /* For landscape layouts only */
}
/*******Nuevos mensajes de error******/
.new-message-box {
  margin: 15px 0;
  padding-left: 20px;
  margin-bottom: 25px !important;
}

.new-message-box p {
  font-size: 1.15em;
  font-weight: 600;
}

.info-tab {
  width: 40px;
  height: 40px;
  display: inline-block;
  position:...

JavaScript

var placeSearch, autocomplete, map, geo;
var componentForm = {
	subpremise: 'short_name',
	street_number: 'short_name',
  route: 'long_name',
  sublocality_level_1: 'short_name',
  locality: 'long_name',
  administrative_area_level_1: 'short_name',
  country: 'short_name',
  postal_code: 'short_name'
};

var componentInputs = {
  sublocality_level_1: 'addressLine2Input',
  locality: 'cityInput',
  administrative_area_level_1: 'provinceInput',
  country: 'countryCodeInput',
  postal_code: 'postCodeInput'
};

var BreakException = {};

var regex = /^.*(po\s*box|private\s*bag).*$|^\d[\/a-zĀ-ū0-9\s\,\'\-]*$/i;

/** @start HTML5 form validation **/
let fulladdress = document.getElementById('addressLine1Input');
fulladdress.onblur = validate;

fulladdress.setAttribute("pattern", "\\d[/a-zA-ZĀ-ū0-9\\s',-]*");

fulladdress.addEventListener('input', () => {
  fulladdress.setCustomValidity('');
  fulladdress.checkValidity();
});

fulladdress.addEventListener('invalid', () => {
  fulladdress.setCustomValidity('No PO Box or Private Bag address must start with a number, e.g. 1/311 Canaveral Drive');
});
/** @end HTML5 form validation **/

function getValue() {
  return document.getElementById("addressLine1Input").value;
}

function validateAddress() {
  var str = getValue();
  var match = str.match(regex);
  var tooltip = document.getElementById("notification");
  var msg = document.getElementById("msg");

  if (match && !match[1]) {

    // valid address
    msg.innerHTML = "<p>Address looks to be valid</p>";
    tooltip.style.display = 'none';

  } else {

    // invalid address
    msg.innerHTML = "<p>Invalid address (No PO Box or Private Bag address must start with a number, e.g. 1/311 Canaveral Drive)</p>";
    tooltip.style.display = 'block';

  }
}

function initAutocomplete() {
  // Create the autocomplete object, restricting the search to geographical
  // location types.
  autocomplete = new google.maps.places.Autocomplete(
    /** @type {!HTMLInputElement} */
   ...