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!