2

Is there a way to get the City and State to select correctly once our operators type in the zip code? It feels like hours pass while trying to select the proper state in the dropdown.

1

Using a free (for now) service, getziptastic.com, you can implement a solution.

The forms containing the city, state, and zip codes are built in this file: app/design/adminhtml/default/default/template/sales/order/create/form/address.phtml

Update: Upon testing, I found the shipping address would change back to the original values after my Observer's function ended. This explains why every example on the Internet for Magento autocompletion only show the billing address and remain silent about shipping address. Looking at the code, I could tell these two lines were my problem:

    order.bindAddressFields('<?php echo $_fieldsContainerId ?>');
    order.bindAddressFields('<?php echo $_addressChoiceContainerId ?>');

Thanks to Chrome's developer tools and the watch expression for order, I eventually found the function loadArea() was nested inside bindAddressFields() which is already observing the form. Rather than manipulating the form elements via prototype or scriptacular, I instead change the global java object order. Also note how Magento developers made the element id's text appear like object notation.

To use loadArea(), I copied from js/mage/adminhtml/sales.js near line 304.

I ended up using separate functions for billing and shipping with the shared code using
<?php echo $bs ?> I added scriptacular's Effect.Highlight() for feedback to the user.

I added this at the bottom:
(apologies in advance for my lame javascript coding)

<?php if($this->getIsShipping()) { 
    $bs='shipping';
?>
<script type="text/javascript">
$('order-<?php echo $bs ?>_address_postcode').observe('change', function(event) {
    var data = order.serializeData(order.shippingAddressContainer);
    data = data.toObject();
    if( 'US' == data['order[shipping_address][country_id]'] ) {
        new Effect.Highlight( $('order-<?php echo $bs ?>_address_city'), { startcolor: "#ccddff", duration: 3 });
        new Effect.Highlight( $('order-<?php echo $bs ?>_address_region_id'), { startcolor: "#ccddff", duration: 3 });
        new Effect.Highlight( this, { startcolor: "#ccddff", duration: 3 });
        //  zip.php is our wrapper for JSON get of url = http://zip.getziptastic.com/v2/91941
        //  otherwise, Magento and javascript were mad about cross domain ajax call
        var url = '/var/export/zip.php?zip='+this.value;
        new Ajax.Request( url, {
            onSuccess: function(transport){
                var zcs = transport.responseText.evalJSON();    // zcs: zip city state
                data['order[shipping_address][postcode]'] = this.value;
                data['order[shipping_address][city]']=zcs.city;
                $$('select#order-<?php echo $bs ?>_address_region_id option').each(function(o) {
                  if(o.innerHTML == zcs.state) { // note, this compares strings
                    data['order[shipping_address][region_id]'] = o.value;
                  }
                });
                order.loadArea(['shipping_method', 'billing_method', 'shipping_address', 'totals', 'giftmessage'], true, data);
           }
        });
    }
});
</script>
<?php } else { 
    $bs='billing';
?>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=true&libraries=places"></script>
<script type="text/javascript">
var el<?php echo $bs ?> = document.getElementById('order-<?php echo $bs ?>_address_postcode');
Event.observe( el<?php echo $bs ?> ,'change', function( ) {  
    var country = document.getElementById('order-<?php echo $bs ?>_address_country_id');
    //  If we're in the US of A, we'll do this thing
    var index = country.selectedIndex;
    if( country.options[index].value == 'US' ) {
        new Effect.Highlight( $('order-<?php echo $bs ?>_address_city'), { startcolor: "#ccddff", duration: 3 });
        new Effect.Highlight( $('order-<?php echo $bs ?>_address_region_id'), { startcolor: "#ccddff", duration: 3 });
        new Effect.Highlight( this, { startcolor: "#ccddff", duration: 3 });
        var url = '/var/export/zip.php?zip='+el<?php echo $bs ?>.value;
        new Ajax.Request( url, {
            onSuccess: function(transport){
                var data = transport.responseText.evalJSON();
                var city = document.getElementById('order-<?php echo $bs ?>_address_city');
                city.value =  data.city;
                // change SELECT derived from: http://stackoverflow.com/questions/1243595/how-do-i-select-an-option-using-prototype
                $$('select#order-<?php echo $bs ?>_address_region_id option').each(function(o) {
                  if(o.innerHTML == data.state) { // note, this compares strings
                    o.selected = true;
                  } else { 
                    o.selected = false;
                  }
                });
           }
        });
    }
});
</script>
<?php } ?>

After spending a few hours trying to make the javascript do a cross domain ajax call to getziptastic.com, I gave up and made a php wrapper for this request: var/export/zip.php

<?php 
if( strlen( $_GET['zip'] ) ) {
    $url = 'https://zip.getziptastic.com/v2/'.$_GET['zip'];
    $json = file_get_contents( $url );
    echo $json;
}
?>

An alternative to the above procedure is to do it "the Magento Way" and build a module and evoke the php code in the Model and override address.phtml in your local code pool.

| improve this answer | |
  • 1
    addrexx.com takes it to a whole 'nother level (personal opinion: address autocompletes are creepy) – Reid Blomquist Nov 13 '14 at 2:54

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.