2

I have a custom module app/code/Learning/FirstUnit/ and in that i have LayoutProcessor.php file in app/code/Learning/FirstUnit/Plugin.

Please see the below code in LayoutProcessor.php

<?php

namespace Learning\FirstUnit\Plugin;

use Magento\Directory\Helper\Data as DirectoryHelper;
use Magento\Directory\Model\ResourceModel\Country\CollectionFactory;
use Magento\Store\Model\StoreManagerInterface;
use function PHPUnit\Framework\assertIsCallable;

class LayoutProcessor
{

    public function afterProcess(
        \Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
        $result
    ) {
  
        //For shipping form
        $result['components']['checkout']['children']['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children']['city'] = [
            'component' => 'Magento_Ui/js/form/element/select',
            'config' => [
                'customScope' => 'shippingAddress',
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/select',
                'id' => 'drop-down',
            ],
            'dataScope' => 'shippingAddress.city',
            'label' => __('City'),
            'provider' => 'checkoutProvider',
            'visible' => true,
            'validation' => [],
            'sortOrder' => 70,
            'id' => 'drop-down',
            'options' => $this->getCitiesDropdown()
        ];

        //For Billing Form
        foreach ($result['components']['checkout']['children']['steps']['children']['billing-step']['children']
                 ['payment']['children']['payments-list']['children'] as $key => $payment) {
            if (isset($payment['children']['form-fields']['children']['city'])) {
                $result['components']['checkout']['children']['steps']['children']['billing-step']['children']
                ['payment']['children']['payments-list']['children'][$key]['children']['form-fields']['children']
                ['city'] = [
                    'component' => 'Magento_Ui/js/form/element/select',
                    'config' => [
                        'customScope' => 'shippingAddress',
                        'template' => 'ui/form/field',
                        'elementTmpl' => 'ui/form/element/select',
                        'id' => 'drop-down',
                    ],
                    'label' => __('City'),
                    'provider' => 'checkoutProvider',
                    'visible' => true,
                    'validation' => [],
                    'sortOrder' => 70,
                    'id' => 'drop-down',
                    'options' => $this->getCitiesDropdown()
                ];
            }
        }

        return $result;

    }

    public function getCitiesDropdown()
    {
        
        return [
        ['value' => "test1", "label" => "Test city 1", "is_default" => true], 
        ['value' => "test2", "label" => "Test city 2", "is_default" => false],
        ['value' => "test3", "label" => "Test city 3", "is_default" => false]
        ];
    }

}

This code is for to make the city field in checkout page as dropdown.

In getCitiesDropdown function I need to get the id of user selected country and region name that user type or selected . How can I get this .

I have custom table in database, so if I get the user typed region name then I will load the corresponding city name in the dropdown form that table.

Please help.

2 Answers 2

2

You cannot reach your goal through LayoutProcessor.php because in this way you define how your field will look like after it is rendered. So in your layout processor you should define the select default value (e.g. Please select country and/or region) and define a custom component for your city field.

Let's suppose that your custom component is Vendor_Module/js/city.js. You have to create city.js in Vendor/Module/view/frontend/web/js and put something like this inside

define([
    'underscore',
    'Magento_Ui/js/form/element/select'
], function (_, select) {
    'use strict';
    return select.extend({
        defaults: {
            skipValidation: false,
            imports: {
                country: '${ $.parentName }.country_id:value',
                region: '${ $.parentName }.region_id:value',
            }
        },

        country: function (value) {
            // this function is called whenever country value changes and 'value' is the
            // value of country field. You can put here the custom logic to update city select options depending on country field

        },

        region: function (value) {
            // this function is called whenever region value changes and 'value' is the
            // value of region field. You can put here the custom logic to update city select options depending on region field

        }

    });
});

You can create in those function the needed business logic to render the city options as you prefer

2
  • This will definitely help. But i need to make an sql call when ever region is changing. Where i have o add the sql call. Commented Sep 22, 2021 at 7:29
  • Not exactly! You could insert your mapping on checkout config and directly access on it without make any ajax call! Give a look on this magento.stackexchange.com/questions/174775/… Commented Sep 22, 2021 at 9:13
0

Making changes in the LayoutProcessor will not help you, for this, you will have to go into the KO.

For detail, I believe the solution mentioned in this link will help you.

How to change City field to a dropdown in Checkout step Magento 2

Other than that, there are few modules available over the git, which you can use for reference or modify as per your need, few are

https://github.com/php-cuong/magento2-regions-manager

https://github.com/EaDesgin/Magento2-City-Dropdown

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.