How to Create Country & State Dropdown in Magento 2 Custom Frontend Form

img How to Create Country State Dropdown in Magento 2 Custom Frontend Form

Understanding that each business is different with unique requirements. Each store owner has his own needs for their web stores in order to provide better shopping experience. When a store is created for some specific countries or location and when admin needs to have some custom form, he needs to have it with selection options rather than text boxes in order to minimize users’ efforts to fill in and maximize their experience.While working on our client’s Magento 2 store, we required to have two selection boxes; one for countries and other for states selection. As the selection options are generally presented with dropdown, we choose to add 2 dropdowns to serve the purpose. To Create Country and State Dropdown in Magento 2 Custom Frontend Form, we implemented a custom code which I’m sharing with you today.

First create a file “index.php” at app\code\local\Vendor\Extension\Block with below code.

<?php
namespace Vendor\Extension\Block;
 
class Index extends \Magento\Framework\View\Element\Template
{
    protected $directoryBlock;
    protected $_isScopePrivate;
    
    public function __construct(
         	\Magento\Framework\View\Element\Template\Context $context,
         	\Magento\Directory\Block\Data $directoryBlock,
         	array $data = []
        	)
        	{
         	parent::__construct($context, $data);
         	$this->_isScopePrivate = true;
         	$this->directoryBlock = $directoryBlock;
        	}
 
        	public function getCountries()
        	{
         	$country = $this->directoryBlock->getCountryHtmlSelect();
         	return $country;
        	}
        	public function getRegion()
        	{
         	$region = $this->directoryBlock->getRegionHtmlSelect();
         	return $region;
        	}
        	 public function getCountryAction()
        	{
         	return $this->getUrl('extension/extension/country', ['_secure' => true]);
        	}
    
    
}

Now, you need to create another file at app\code\local\Vendor\Extension\view\frontend\layout\ with following code and rename it as “extension_extension_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
        	<head>
         	<title>extension</title>
        	</head>
     <body>    	
         	<referenceContainer name="content">                 	
                    	 <block class="Vendor\Extension\Block\Index" name="extension" template="extension/index.phtml">
                    	 </block>
         	</referenceContainer>       	 
        	</body>
</page>

Now create “index.phtml” with following code at app\code\local\Vendor\Extension\view\frontend\templates\extension

<?php
$countryList=$block->getCountries();
$regionList=$block->getRegion();  ?>
<form class="form retuns"
         	action="<?php /* @escapeNotVerified */ echo $block->getFormAction(); ?>"
         	id="return-form"
         	method="post"
         	data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>"
         	data-mage-init='{"validation":{}}'>
 
        	<div class="field country required">
                       	<label class="label" for="country"><span><?php /* @escapeNotVerified */ echo __('Country') ?></span></label>
                       	<div class="control">
                                   	<?php echo $countryList?>
                       	</div>
               </div>
 
        	 <div class="field region required">
                      	<label class="label" for="state"><span><?php /* @escapeNotVerified */ echo __('State') ?></span></label>
                      	<div class="control">
                       	<?php echo $regionList?>
                      	</div>
                      	</div>
                      	
                      	
                      	<div class="field states required" style="display:none">
                      	<label class="label" for="states"><span><?php /* @escapeNotVerified */ echo __('State') ?></span></label>
                      	<div class="control">
                       	<input name="state" id="states" title="<?php /* @escapeNotVerified */ echo __('State') ?>"  class="input-text" type="text" />
                      	</div>
                      	</div>
 
</form>
 
<script>
        	jQuery(document).on('change','#country',function() {
        	 var param = 'country='+jQuery('#country').val();
        	 jQuery.ajax({
                    	 showLoader: true,
                    	 url: '<?php /* @escapeNotVerified */ echo $block->getCountryAction(); ?>',
                    	 data: param,
                    	 type: "GET",
                    	 dataType: 'json'
        	 }).done(function (data) {
                    	 jQuery('#state').empty();
                    	 if(data.value=='')
                    	 {
                                	 jQuery('.field.states.required').show();
                                	 jQuery('.field.region.required').hide();
                    	 }
                    	 else
                    	 {
                     	 jQuery('#state').append(data.value);
                                	 jQuery('.field.states.required').hide();
                                	 jQuery('.field.region.required').show();
                    	 }
        	 });
    });
</script>

Lastly, you need to create “Country.php” in your extension folder at app\code\local\Vendor\Extension\Controller\Extension\ with following code.

<?php
namespace Vendor\Extension\Controller\Extension;
 
class Country extends \Magento\Framework\App\Action\Action
{
        	protected $resultJsonFactory;
    
    protected $regionColFactory;
 
        	public function __construct(
         	\Magento\Framework\App\Action\Context $context,
         	\Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
         	\Magento\Directory\Model\RegionFactory $regionColFactory)
    {    	
         	$this->regionColFactory     	= $regionColFactory;
         	$this->resultJsonFactory     	= $resultJsonFactory;
         	parent::__construct($context);
        	}
 
        	public function execute()
        	{
         	$this->_view->loadLayout();
         	$this->_view->getLayout()->initMessages();
         	$this->_view->renderLayout();
 
         	$result          	= $this->resultJsonFactory->create();
         	$regions=$this->regionColFactory->create()->getCollection()->addFieldToFilter('country_id',$this->getRequest()->getParam('country'));
        	
        	 $html = '';
        	
        	 if(count($regions) > 0)
        	 {
                    	 $html.='<option selected="selected" value="">Please select a region, state or province.</option>';
                    	 foreach($regions as $state)
                    	 {
                                	 $html.=    '<option  value="'.$state->getName().'">'.$state->getName().'.</option>';
                    	 }
        	 }
        	 return $result->setData(['success' => true,'value'=>$html]);
   }
}

Adding country and state dropdowns in Magento 2 custom form is not rocket science, it’s as easy pie! Simply modify above code according to your custom fields and options, paste in your custom form and voila, you are done! I hope the code has enough served your purpose to implement country and state dropdown in Magento 2.
Let me know how did you customize the code and where have you used it. Also, tell me if you stuck somewhere and need help.

Don’t forget to flash out the 5 stars below if you like the tutorial.
Happy Coding!

CityRegion Manager

Previous Article

How to Get Number of Product Reviews & Average Ratings Programmatically in Magento

Next Article

How to Create Dependent Dropdowns in Magento 2 Frontend Form

Write a Comment
  1. Hello, I am new to magento, integrate your code into a project, I am only adding the country

    I got an error:

    Undefined variable: countryList in …/Morwi/Registro/view/frontend/templates/registro.phtml on line 17

    –Saludos

  2. Hello, I am new to magento, integrate your code into a project, I am only adding the country

    I got an error:

    Undefined variable: countryList in …/Morwi/Registro/view/frontend/templates/registro.phtml on line 17

    –Saludos

    1. You need to add this line in your phtml file.
      < ?php $countryList=$block->getCountries();
      $regionList=$block->getRegion(); ?>

      We have updated our blog too.

    1. For the checkout page, you need to implement it differently, because checkout is created with the use of knockout js. We will see if we can write a blog for the same.

  3. hello i am using above your code.but when I am selected country UK to USA then dropdown value not working

  4. Please is there any changes i should make if i want to store the country and state value in a database

Leave a Comment

Your email address will not be published. Required fields are marked *

Get Connect With Us

Subscribe to our email newsletter to get the latest posts delivered right to your email.
Pure inspiration, zero spam ✨