In order to display your fields in checkout page Use below method
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="add-checkout-field"
type="Vendor\module-name\Model\Checkout\LayoutProcessorPlugin" sortOrder="10"/>
</type>
</config>
Vendor\module-name\Model\Checkout\LayoutProcessorPlugin.php
<?php
namespace Vendor\module-name\Model\Checkout;
class LayoutProcessor
{
/**
* @var \Magento\Framework\App\Config\ScopeConfigInterface
*/
protected $scopeConfig;
/**
* @var \Magento\Checkout\Model\Session
*/
protected $checkoutSession;
/**
* @var \Magento\Customer\Model\AddressFactory
*/
protected $customerAddressFactory;
/**
* @var \Magento\Framework\Data\Form\FormKey
*/
protected $formKey;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\CheckoutAgreements\Model\ResourceModel\Agreement\CollectionFactory $agreementCollectionFactory,
\Magento\Checkout\Model\Session $checkoutSession,
\Magento\Customer\Model\AddressFactory $customerAddressFactory
) {
$this->scopeConfig = $context->getScopeConfig();
$this->checkoutSession = $checkoutSession;
$this->customerAddressFactory = $customerAddressFactory;
}
/**
* @param \Magento\Checkout\Block\Checkout\LayoutProcessor $subject
* @param array $jsLayout
* @return array
*/
public function afterProcess(
\Magento\Checkout\Block\Checkout\LayoutProcessor $subject,
array $jsLayout
) {
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
['shippingAddress']['children']['before-form']['children']['custom_field'] = [
'component' => 'Magento_Ui/js/form/element/abstract',
'config' => [
'customScope' => 'shippingAddress',
'template' => 'ui/form/field',
'options' => [],
'id' => 'custom_field_id'
],
'dataScope' => 'shippingAddress.custom_field',
'label' => 'Custom field',
'provider' => 'checkoutProvider',
'visible' => true,
'validation' => [],
'sortOrder' => 200,
'id' => 'custom_field'
];
return $jsLayout;
}
}
The above code will display the custom field in shipping address section you can change the position in the array $jsLayout
In order to get this value when submitting the form in checkout page. use below method
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\Quote\Api\Data\AddressInterface">
<attribute code="custom_field" type="string"/>
</extension_attributes>
</config>
view/frontend/requirejs-config.js
var config = {
config: {
mixins: {
'Magento_Checkout/js/action/set-shipping-information': {
'vendoe_modulename/js/action/set-shipping-information-mixin': true
}
} // this is how js mixin is defined
}
};
view/frontend/web/js/action/set-shipping-information-mixin.js
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'] = {'custom_field':'1'};
}
return originalAction();
});
};
});
The next step is saving this custom field post data to the quote. Let's make another plugin by adding an xml node in our etc/di.xml
<type name="Magento\Checkout\Model\ShippingInformationManagement">
<plugin name="save-in-quote" type="vendor\modulename\Model\Checkout\ShippingInformationManagementPlugin" sortOrder="10"/>
</type>
this method will save the custom field value in quote table
vendor\modulename\Model\Checkout\ShippingInformationManagementPlugin.php
<?php
namespace vendor\modulename\Plugin\Checkout;
class ShippingInformationManagementPlugin
{
protected $quoteRepository;
public function __construct(
\Magento\Quote\Model\QuoteRepository $quoteRepository
) {
$this->quoteRepository = $quoteRepository;
}
/**
* @param \Magento\Checkout\Model\ShippingInformationManagement $subject
* @param $cartId
* @param \Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
*/
public function beforeSaveAddressInformation(
\Magento\Checkout\Model\ShippingInformationManagement $subject,
$cartId,
\Magento\Checkout\Api\Data\ShippingInformationInterface $addressInformation
) {
$extAttributes = $addressInformation->getShippingAddress()->getExtensionAttributes();
$deliveryDate = $extAttributes->getCustomField();
$quote = $this->quoteRepository->getActive($cartId);
$quote->setCustomField($deliveryDate);
}
}
After that create another plugin to save the custom field value from quote table to sales_order table