2

I need to add country and state drop down in admin form how to do it

9

in admin form block in _prepareForm() add country and region

that is

in __construct() add country config source

protected $_countryFactory;

    /**
     * @param \Magento\Backend\Block\Template\Context $context
     * @param \Magento\Framework\Registry $registry
     * @param \Magento\Framework\Data\FormFactory $formFactory
     * @param \Magento\Store\Model\System\Store $systemStore
     * @param array $data
     */
    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        \Magento\Framework\Registry $registry,
        \Magento\Framework\Data\FormFactory $formFactory,
        \Magento\Store\Model\System\Store $systemStore,
        \Magento\Cms\Model\Wysiwyg\Config $wysiwygConfig,
        \Magento\Directory\Model\Config\Source\Country $countryFactory,
        \Sugarcode\Test\Model\Status $status,
        array $data = []
    ) {
        $this->_systemStore = $systemStore;
        $this->_wysiwygConfig = $wysiwygConfig;
        $this->_status = $status;
        $this->_countryFactory = $countryFactory;
        parent::__construct($context, $registry, $formFactory, $data);
    }

and in _prepareForm()

     protected function _prepareForm()
        {
    .
    .
    .
    .
    .
    old field 
    .
    .
    .
    .
    $optionsc=$this->_countryFactory->toOptionArray();
            $country = $fieldset->addField(
                'country_id',
                'select',
                [
                    'name' => 'country_id',
                    'label' => __('Country'),
                    'title' => __('Country'),
               // 'onchange' => 'getstate(this)',
                    'values' => $optionsc,
                ]
            );
            //$optionsc=$this->_countryFactory->toOptionArray();
            $fieldset->addField(
                'region_id',
                'select',
                [
                    'name' => 'region_id',
                    'label' => __('Region'),
                    'title' => __('Region'),
                    'values' =>  ['--Please Select Country--'],
                ]
            );


         /*
            * Add Ajax to the Country select box html output
            */
      $country->setAfterElementHtml("   
            <script type=\"text/javascript\">
                    require([
                    'jquery',
                    'mage/template',
                    'jquery/ui',
                    'mage/translate'
                ],
                function($, mageTemplate) {
                   $('#edit_form').on('change', '#country_id', function(event){
                        $.ajax({
                               url : '". $this->getUrl('test/*/regionlist') . "country/' +  $('#country_id').val(),
                                type: 'get',
                                dataType: 'json',
                               showLoader:true,
                               success: function(data){
                                    $('#region_id').empty();
                                    $('#region_id').append(data.htmlconent);
                               }
                            });
                   })
                }

            );
            </script>"
        );
$form->setValues($model->getData());
        $this->setForm($form);

        return parent::_prepareForm();
    }

and create admin side action file to get region that is app\code\Sugarcode\Test\Controller\Adminhtml\Lists\Regionlist.php

<?php
/**
 *
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */

// @codingStandardsIgnoreFile

namespace Sugarcode\Test\Controller\Adminhtml\Lists;

/**
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class Regionlist extends \Magento\Framework\App\Action\Action
{
            /**
         * @var \Magento\Framework\View\Result\PageFactory
         */
        protected $resultPageFactory;
    /**
     * @var \Magento\Directory\Model\CountryFactory
     */
    protected $_countryFactory;

        /**
         * @param \Magento\Framework\App\Action\Context $context
         * @param \Magento\Framework\View\Result\PageFactory resultPageFactory
         */
        public function __construct(
            \Magento\Framework\App\Action\Context $context,
            \Magento\Directory\Model\CountryFactory $countryFactory,
            \Magento\Framework\View\Result\PageFactory $resultPageFactory
        )
        {
            $this->_countryFactory = $countryFactory;
            $this->resultPageFactory = $resultPageFactory;
            parent::__construct($context);
        }
    /**
     * Default customer account page
     *
     * @return void
     */
    public function execute()
    {


        $countrycode = $this->getRequest()->getParam('country');
        $state = "<option value=''>--Please Select--</option>";
        if ($countrycode != '') {
            $statearray =$this->_countryFactory->create()->setId(
                    $countrycode
                )->getLoadedRegionCollection()->toOptionArray();
            foreach ($statearray as $_state) {
                if($_state['value']){
                    $state .= "<option >" . $_state['label'] . "</option>";
            }
           }
        }
       $result['htmlconent']=$state;
         $this->getResponse()->representJson(
            $this->_objectManager->get('Magento\Framework\Json\Helper\Data')->jsonEncode($result)
        );
    } 

  }

once you change country region will load same way you can do for city also

If any one know better then this solution as like in we use in edit.phtml please share us

  • If you must add CouplingBetweenObjects, you do something wrong – user32135 Nov 12 '15 at 12:54
  • @AntonOhorodnyk:- can you tell me how ? what is CouplingBetweenObjects and how to do it – Pradeep Kumar Nov 13 '15 at 3:32
  • CouplingBetweenObjects - it's when two objects have dependency each other – user32135 Nov 13 '15 at 8:34
  • @AntonOhorodnyk:- i am blank about that can you tell me how to use in this situation country region in future i will have one more city dropdown based on region based on your inputs i can develop that also so please help in that – Pradeep Kumar Nov 13 '15 at 9:28
  • I have used above code for display country and region drop down but if I select country which have not region for Magento, region drop down display as blank. Any solution for that? – Suresh Chikani May 31 '17 at 7:23
1

In the block constructor, you'll need to enable two classes with the collection of regions and countries. Also, don't forget to add the corresponding fields in there.

Next, apply the standard RegionUpdater from lib/web/varien/form.js. it can be added in any convenient for you way - in our example we're using a child block with the template where it is called (just note that there're some required parameters: country elements, region (text), region (select) and the object that contains data for countries and regions (from the Helper directory).

In case you need to modify the list of countries and regions, do that not only in the form , but also in the data object from RegionUpdater.

Changes in the class of the form block, add new classes to di, the __construct method and make changes to the _prepareForm method.

<?php
/**
 * @var \Magento\Directory\Model\Config\Source\Country
 */
protected $_country;

/**
 * @var \Magento\Directory\Model\RegionFactory
 */
protected $_regionFactory;

// ... add them in __construct

// ...

// Add next changes in the _prepareForm method

$countries = $this->_country->toOptionArray(false, 'US');
$regionCollection = $this->_regionFactory->create()->getCollection()->addCountryFilter(
    $formData['country_id']
);
$regions = $regionCollection->toOptionArray();

$fieldset->addField(
    'country_id',
    'select',
    ['name' => 'country_id', 'label' => __('Country'), 'required' => true, 'values' => $countries]
);

$fieldset->addField(
    'region_id',
    'select',
    ['name' => 'region_id', 'label' => __('State'), 'values' => $regions]
);

$fieldset->addField(
    'region',
    'text',
    ['name' => 'region', 'label' => __('Region')]
);

$fieldset->addField(
    'city',
    'text',
    ['name' => 'city', 'label' => __('City')]
);

$this->setChild(
    'form_after',
    $this->getLayout()->createBlock('Magento\Framework\View\Element\Template')->setTemplate('Vendor_Module::js.phtml')
);
?>

> Vendor_Module::js.phtml

<script>
    require([
        "jquery",
        "mage/adminhtml/form"
    ], function ($) {

        var updater = new RegionUpdater($('[name=country_id]')[0], $('[name=region]')[0], $('[name=region_id]')[0],
            <?php echo $this->helper('Magento\Directory\Helper\Data')->getRegionJson() ?>,
            'hide'
        );
        updater.disableRegionValidation();
        window.updater = updater;
    });
</script>

This is how it works:

1) by default

enter image description here

2) After you select the USD, the text field for the region is hidden (the 5th argument RegionUpdater constructor - this method will be applied to any inactive fields, also it can be hidden or disabled)

enter image description here

3) For Albania, there're no regions by default. Hence, we can see just the text field with hidden regions:

enter image description here

4) For Switzerland, we can see the regions again:

enter image description here

And it it goes without saying that you should make it convenient to use for your clients, as using the Hide method, the filed label is NOT hidden.

But upon the whole, RegionUpdater works well for a non-UI forms of Magento.

P.S. Also note that there's no way to add an updater for cities,as by default, Magento doesn't support the lists of Cities.

0

You can try using/replicationg the Config module's way.

Add the js.phtml block, that's also used in the shipping origin config, to your layout xml.

    <referenceContainer name="js">
        <block class="Magento\Backend\Block\Template" template="Magento_Config::system/config/js.phtml"/>
    </referenceContainer>

Name your field ids as "country_id" and "region_id" and add "countries" css class to the country_id field.

$fieldset->addField(
    'country_id',
    'select',
    [
        'name'  => 'country_id',
        'label' => __('Country'),
        'title' => __('Country'),
        'values' => array_merge(['' => ''], $this->_countryOptions->toOptionArray()),
        'class' => 'countries',
    ]
);
$fieldset->addField(
    'region_id',
    'text',
    [
        'name'  => 'region_id',
        'label' => __('Region/State'),
        'title' => __('Region/State'),
    ]
);

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.