Configuring city as dropdown option in checkout billing & shipping address

June 15, 2013  |  15 Comments  |  by Raj (MagePsycho)  |  Latest, Magento

Introduction

Magento provides country and region* as dropdown option in checkout addresses unlike city which is an input text field. This on one side provides flexibility but on other side increases chances of typo in city names.
If you want your store to have an extra operations like giving free shipping to certain cities, giving COD payment option to certain cities etc., it’s better to configure the input city field as dropdown.
Here we will be discussing on listing United Arab Emirates’ cities as dropdown option.

Steps

Assume MagePsycho_Citydropdown skeleton module has already been created.
1. Adding functions for populating cities.
File: app/code/local/MagePsycho/Citydropdown/Helper/Data.php
Code:

<?php
/**
 * @category   MagePsycho
 * @package    MagePsycho_Citydropdown
 * @author     magepsycho@gmail.com
 * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */
class MagePsycho_Citydropdown_Helper_Data extends Mage_Core_Helper_Abstract
{
	public function getUaeCities()
	{
		$helper = Mage::helper('directory');
		$cities = array(
			$helper->__('Abu Dhabi'),
			$helper->__('Ajman'),
			$helper->__('Al Ain'),
			$helper->__('Dubai'),
			$helper->__('Fujairah'),
			$helper->__('Ras al Khaimah'),
			$helper->__('Sharjah'),
			$helper->__('Umm al Quwain'),
		);
		return $cities;
	}

	public function getUaeCitiesAsDropdown($selectedCity = '')
	{
		$cities = $this->getUaeCities();
		$options = '';
		foreach($cities as $city){
			$isSelected = $selectedCity == $city ? ' selected="selected"' : null;
			$options .= '<option value="' . $city . '"' . $isSelected . '>' . $city . '</option>';
		}
		return $options;
	}
}

Notes: You can also populate the cities in db tables to make it more dynamic. For example, you can create following tables similar to regions:
+ directory_country_city (city_id, country_id, code, default_name)
+ directory_country_city_name (locale, city_id, name)

2. Replacing input text city field to dropdown using javascript
2.1
File: app/design/frontend/[package]/[theme]/template/checkout/onepage/billing.phtml
Code: Add the following code to the last of above template

<script type="text/javascript">
	<?php
	$helper			 = Mage::helper('citydropdown');
	$address		 = Mage::getSingleton('checkout/session')->getQuote()->getBillingAddress();
	$defaultCity	 = $address->getCity();
	$citiesOptions	 = addslashes($helper->getUaeCitiesAsDropdown($defaultCity));
	?>

	var billingCity = '<?php echo $defaultCity ; ?>';
	function billingSwitchCityField(){
		var selectVal = jQuery('#billing\\:country_id option:selected').val();
		if(selectVal == "AE"){
			jQuery("#billing\\:city")
			.replaceWith('<select id="billing:city" name="billing[city]" class="required-entry">' +
				  '<option value=""></option>' +
				  '<?php echo $citiesOptions; ?>' +
				'</select>');
		}else{
			jQuery("#billing\\:city")
			.replaceWith('<input type="text" class=" input-text required-entry absolute-advice " title="City" value="' + billingCity + '" id="billing:city" name="billing[city]" autocomplete="off">');
		}

	}
   jQuery(document).ready(function(){
		billingSwitchCityField();
		jQuery('#billing\\:country_id').change(function() {
			billingSwitchCityField();
		});
   })
</script>

2.2
File: app/design/frontend/[package]/[theme]/template/checkout/onepage/shipping.phtml
Code: Add the following code to the last of above template

<script type="text/javascript">
	<?php
	$helper			 = Mage::helper('citydropdown');
	$address		 = Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress();
	$defaultCity	 = $address->getCity();
	$citiesOptions	 = addslashes($helper->getUaeCitiesAsDropdown($defaultCity));
	?>




	var shippingCity = '<?php echo $defaultCity ; ?>';
	function shippingSwitchCityField(){
		var selectVal = jQuery('#shipping\\:country_id option:selected').val();
		if(selectVal == "AE"){
			jQuery("#shipping\\:city")
			.replaceWith('<select id="shipping:city" name="shipping[city]" class="required-entry">' +
				  '<option value=""></option>' +
				  '<?php echo $citiesOptions; ?>' +
				'</select>');
		}else{
			jQuery("#shipping\\:city")
			.replaceWith('<input type="text" class=" input-text required-entry absolute-advice " title="City" value="' + shippingCity + '" id="shipping:city" name="shipping[city]" autocomplete="off">');
		}




	}
   jQuery(document).ready(function(){
		shippingSwitchCityField();
		jQuery('#shipping\\:country_id').change(function() {
			shippingSwitchCityField();
		});
   })
</script>

3. Reload the checkout page, you can see the city options for United Arab Emirates as:

City as dropdown field


In the similar manner you can configure the city options for other countries as well and for other sections like My Account > Address Book etc.

Thanks for reading & sharing.

Posted in Latest, Magento and tagged , , , . Bookmark the permalink.

About Raj (MagePsycho)

Raj, the guy behind MagePsycho is a Zend PHP5 Certified Engineer, Magento Certified Developer, Magento Moderator / Freelancer with specialization in web applications (CMS, E-Commerce, ERP etc.). Catch him on: Twitter: @magepsycho Skype: magentopycho
  • Upma

    Not working for me. Please help me

  • tnchuntic

    where to link the helper? then I didn’t get this “Assume MagePsycho_Citydropdown skeleton module has already been created.” I am just starting learning magento.

  • http://www.jehzlau-concepts.com/ jehzlau

    Nice tut. But how can I create a skeleton module? I don’t have an idea how. This is my first day on Magento. O__O

  • Saleh G

    @Upma … can you post your etc/config,xml .This is nice piece of code and working for me.If anyone wants the entire module contact me on unimax.systems@gmail.com

    Thanks

  • Rajveer Pratap

    nice .
    How it dynamically . this + directory_country_city (city_id, country_id, code, default_name)
    + directory_country_city_name (locale, city_id, name) not work as dynamically .

  • Gunawan Sumantri

    I has go through all the above steps, but the data cannot appear.

    How to replace

    <input type="text" title="__(‘City’) ?>” name=”billing[city]” value=”escapeHtml($this->getAddress()->getCity()) ?>” class=”input-text helper(‘customer/address’)->getAttributeValidationClass(‘city’) ?>” id=”billing:city” />

    in File: app/design/frontend/[package]/[theme]/template/checkout/onepage/billing.phtml

  • M Sohrab Zia

    i have no idea about MagePsycho_Citydropdown skeleton module , any one? it would be cool if someone just make an extension.

  • ChefMaha

    beginning of the article says: “Assume MagePsycho_Citydropdown skeleton module has already been created.”

    Can you kindly provide steps for creating the skeleton module?

    Thanks!

  • ChefMaha

    How would I go around implementing this for several countries? (not just UAE)

    • Saleh G

      For multiple countries you have to tweak the jquery. Remove select.val == “AE” and the add a controller to get the cities based on country from the database.You have to add country / city database use ajax and get the cities based on countries.

  • Wajih

    Hi, can I use this code in Magento Go store, do they allow it?

  • Matteo

    Hi, I followed the directions in this article but I returns a
    PHP Fatal error: Class ‘Mage_Citydropdown_Helper_Data’ not found in /home/site/public_html/prova/app/Mage.php on line 547

    Why? What’s wrong?

    Thanks
    Matteo

  • Peter delgado

    I do Magento Drop Down cities list based on Provinces/Regions?