jQuery UI and Auto-Complete Address Entry
Written by Ian Elliot   
Tuesday, 18 April 2017
Article Index
jQuery UI and Auto-Complete Address Entry
Using the Melissa Data API
Going Global

expentsq

Using the Melissa Data API

Now it is time to work with the Global Express Entry API, which is fairly easy.  We could create the function that does all the work inline as part of the autocomplete, but when functions have more than a few lines it is better to make them separate named functions.

$('#address').autocomplete(
  {
     source: getAddress
  }

Now our job is to define the getAddress function.

We first need two items of data, the url of the server and your private key.

var url = "http://expressentry.melissadata.net/";
var id = "your key";
 

It makes sense to add the fixed part of the request to the url:

url += "jsonp/ExpressFreeForm?callback=?";

There are a number of different URLs you can use depending on the exact service you want. In this case we are using the free form search for the USA. There are URLs that allow you to search for an autocomplete using different specific parts of the address, i.e. the postal code, state and city and street. There are also corresponding URLs for searching the world for an address. In this case you have to specify the code of the country you want to search - more of this later. 

As this is a cross domain JSON request, it is in fact a JSONP request as indicated by callback=?. You don't need to worry about the details of how the JSONP request is handled, jQuery does all that for you. However the Global Express Entry API does need some additional data to work out what its response should be and this has to be added to the query string.The good news is that jQuery lets you specify anything you want in the query string as an object containing key value pairs. 

 

 var query = {
               format: "jsonp",
                   id: id,
                   FF: request.term,
           maxrecords: "30"
             };

 

These are fairly obvious options and you can find more about them in the Global Express Wiki. The format property can be jsonp or xml, id is your key, FF specifies the data for the autocomplete, i.e. what the user has typed so far and maxrecords specifies the number of records you want returned. 

Now we have the URL and the query we can make use of jQuery's getJSON function. There are two ways to make use of this. The first is to provide a success and a fail callback, but the modern way to do this is to make use of the promise object that is returned.

If you think that using a promise object is overly complex, then it is worth pointing out that at its simplest it is no more than specifying a success and fail callback. For example:

$.getJSON(url, query) .then(
                        function (data) {
                        },
                        function (data) {
                        }
                      );

The first function specified in the then is the success callback and the second is the fail callback. Given that this is so much like using a pair of callbacks you might ask why bother? The answer is that the promise approach is far more flexible and when you come to extend the program it will be much easier if you use a promise. 

When the getJSON call has retrieved the data the promise will call either the success or the fail callback passing the data that the JSONP returned fully expanded into a JavaScript object or array. In this case an object is returned with three important properties:

Version     Version information of the service
ResultCode  XS01=all, XS02=some or XS03=none
Results     An array of address records

Each address record has the format:

AddressLine1     Line 1 of the output address
City             The city of the output address
CityAccepted     USPS accepted city name of the address
CityNotAccepted  Vanity city name of the address
State            The state of the address 
PostalCode       The postal code of the address
CountrySubdivisionCode  The Subdivision Code for the state
AddressKey       Address Key of the address 
SuiteName        The type of suite at the address 
SuiteCount       The number of suites at the address
SuiteList        A list of suites at the address
PlusFour         The +4 of each suite at the address
MAK              The Melissa Address Key for this address
BaseMAK         

The base Melissa Address Key the building

 

 

We need to process each record to create an address that we can show to the user and one to enter if the user selects it.The first requirement is to show the user a recognizable address list to pick from. The only small problem we have is what to do if there are multiple suites, i.e separate business entities occupying a single address. To handle this fairly infrequent occurrence we would have to allow the user to select the suite to use to get the complete address. For the moment let's ignore this complication and construct an address that doesn't have a suite.

You can do this in a number of ways, but to show how easy it is let's look at a standard for loop used to scan the array and build up an array of label value objects in the promise's success function:

function (data) {
 var i, item;
 var auto=[];
 for (i = 0; i < data.Results.length; i++) {
  item = data.Results[i];
  auto[i] = {label: item.Address.AddressLine1 + " " +
                    item.Address.City + ", " +
                    item.Address.State + " " +
                    item.Address.PostalCode,
             value: item.Address.AddressLine1};
 }
 response(auto);
}

You can see that we build up the label to be shown to the user from the different fields in the address data.

Now that you have seen this simplified version of the function, it is easy to understand the more usual version in the normal jQuery functional idiom using map: 

function (data) {
 var auto=$.map(data.Results,function(item){
   return {label: item.Address.AddressLine1 + " " +
                  item.Address.City + ", " +
                  item.Address.State + " " +
                  item.Address.PostalCode,
           value: item.Address.AddressLine1};
  });

The map function takes the array specified as the first parameter and applies the function specified as the second parameter to each of its items in turn. The return values are formed into a new array which is returned by the map function. In most cases you can avoid for loops to scan through and process arrays.

If you run the program you will discover that a list of addresses is displayed, but there is a small problem. The list is shown when the first letter is typed and it is better to wait for more of the address before performing a lookup. There are options for the autocomplete widget that let you specify how many characters need to be typed and a delay between lookups:

 {
      source: getAddress,
   minLength: 4,
       delay: 400
 }

You can arrange to tune these values to get the response you want. 

We have one last problem. 

At the moment the program places the selected address into the field that the user is typing in and we want it to go into the textarea. In  general we probably want the address to be stored in individual fields so that it can be stored in a database, but this is also easy.

To process the user's selection all we have to do is provide a select event handler within the autocomplete widgets options:

 {
     source: getAddress,
  minLength: 4,
      delay: 400,
     select:function(event,ui){    
              $("#result").val(ui.item.value);
              return false;
            }
}

 

This finalizes our working autocomplete program.

expentsq



Last Updated ( Tuesday, 18 April 2017 )