Tuesday, May 07, 2013

Microsoft Dynamics CRM 2011: Lookup address by ZIP Code

This time I had task to write code that lookups address details (country, state and city) by entered postal code. I will share with my results in this post.
In my code I used Google Geocoding Webservices. Why? Because I have already tried other geolocating webservices (like Bing) in previous projects and results were amazing for USA and Canada but for other countries results were not ideal.
1. Add jQuery to your solution. You can find it here - http://jquery.com/download/
2. Create new webresource (for example AddresLookup.js) of JS type and put following code inside:

if (typeof Slickdata == 'undefined') {
    Slickdata = {
        __namespace: true
    };
}

if (typeof Slickdata.AddressLookup == 'undefined') {
    Slickdata.AddressLookup = {
        Resolve: function () {
            Xrm.Page.getAttribute("address1_country").setValue(null);
            Xrm.Page.getAttribute("address1_stateorprovince").setValue(null);
            Xrm.Page.getAttribute("address1_city").setValue(null);

            if (Xrm.Page.getAttribute('address1_postalcode').getValue() == null) {
                return;
            }

            jQuery.support.cors = true;
            var requestUrl = 'http://maps.google.com/maps/api/geocode/json?sensor=false&components=country:US|postal_code:' + 
        Xrm.Page.getAttribute('address1_postalcode').getValue();

            $.getJSON(requestUrl, function (data, textStatus, XmlHttpRequest) {
                if (data.status == "OK" && data.results.length != 0) {
                    var address = data.results[0].address_components;

                    for (var i = 0; i < address.length; i++) {
                        switch (address[i].types[0]) {
                            case 'country':
                                Xrm.Page.getAttribute("address1_country").setValue(address[i].short_name);
                                break;
                            case 'administrative_area_level_1':
                                Xrm.Page.getAttribute("address1_stateorprovince").setValue(address[i].short_name);
                                break;
                            case 'administrative_area_level_2':
                            case 'locality':
                                Xrm.Page.getAttribute("address1_city").setValue(address[i].short_name);
                                break;
                        }
                    }
                }
                else {
                    alert('No data was found');
                }
            });
        },
        __namespace: true
    };
}


Note: in case you will use address lookup for other fields then I (address1_postalcode, address1_country, address1_stateorprovince, address1_city) you will have to modify code to use proper fields. I developed functionality for customer from USA so I put additional filter to show results only from USA – in case you will use provided code for other country you will have to remove the filter.

3. Open entity form (I used lead) that you want to have lookup functionality and add jQuery and AddressLookup webresources.

4. Add OnChange handler to Postal Code field as it shown on following screenshot:
5. Save and publish entity. Once this is done you can use functionality:
Note: to make this functionality work in IE you should to 2 actions:

1. Add http://maps.google.com to trusted websites.

2. Change security settings of IE as it shown on following screenshots: