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!