Hello Magento Friends,
In today’s Magento 2 tutorial, I am going to explain How to Add a Custom Field in the Customer Address Form and Save its Value in the Magento 2.
Magento 2 offers a robust framework that allows developers to extend and enhance its functionalities. One common requirement is the need to add custom fields to the customer address form and store the values efficiently. In this blog post, we’ll explore the process of adding a custom field to the customer address form in Magento 2 and saving its value.
Contents
Steps to Add Custom Field at Customer Address Form and Save its Value in Magento 2:
Step 1: Create registration.php file inside the Extension folder.
app\code\Vendor\Extension\
Then add the code as follows
1 2 3 4 5 6 |
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Vendor_Extension', __DIR__ ); |
Step 2: Now, create module.xml file inside the etc folder.
app\code\Vendor\Extension\etc\
And include the below-mentioned code
1 2 3 4 |
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Vendor_Extension" setup_version="1.0.0"/> </config> |
Step 3: Then create Customfield.php file inside Field folder.
app\code\Vendor\Extension\Block\Address\Field\
After that, add the following piece of code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
<?php namespace Vendor\Extension\Block\Address\Field; use Magento\Framework\View\Element\Template; class Customfield extends Template { /** * @var string */ protected $_template = 'address/edit/field/customfield.phtml'; /** * @var \Magento\Customer\Api\Data\AddressInterface */ protected $_address; /** * @return string */ public function getCustomfieldValue() { /** @var \Magento\Customer\Model\Data\Address $address */ $address = $this->getAddress(); $customfieldValue = $address->getCustomAttribute('customfield'); if (!$customfieldValue instanceof \Magento\Framework\Api\AttributeInterface) { return ''; } return $customfieldValue->getValue(); } /** * Return the associated address. * * @return \Magento\Customer\Api\Data\AddressInterface */ public function getAddress() { return $this->_address; } /** * Set the associated address. * * @param \Magento\Customer\Api\Data\AddressInterface $address */ public function setAddress($address) { $this->_address = $address; } } |
Step 4: Next, create di.xml file inside the frontend folder.
app\code\Vendor\Extension\etc\frontend\
And add the code as given below
1 2 3 4 5 6 7 8 9 |
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\Customer\Block\Address\Edit"> <plugin name="checkout-fields-block-address-form" type="Vendor\Extension\Plugin\AddExtraFieldToAddressForm" /> </type> <type name="Magento\Customer\Api\AddressRepositoryInterface"> <plugin name="checkout-fields-repository-address" type="Vendor\Extension\Plugin\AddExtraFieldToAddressEntity" /> </type> </config> |
Step 5: After that, create extension_attributes.xml file inside etc folder.
app\code\Vendor\Extension\etc\
Now add the following code snippet
1 2 3 4 5 6 7 8 9 10 11 |
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd"> <extension_attributes for="Magento\Checkout\Api\Data\ShippingInformationInterface"> <attribute code="customfield" type="string" /> </extension_attributes> <extension_attributes for="Magento\Customer\Api\Data\AddressInterface"> <attribute code="customfield" type="string" /> </extension_attributes> <extension_attributes for="Magento\Quote\Api\Data\AddressExtensionInterface"> <attribute code="customfield" type="string" /> </extension_attributes> </config> |
Step 6: Then create AdditionalAttributes.php file inside Address folder.
app\code\Vendor\Extension\Model\Address\
Now include the following code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?php namespace Vendor\Extension\Model\Address; use Magento\Framework\Api\AbstractSimpleObject; class AdditionalAttributes extends AbstractSimpleObject implements \Magento\Customer\Api\Data\AddressExtensionInterface { /** * @param string $note * @return void */ public function setCustomfield($customfield) { $this->setData('customfield', $customfield); } /** * @return mixed|null */ public function getCustomfield() { return $this->_get('customfield'); } } |
Step 7: Then create AddExtraFieldToAddressEntity.php file inside Plugin folder.
app\code\Vendor\Extension\Plugin\
Now add the following code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
<?php namespace Vendor\Extension\Plugin; use Magento\Customer\Api\AddressRepositoryInterface as Subject; use Magento\Customer\Api\Data\AddressInterface as Entity; /** * Class AddNoteFieldToAddressEntity * * @package Yireo\ExampleAddressFieldNote\Plugin */ class AddExtraFieldToAddressEntity { protected $httpRequest; protected $logger; public function __construct( \Magento\Framework\App\RequestInterface $httpRequest, \Magento\Framework\Logger\Monolog $logger ) { $this->httpRequest = $httpRequest; $this->logger = $logger; } /** * @param Subject $subject * @param Entity $entity * * @return Entity */ public function afterGetById(Subject $subject, Entity $entity) { $extensionAttributes = $entity->getExtensionAttributes(); if ($extensionAttributes === null) { return $entity; } $customfield = $this->getCustomfieldByEntityId($entity); $extensionAttributes->setCustomfield($customfield); $entity->setExtensionAttributes($extensionAttributes); return $entity; } /** * @param Subject $subject * @param Entity $entity * * @return [Entity] */ public function beforeSave(Subject $subject, Entity $entity) { $extensionAttributes = $entity->getExtensionAttributes(); if ($extensionAttributes === null) { return [$entity]; } // @todo: Really dirty hack, because Magento\Customer\Controller\Address\FormPost does not support Extension Attributes $customfield = $this->httpRequest->getParam('customfield'); $entity->setCustomAttribute('customfield', $customfield); return [$entity]; } /** * @param Entity $entity * * @return string */ private function getCustomfieldByEntityId(Entity $entity) { $attribute = $entity->getCustomAttribute('customfield'); if ($attribute) { return $attribute->getValue(); } return ''; } } |
Step 8: Then create AddExtraFieldToAddressForm.php file inside Plugin folder.
app\code\Vendor\Extension\Plugin\
And add the code as follows
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
<?php namespace Vendor\Extension\Plugin; use Magento\Customer\Block\Address\Edit as Subject; use Vendor\Extension\Block\Address\Field\Customfield as CustomfieldBlock; class AddExtraFieldToAddressForm { /** * @param Subject $subject * @param string $html * * @return string */ public function afterToHtml(Subject $subject, $html) { $customfieldBlock = $this->getChildBlock(CustomfieldBlock::class, $subject); $customfieldBlock->setAddress($subject->getAddress()); $html = $this->appendBlockBeforeFieldsetEnd($html, $customfieldBlock->toHtml()); return $html; } /** * @param string $html * @param string $childHtml * * @return string */ private function appendBlockBeforeFieldsetEnd($html, $childHtml) { $pregMatch = '/\<\/fieldset\>/'; $pregReplace = $childHtml . '\0'; $html = preg_replace($pregMatch, $pregReplace, $html, 1); return $html; } /** * @param $parentBlock * * @return mixed */ private function getChildBlock($blockClass, $parentBlock) { return $parentBlock->getLayout()->createBlock($blockClass, basename($blockClass)); } } |
Step 9: Next create Customfield.php file inside the Data folder.
app\code\Vendor\Extension\Setup\Patch\Data
Then add the below given code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
<?php namespace Vendor\Extension\Setup\Patch\Data; use Magento\Customer\Model\Customer; use Magento\Framework\Setup\ModuleDataSetupInterface; use Magento\Framework\Setup\Patch\DataPatchInterface; use Magento\Customer\Setup\CustomerSetupFactory; class Customfield implements DataPatchInterface { private $customerSetupFactory; protected $setup; public function __construct(CustomerSetupFactory $customerSetupFactory, ModuleDataSetupInterface $moduleDataSetup) { $this->customerSetupFactory = $customerSetupFactory; $this->setup = $moduleDataSetup; } public function apply() { $customerSetup = $this->customerSetupFactory->create(['setup' => $this->setup]); $customerSetup->addAttribute('customer_address', 'customfield', [ 'label' => 'Custom Field', 'input' => 'text', 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, 'source' => '', 'required' => false, 'position' => 90, 'visible' => true, 'system' => false, 'is_used_in_grid' => true, 'is_visible_in_grid' => true, 'is_filterable_in_grid' => false, 'is_searchable_in_grid' => false, 'frontend_input' => 'hidden', 'backend' => '' ]); $attribute=$customerSetup->getEavConfig() ->getAttribute('customer_address','customfield') ->addData(['used_in_forms' => [ 'adminhtml_customer_address', 'adminhtml_customer', 'customer_address_edit', 'customer_register_address', 'customer_address', 'checkout_register', 'adminhtml_checkout' ] ]); $attribute->save(); } public static function getDependencies() { return []; } /** * {@inheritdoc} */ public function getAliases() { return []; } /** * {@inheritdoc} */ public static function getVersion() { return '3.0.6'; } } |
Step 10: At last, create customfield.phtml file inside field folder.
app\code\Vendor\Extension\view\frontend\templates\address\edit\field\
Finally, add the code as follows
1 2 3 4 5 6 |
<div class="field customfield"> <label class="label" for="customfield"><span><?php /* @escapeNotVerified */ echo __('Custom Field') ?></span></label> <div class="control"> <input type="text" name="customfield" value="<?php echo $block->getCustomfieldValue() ?>" title="<?php /* @escapeNotVerified */ echo __('Custom Field') ?>" id="customfield" class="input-text" > </div> </div> |
Output:
After following the above steps, you can see that the custom field has been added to the customer address.
Conclusion:
Customizing the customer address form in Magento 2 allows you to collect specific information tailored to your business needs. By following the steps outlined in this blog post, you can seamlessly integrate custom fields, enhancing the overall customer experience on your Magento e-commerce platform.
If you face any difficulty while implementing the above steps, let me know through the comment section. For more customization requirements, get in touch with experienced Magento Developers.
Happy Coding!
Your comment is awaiting moderation.
To be more precise. Even when applied the updated code in step9 it will work when there is only one address assigned to a customer. If multiple addresses are assigned only one entry for the last address will be saved. In my case the custom field disappeared when I issued an order with this address.
If you are facing the issue then contact on support@magecomp.com
Installed the updated code in step 9. Seems to save, but after short period the data is lost.
If you are facing the issue then contact on support@magecomp.com
Data is not getting saved nor showing in admin
I have the same problem
We have updated the code. Please check Step 9