Magento – Magento 2.2: How to add country and region drop-downs in a custom step form in one page checkout

drop-downsknockoutjsmagento2onepage-checkoutshipping-address

I need to add a custom step in Magento which verifies the address of the customer via a third party API, the fields are similar to the shipping address form, but I could not find out how the country and region drop-downs are added from the core files.

The fields in the shipping form are set from the checkout_index_index.xml, and displayed using the knockout for each loop, but I could not do the same.

Thanks

EDIT
I have added the country_id, region, and region_id fields using layout xml, but it adds text box instead of the drop-down.

Best Answer

To add the dropdowns in your custom module for checkout. You can use /vendor/magento/module-checkout/Block/Checkout/DirectoryDataProcessor.phpas reference.

You need to create a plugin for the \Magento\Checkout\Block\Checkout\DirectoryDataProcessor::process method. In your plugin, implement the after method adding the option data to the corresponding layout nodes at run-time.

Create di.xml to declare the plugin

<?xml version='1.0'?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd" >
    <type name="Magento\Checkout\Block\Checkout\DirectoryDataProcessor">
        <plugin name='customDropdownPlugin' type='VendorName\ModuleName\Plugin\Block\Checkout\DirectoryDataProcessorPlugin' sortOrder='999'/>
    </type>
</config>

Create VendorName\ModuleName\Plugin\Block\Checkout\DirectoryDataProcessorPlugin.php

<?php
namespace VendorName\ModuleName\Plugin\Block\Checkout;


class DirectoryDataProcessorPlugin
{
    /**
     * @param \Magento\Checkout\Block\Checkout\DirectoryDataProcessor $subject
     * @param array $jsLayout
     * @return array
     */
    public function afterProcess(
        \Magento\Checkout\Block\Checkout\DirectoryDataProcessor $subject,
        array  $jsLayout
    ) {
        if (isset($jsLayout['components']['checkoutProvider']['dictionaries'])) {
            $jsLayout['components']['checkoutProvider']['dictionaries'] = [
                'custom_country_id' => $subject->getCountryOptions(),
                'custom_region_id' => $subject->getRegionOptions(),
            ];
        }

        return $jsLayout;
    }
}

Here you need to replace custom_cuntry_id and custom_region_id with your fileds respectively.

Also check your attribute you have created must be of type select in eav_attribute table for customer address entity.