How to add new fields in address form

The Magento 2 shipping address form is where customers provide their shipping details, such as name, address, and contact information. This information is necessary to determine where to send the purchased items. It helps us calculate shipping costs, estimate delivery times, and ensure timely delivery. Magento 2 provides a default shipping address form as part of its standard checkout process.

However, Magento 2 stores might need different information from customers that the existing fields in Magento default forms do not support. Luckily, in default checkout forms of Magento 2, you are given the power to add new fields such as shipping address and billing address forms. In today’s post, I’m going to show you five simple steps on how to add a new field in the address form.


SVG

One Step Checkout for Magento 2

Cut down 80% of checkout time & increase 30% of conversion rates (Hyva ready)

Check it out!


6 Steps to add new fields in an address form in Magento 2:

Step 1: Add field to layout

As both shipping address and billing address forms in Magento 2 are created dynamically, to customize their layouts, you need to create a plugin for the method \Magento\Checkout\Block\Checkout\LayoutProcessor::process and then declare it in the di.xml file which is in your module.

Here is a sample code for adding a Custom Attribute field to the Magento 2 shipping address form:

<?php
$customAttributeCode = 'custom_field';
$customField = [
    'component' => 'Magento_Ui/js/form/element/abstract',
    'config' => [
        // customScope is used to group elements within a single form (e.g. they can be validated separately)
        'customScope' => 'shippingAddress.custom_attributes',
        'customEntry' => null,
        'template' => 'ui/form/field',
        'elementTmpl' => 'ui/form/element/input',
        'tooltip' => [
            'description' => 'this is what the field is for',
        ],
    ],
    'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
    'label' => 'Custom Attribute',
    'provider' => 'checkoutProvider',
    'sortOrder' => 0,
    'validation' => [
       'required-entry' => true
    ],
    'options' => [],
    'filterBy' => null,
    'customEntry' => null,
    'visible' => true,
];

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

In this example, the field is added to the customAttributes property of Magento_Checkout/js/model/new-customer-address.js, which is a JavaScript object listing all predefined address attributes and matching the corresponding server-side interface \Magento\Quote\Api\Data\AddressInterface.

The customAttributes property is related to the method \Magento\Quote\Model\Quote\Address\CustomAttributeListInterface::getAttributes. Besides, it was designed to hold custom EAV address attributes. The sample code that I have just provided above will help you handle storage persistence on the frontend automatically.

However, instead of adding a plugin, there is another way which is using a dependency injection also known as DI. In order to use a DI, you need to add the LayoutProcessor, that adds the custom field to the address form class, to directory <your_module_dir>/Block/Checkout/. The \Magento\Checkout\Block\Checkout\LayoutProcessorInterface interface must be implemented by the class. The code sample can be used as an example of the method implementation \Magento\Checkout\Block\Checkout\LayoutProcessorInterface::process().

For the LayoutProcessor class to be added to the corresponding pool of processors, you need to specify the following code (in here, you need to replace %unique_name% and %path\to\your\LayoutProcessor% by your real value) in the <your_module_dir>/etc/frontend/di.xml file:

<type name="Magento\Checkout\Block\Onepage">
        <arguments>
            <argument name="layoutProcessors" xsi:type="array">
                <item name="%unique_name%" xsi:type="object">%path\to\your\LayoutProcessor%</item>
            </argument>
        </arguments>
</type>

Step 2: Add JS mixin to modify data submission

To change the component responsible behavior for the data submission, add a JS mixin to the server side.

First of all, in your custom module, you need to define a mixin as a separate AMD module which returns a callback function. The mixin file can be added anywhere as long as it is in the <your_module_dir>/view/frontend/web directory. You can also freely name the file as you want.

Below is a sample mixin code which modifies the Magento_Checkout/js/action/set-shipping-information’s behavior. The component is responsible for data submission between two steps shipping and billing:

/*jshint browser:true jquery:true*/
/*global alert*/
define([
    'jquery',
    'mage/utils/wrapper',
    'Magento_Checkout/js/model/quote'
], function ($, wrapper, quote) {
    'use strict';

    return function (setShippingInformationAction) {

        return wrapper.wrap(setShippingInformationAction, function (originalAction) {
            var shippingAddress = quote.shippingAddress();
            if (shippingAddress['extension_attributes'] === undefined) {
                shippingAddress['extension_attributes'] = {};
            }

            shippingAddress['extension_attributes']['custom_field'] = shippingAddress.customAttributes['custom_field'];
            // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
            return originalAction();
        });
    };
});

When the field is added to the billing address form, the Magento_Checkout/js/action/place-order or Magento_Checkout/js/action/set-payment-information component’s behaviour need to be modified according to the time when you need the custom field valued to be passed to the server side.

If you want to view an example of a mixing which modifies a component, view the place-order-mixin.js which is in the Magento_CheckoutAgreements module.

Step 3: Load mixin

By adding the requirejs-config.js to the <YourModule_dir>/view/frontend/ directory, you will be able to tell Magento to load your mixin for the corresponding JS component.

Below is an example which use the sample mixin which is added earlier:

var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/action/set-shipping-information': {
                '<YourNamespace_YourModule>/js/action/set-shipping-information-mixin': true
            }
        }
    }
};

Step 4: Add field to address model

In this stage, you would need to add the extension_attributes.xml file in the <YourModule_dir>/etc/ directory in order to add a field to the address model which is on the Magento 2 server side.

Following is an extension_attributes.xml file’s example:

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Quote\Api\Data\AddressInterface">
        <attribute code="custom_field" type="string" />
    </extension_attributes>
</config>

Remember to clear the var/generation directory when the setup:di:compile command is run. You will be able to add new getter and setter methods in the file /var/generation/Magento/Quote/Api/Data/AddressInterface.php.

Step 5: Access custom field’s value on server side

Once you have finished all the steps which are mentioned in the previous sections, the interface which includes your custom attribute will be generated, and you will be able to access your field value.

These attributes values can also be set or get when you create an instance of the Magento/Quote/Api/Data/AddressInterface.php interface.

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$addressInformation = $objectManager->create('Magento\Checkout\Api\Data\ShippingInformationInterface');
$extAttributes = $addressInformation->getExtensionAttributes();
$selectedShipping = $extAttributes->getCustomShippingCharge(); //get custom attribute data.

Step 6: Run CLI Commands

  1. Compile the code with the command below to process and generate necessary classes for the new field you added in the shipping address form and ensure that the code is ready to be executed properly: bin/magento setup:di:compile

  2. Deploy the static files required for the frontend to make the new field you added visible and functional on the user interface. bin/magento setup:static-content:deploy

  3. Run the command below so that the changes you made to your Magento 2 shipping address form are immediately visible and active without any conflicts with previously cached data: bin/magento cache:clean


Custom Checkout Fields

Custom Checkout Fields for Magento 2

Collect extra customer data at the checkout page to improve marketing strategy

Check it out!


Conclusion

A well-designed and user-friendly shipping address form is essential for a seamless checkout experience. It minimizes errors and enables customers to complete their orders quickly and easily. Additionally, it helps store owners avoid shipping issues and ensure accurate product delivery.

With the above five steps, you will be able to add new fields in your Magento 2 shipping address form. I hope this tutorial will be helpful for you when managing the address form. If you have any questions or new ideas, feel free to leave a comment below.

Image Description
Hello, I'm the Chief Technology Officer of Mageplaza, and I am thrilled to share my story with you. My deep love and passion for technology have fueled my journey as a professional coder and an ultra-marathon runner. Over the past decade, I have accumulated extensive experience and honed my expertise in PHP development.
x