Magento: How to remove certain States from state/region list at Checkout or registration.
April 29th, 2010 in Web Development, E-Commerce
Magento is an e-commerce platform that supports multi-language and all that multi stuff. Therefore list of Regions per country is perfectly legal. The list of regions for USA contains: Alaska, Hawaii, American Samoa, Guam, Marshall Islands, Micronesia and Armed American Forces all over the world. This is the list that is available both during registration and on checkout. There are a lot of store owners/developers/designers who want to remove some of the items from that list. Why?
Plenty of reasons:
- e-commerce store offers free shipping and doesn't want to ship to Guam for free.
- risk of items not being delivered, problems in shipping.
- Simply to shorten that drop-down region list.
- or... simply store owner just doesn't want to ship to.. say, Alabama.
How most of people approach this task. Well.. most people, in order to avoid those regions being listed, go to phpMyAdmin magento database and manually delete all of those region id's and such. I don't think this is the best way to go, as upon upgrade, you'll get those states back in the region list.
Here's a different approach of removing 'unwanted' states from magento region list. Simply override Region collection, so that those codes are being filtered out. Here's what to do:
- copy file at <magento installation>/app/code/core/Mage/Directory/Model/Mysql4/Region/Collection.php to your local code directory at <magento installation>/app/code/local/Mage/Directory/Model/Mysql4/Region/Collection.php
- change this line of code (around line 50):
$this->_select->from(array('region'=>$this->_regionTable),
array('region_id'=>'region_id', 'country_id'=>'country_id', 'code'=>'code', 'default_name'=>'default_name')
);
- to this:
$exclude_regions = array ('AS','AK','AA','AC','AE','AK','AM','AP','FM','GU','HI','MH','MP','PW','PR','VI','AF');
$this->_select->from(array('region'=>$this->_regionTable),
array('region_id'=>'region_id', 'country_id'=>'country_id', 'code'=>'code', 'default_name'=>'default_name')
)
->where('code NOT IN (?)', $exclude_regions);
This filters out a lot of unnecessary states from query and doesn't show them on front-end of magento. In addition, you can remove any other states you want, just look up codes in the magento DB.
![]() |
Timur Information Architect |
Comments (9)
Hey, but will it work after upgrading your mage installation? looks like core patching to me. I'm no pro at magento but filepath looks like it will be upgraded during install.
by Rinat Khaziev - 05/01/2010 @ 03:23am
It's in /app/code/local/ so it won't be updated. Local code. thanks.
by Timur - 05/01/2010 @ 11:03pm
A better but longer way would be to extend it and only overwrite the __contruct method. That way if there ever was changes/upgrades to other methods in this class your class would not override everything. When in doubt extend not override.
by Justin - 11/03/2010 @ 03:30pm
Great post! Is there a way to do this with countries also?
by Phil - 01/05/2011 @ 03:12pm
Thanks man!!! it really helped.
by Shashikant Arya - 02/18/2011 @ 01:54am
Hey here is a Magento way of getting only the us states. Hope my code shows up.
public function getStatesCollection()
{
$collection = $this->getData(\'state_collection\');
if (is_null($collection)) {
$exclude_regions = array (\'AS\',\'AK\',\'AA\',\'AC\',\'AE\',\'AK\',\'AM\',\'AP\',\'FM\',\'GU\',\'HI\',\'MH\',\'MP\',\'PW\',\'PR\',\'VI\',\'AF\');
$collection = Mage::getModel(\'directory/region\')->getResourceCollection()
->addCountryFilter(\'US\')
->addFieldToFilter(\'code\', array(\'nin\' => $exclude_regions))
->addOrder(\'default_name\', \'asc\')
->load();
$this->setData(\'state_collection\', $collection);
}
return $collection;
}
by Mike D - 03/16/2011 @ 04:27pm
THX for sharing
by milano abercrombie - 06/09/2011 @ 06:52am
Excellent workaround, it took me a while to remember to go into the magento admin section and re-index/refresh cache so this would show up correctly (without unwanted States).
Also I found the State IDs in magento db under directory_country_region which took me a while to find too.
Nice.
by Matthew - 06/29/2011 @ 03:54pm
Has anyone implemented this in 1.6? The collection has changed.
by Jamie - 10/14/2011 @ 05:18pm