cancel
Showing results for 
Search instead for 
Did you mean: 

How to set region value in checkout page?

How to set region value in checkout page?

I am following this guide to build a zipcode lookup implementation.
I try to populate region, city and street data based on zipcode.

this.region().value(regionValue);
this.city().value(cityValue);
this.street().elems()[0].set('value', streetValue);

With code above, city and street fields successfully changed when I type zipcode but no for region field.
Is there any different implementation for region field?
Here is my fullcode:

LayoutProcessor.php

<?php

namespace Vendor\Module\Block\Checkout;

class LayoutProcessor
{
    /**
     * Checkout LayoutProcessor after process plugin.
     *
     * @param \Magento\Checkout\Block\Checkout\LayoutProcessor $processor
     * @param array $jsLayout
     * @return array
     */
    public function afterProcess(\Magento\Checkout\Block\Checkout\LayoutProcessor $processor, $jsLayout)
    {
        $shippingConfiguration = &$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
            ['children']['shippingAddress']['children']['shipping-address-fieldset']['children'];
        $billingConfiguration = &$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']
        ['children']['payment']['children']['payments-list']['children'];

        //Checks if shipping step available.
        if (isset($shippingConfiguration)) {
            $shippingConfiguration = $this->processAddress(
                $shippingConfiguration,
                'shippingAddress',
                [
                    'checkoutProvider',
                    'checkout.steps.shipping-step.shippingAddress.shipping-address-fieldset.city',
                    'checkout.steps.shipping-step.shippingAddress.shipping-address-fieldset.street',
                    'checkout.steps.shipping-step.shippingAddress.shipping-address-fieldset.region_id'
                ]
            );
        }

        //Checks if billing step available.
        if (isset($billingConfiguration)) {
            //Iterate over billing forms.
            foreach($billingConfiguration as $key => &$billingForm) {
                //Exclude not billing forms
                if (!strpos($key, '-form')) {
                    continue;
                }

                $billingForm['children']['form-fields']['children'] = $this->processAddress(
                    $billingForm['children']['form-fields']['children'],
                    $billingForm['dataScopePrefix'],
                    [
                        'checkoutProvider',
                        'checkout.steps.billing-step.payment.payments-list.' . $key . '.form-fields.city',
                        'checkout.steps.billing-step.payment.payments-list.' . $key . '.form-fields.street',
                        'checkout.steps.billing-step.payment.payments-list.' . $key . '.form-fields.region_id'
                    ]
                );
            }
        }

        return $jsLayout;
    }

    /**
     * Process provided address to contains checkbox and have trackable address fields.
     *
     * @param $addressFieldset - Address fieldset config.
     * @param $dataScope - data scope
     * @param $deps - list of dependencies
     * @return array
     */
    private function processAddress($addressFieldset, $dataScope, $deps)
    {
        //Creates input field.
        $addressFieldset['postcode'] = [
            'component' => 'Vendor_Module/js/input',
            'config' => [
                'customScope' => $dataScope,
                'template' => 'ui/form/field',
                'elementTmpl' => 'ui/form/element/input',
            ],
            'dataScope' => $dataScope . '.postcode',
            'deps' => $deps,
            'label' => __('My label'),
            'provider' => 'checkoutProvider',
            'visible' => true,
            'sortOrder' => 71,
            'validation' => [
               'required-entry' => true
            ],
        ];

        //Makes each address field label trackable.
        if (isset($addressFieldset['street']['children'])) {
            foreach($addressFieldset['street']['children'] as $key => $street) {
                $street['tracks']['label'] = true;
                //Remove .additional class. Can be removed, but style fix provided instead.
                $street['additionalClasses'] = '';
                $addressFieldset['street']['children'][$key] = $street;
            }
        }

        return $addressFieldset;
    }
}

input.js

define([
  'Magento_Ui/js/form/element/abstract',
  'mage/translate'
], function (AbstractField, $t) {
  'use strict';

  return AbstractField.extend({
      defaults: {
          modules: {
            region: '${ $.parentName }.region_id',
            city: '${ $.parentName }.city',
            street: '${ $.parentName }.street',
          }
      },

      populateData: function () {
          if (this.value()?.length >= 7) {
            const nameFile = this.value().substr(0, 3);
            fetch(`https://domain.tld/data/${nameFile}.js`)
              .then(response => {
                if (response.ok) {
                  return response.json();
                }
                return Promise.reject(response);
              })
              .then(data => {
                const prefectures = [
                  null,
                  '北海道',
                  '青森県',
                  '岩手県',
                  '宮城県',
                  '秋田県',
                  '山形県',
                  '福島県',
                  '茨城県',
                  '栃木県',
                  '群馬県',
                  '埼玉県',
                  '千葉県',
                  '東京都',
                  '神奈川県',
                  '新潟県',
                  '富山県',
                  '石川県',
                  '福井県',
                  '山梨県',
                  '長野県',
                  '岐阜県',
                  '静岡県',
                  '愛知県',
                  '三重県',
                  '滋賀県',
                  '京都府',
                  '大阪府',
                  '兵庫県',
                  '奈良県',
                  '和歌山県',
                  '鳥取県',
                  '島根県',
                  '岡山県',
                  '広島県',
                  '山口県',
                  '徳島県',
                  '香川県',
                  '愛媛県',
                  '高知県',
                  '福岡県',
                  '佐賀県',
                  '長崎県',
                  '熊本県',
                  '大分県',
                  '宮崎県',
                  '鹿児島県',
                  '沖縄県',
                ];

                const regionValue = data[0].hasOwnProperty(this.value()) ? prefectures[data[0][this.value()][0]] : '';
                const cityValue = data[0].hasOwnProperty(this.value()) ? data[0][this.value()][1] : '';
                const streetValue = data[0].hasOwnProperty(this.value()) ? data[0][this.value()][2] : '';
                this.region().value(() => regionValue);
                this.city().value(cityValue);
                this.street().elems()[0].set('value', streetValue);
              })
              .catch(error => console.warn(error))
          } else {
            this.region().value('');
            this.city().value('');
            this.street().elems()[0].set('value', '');
          }
      },

      setDifferedFromDefault: function () {
          this._super();
          this.populateData();
      }
  });
});

Any idea what's wrong with my implementation to set auto-filled region value?

Regards.