Skip to content

How to Show/Hide a Field in Magento 2 Checkout Based on the Preselected Shipping Address?

I am developing a Magento 2 module that adds a VAT field to the checkout, below the list of shipping addresses. The field should only be visible if the selected address does not have a **vat_id**.

  • The field is added via the Layout Processor, specifically in
    address-list-additional-addresses.

  • A JavaScript script handles its visibility, displaying it when
    necessary.

⚠️ Issue:
The field should be hidden by default and only appear if the selected address does not contain vat_id, when I manually switch between addresses, the field correctly shows/hides as expected, but when the preselected address when loading the checkout does not have a vat_id, the VAT field does not appear on checkout load, even though the console logs confirm that the visibility logic is being executed.

🔍 What I Have Tried

  • console.log confirms that toggleVatField() executes correctly and
    detects whether VAT should be shown or hidden.

  • The function works when manually changing addresses, but not on
    initial page load.

  • I tried forcing display: block with .css(‘display’, ‘block’), but it
    does not work.

  • The quote.shippingAddress() object correctly shows vatId: null when
    applicable.

app/code/Vendor/RequireVat/Plugin/Checkout/LayoutProcessorPlugin.php

<?php
declare(strict_types=1);

namespace VendorRequireVatPluginCheckout;

use MagentoCheckoutBlockCheckoutLayoutProcessorInterface;
use VendorRequireVatModelValidator;

class LayoutProcessorPlugin
{
    private Validator $validator;

    public function __construct(Validator $validator)
    {
        $this->validator = $validator;
    }

    public function afterProcess(LayoutProcessorInterface $subject, array $jsLayout): array
    {
        $vatRequired = $this->validator->isVatRequired();

        $shippingAddress = &$jsLayout['components']['checkout']['children']
        ['steps']['children']['shipping-step']['children']
        ['shippingAddress']['children']['shipping-address-fieldset']['children'];

        $billingStep = &$jsLayout['components']['checkout']['children']
        ['steps']['children']['billing-step']['children']
        ['payment']['children']['payments-list']['children'];

        // Remove the field if VAT is not required
        if (!$vatRequired) {
            if (isset($shippingAddress['vat_id'])) {
                unset($shippingAddress['vat_id']);
            }

            foreach ($billingStep as &$paymentMethod) {
                if (isset($paymentMethod['children']['form-fields']['children']['vat_id'])) {
                    unset($paymentMethod['children']['form-fields']['children']['vat_id']);
                }
            }
        } else {
            if (isset($shippingAddress['vat_id'])) {
                $shippingAddress['vat_id']['validation']['required-entry'] = true;
            }

            foreach ($billingStep as &$paymentMethod) {
                if (isset($paymentMethod['children']['form-fields']['children']['vat_id'])) {
                    $paymentMethod['children']['form-fields']['children']['vat_id']['validation']['required-entry'] = true;
                }
            }

            // Add VAT field after address list
            $customVatField = [
                'component' => 'Magento_Ui/js/form/element/abstract',
                'config' => [
                    'customScope' => 'shippingAddress',
                    'template' => 'ui/form/field',
                    'elementTmpl' => 'ui/form/element/input',
                    'id' => 'vat_id'
                ],
                'dataScope' => 'shippingAddress.vat_id',
                'label' => __('VAT Number'),
                'provider' => 'checkoutProvider',
                'sortOrder' => 250,
                'validation' => ['required-entry' => false],
                'visible' => false,
                'additionalClasses' => 'custom-vat-field'
            ];

            $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
            ['shippingAddress']['children']['address-list-additional-addresses']['children']['vat_id'] = $customVatField;
        }

        return $jsLayout;
    }
}

app/code/Vendor/RequireVat/view/frontend/web/js/view/vat-visibility.js

define([
    'jquery',
    'Magento_Checkout/js/model/quote',
    'Magento_Checkout/js/action/select-shipping-address'
], function ($, quote, selectShippingAddressAction) {
    'use strict';

    console.log('✅ vat-visibility.js is running');

    function toggleVatField() {
        var selectedAddress = quote.shippingAddress();

        if (!selectedAddress) {
            console.log('⚠️ Address not loaded yet, waiting...');
            return;
        }

        console.log('🔄 toggleVatField executed');
        console.log('🛒 Selected address:', selectedAddress);

        if (!selectedAddress.vatId) {
            console.log('❗ Showing VAT field');
            $('.custom-vat-field').closest('.field').show();
            $('.custom-vat-field').attr('required', 'required');
            // Ensure display is set correctly
            $('.custom-vat-field').closest('.field').css('display', 'block');
        } else {
            console.log('✅ Hiding VAT field');
            $('.custom-vat-field').closest('.field').hide();
            $('.custom-vat-field').removeAttr('required');
        }
    }

    function waitForAddressLoad() {
        var checkAddress = setInterval(function () {
            if (quote.shippingAddress() && quote.shippingAddress().postcode) {
                console.log('✅ Address loaded:', quote.shippingAddress());
                clearInterval(checkAddress);
                toggleVatField();
            }
        }, 500);
    }

    // **Wait for Magento to load the preselected address**
    $(document).ready(function () {
        console.log('🚀 Page loaded');
        waitForAddressLoad();
    });

    // **Execute when the user manually changes the address**
    quote.shippingAddress.subscribe(function () {
        console.log('📌 Address changed');
        toggleVatField();
    });

    return {};
});

Any help and info would be greatly appreciated! Thanks in advance!