I need to add some fields to the shipping address form from checkout page, and then save them in database. Please tell me how to do this thing?
3 Answers
A quick example shows how to add a custom field in checkout page and save it into database.
First of all, because the necessary information of quote table will be transferred to sales order, so we should create our new custom field custom_test
in quote
and sales_order
tables:
app/code/Vendor/Module/Setup/UpgradeSchema.php
<?php
namespace Vendor\Module\Setup;
use Magento\Framework\Setup\UpgradeSchemaInterface;
use Magento\Framework\Setup\SchemaSetupInterface;
use Magento\Framework\Setup\ModuleContextInterface;
class UpgradeSchema implements UpgradeSchemaInterface
{
/**
* Upgrades DB schema for a module
*
* @param SchemaSetupInterface $setup
* @param ModuleContextInterface $context
* @return void
*/
public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
{
$setup->startSetup();
$quoteAddressTable = 'quote';
$orderTable = 'sales_order';
//Quote address table
$setup->getConnection()
->addColumn(
$setup->getTable($quoteAddressTable),
'custom_test',
[
'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'length' => 255,
'comment' =>'Custom Test'
]
);
//Order address table
$setup->getConnection()
->addColumn(
$setup->getTable($orderTable),
'custom_test',
[
'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
'length' => 255,
'comment' =>'Custom Test'
]
);
$setup->endSetup();
}
}
Add our custom field to checkout page app/code/Vendor/Module/view/frontend/layout/checkout_index_index.xml
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="checkout.root">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="checkout" xsi:type="array">
<item name="children" xsi:type="array">
<item name="steps" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shipping-step" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shippingAddress" xsi:type="array">
<item name="children" xsi:type="array">
<item name="shipping-address-fieldset" xsi:type="array">
<!--Our custom test fieldset here-->
<item name="children" xsi:type="array">
<item name="customer_test" xsi:type="array">
<item name="sortOrder" xsi:type="string">300</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</item>
</argument>
</arguments>
</referenceBlock>
</body>
</page>
Create fieldset.xml
app/code/Vendor/Module/etc/fieldset.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:DataObject/etc/fieldset.xsd">
<scope id="global">
<fieldset id="sales_convert_quote">
<field name="custom_test">
<aspect name="to_order" />
</field>
</fieldset>
</scope>
</config>
Basically, this fieldset is used for defining the attribute which will be copied from quote object to order object automatically.
Don't forget to create registration.php
and etc/module.xml
app/code/Vendor/Module/registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Vendor_Module',
__DIR__
);
app/code/Vendor/Module/etc/module.xml
<?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_Module" setup_version="1.0.0"/>
</config>
Run setup upgrade command: php bin/magento setup:upgrade
. Now, we can see our new custom field in checkout page and database quote
and sales_order
.
After that, now we can create more functions to work with quote and order objects.
-
After I installed your module, the custom field show up in tables quote_address and sales_order_address, but it not appear in frontend shipping address form. Jul 17, 2016 at 9:03
-
I made some changes to this module and now I can see the custom field in frontend but I can't save it in db. I checked for errors in var directory and all is well.Please help me! Jul 18, 2016 at 12:54
-
I will check! How you fixed the custom field on the frontend? Jul 18, 2016 at 13:06
-
I think the problem appears when I click the next button, Custom checkout field is not sent in post data request, If you check the console you will see this. I don't know why this is happening. You can check this in the new version of module: github.com/rlaa/custom-checkout-fields/blob/master/… Jul 19, 2016 at 8:55
-
1Hi, may i know how this save to database part work? I dont see any code which can save to the database in your code. I've do exactly as you, but ignore the
UpgradeSchema.php
andfieldset.xml
. Does that 2 files are everything it need to save to database?– fuduSep 13, 2018 at 15:55
I deleted the view directory and I added the following files: app/code/Vendor/Module/etc/frontend/di.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
<plugin name="vendor_add_custom_field" type="Vendor\Module\Plugin\Checkout\Model\Checkout\LayoutProcessor" sortOrder="100"/>
</type>
</config>
app/code/Vendor/Module/etc/extension_attributes.xml
<?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\Checkout\Api\Data\ShippingInformationInterface">
<attribute code="custom_test" type="string"/>
</extension_attributes>
</config>
app/code/Vendor/Module/Plugin/Checkout/Model/Checkout/LayoutProcessor.php
<?php
namespace Vendor\Module\Plugin\Checkout\Model\Checkout;
class LayoutProcessor
{
public function afterProcess(
\Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
array $jsLayout
) {
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
['shippingAddress']['children']['shipping-address-fieldset']['children']['custom_test'] = [
'component' => 'Magento_Ui/js/form/element/abstract',
'config' => [
'customScope' => 'shippingAddress',
'template' => 'ui/form/field',
'elementTmpl' => 'ui/form/element/input',
'options' => [],
'id' => 'custom_test'
],
'dataScope' => 'shippingAddress.custom_test',
'label' => 'Custom test',
'provider' => 'checkoutProvider',
'visible' => true,
'validation' => [],
'sortOrder' => 252,
'id' => 'custom_test'
];
return $jsLayout;
}
}
after that run: php bin/magento setup:upgrade, php bin/magento cache:clean
-
3Hi @rla i have followed the above steps but its values are not saving in sales_order and quote tables May 22, 2018 at 5:04
-
Download module from GitHub and make changes as per requirements.