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.
6 Steps to add new fields in an address form in Magento 2:
- Step 1: Add field to layout
- Step 2: Add JS mixin to modify data submission
- Step 3: Load mixin
- Step 4: Add field to address model
- Step 5: Access custom field’s value on server side
- Step 6: Run CLI Commands
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
-
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
-
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
-
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
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.
- How to create a simple Hello World module for Magento 2
- Magento 2 Block Template Ultimate Guides
- How to Create Module in Magento 2
- How to Create Controller in Magento 2
- How to create CRUD Models in Magento 2
- How to Create Magento 2 Block, Layout and Templates
- Configuration - System.xml
- How To Create Admin Menu In Magento 2
- Admin ACL
- Admin Grid