Magento – Magento2: How to display country and region drop down fields to admin form in Magento2

adminformcountry-regionsmagento2

I am developing a custom admin module. I have displayed country and region in admin custom module. It is working when I add country and region. But it is not working with edit action.

How I can show country and region which already saved in edit action?

I have Used below code for that in form _prepareForm()

$country = $fieldset->addField(
$field['fields'],
'select',
[
    'name' => $field['fields'],
    'label' => __('Country'),
    'title' => __('Country'),
    'values' => $optionsc,
    'required' => $require
]
);*/

$fieldset->addField(
'region_id',
'select',
[
    'name' => 'region_id',
    'label' => __('State'),
    'title' => __('State'),
    'values' => ['Please select a region, state or province'],
    'required' => $require
]
);

$fieldset->addField(
'region',
'text', ['name' => 'region', 'label' => __('State'), 'title' => __('State'), 'display' => 'none']
);

/*
* 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) {
       $('.field-region').hide();
        $(document).ready(function(){

            $('#item_country').bind('change', function () {
                $.ajax({
                   url : '" . $this->getUrl('b2b_company/lists/regionlist') . "country/' +  $('#item_country').val(),
                   type: 'get',
                   showLoader:true,
                   dataType: 'json',
                   success: function(data){
                        if(data.htmlconent == false){
                            console.log('two');
                            $('.field-region_id').css('display', 'none');
                            $('.field-region').css('display', 'block');
                        } else {
                            $('.field-region').css('display', 'none');
                            $('.field-region_id').css('display', 'block');
                            $('#item_region_id').empty();
                            $('#item_region_id').append(data.htmlconent);
                        }
                   }
                });
            });
            $('#item_country').trigger('change');
        });
    }

);
</script>"

Also I am trying it with : Another Solution but it has used $formData array but not define any where.

Thanks You.

Best Answer

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.

Related Topic