Today we’ll see how to add Custom Field in checkout page in Magento 2.
First You Need to Create Custom module then follow this steps. I have shared a step by step guide to add cms block on checkout sidebar.
Step 1: Create register.php
app/code/Bluethinkinc/CheckoutCustomField/registration.php
1 2 3 4 5 6 7 8 9 |
<?php /** * Copyright © mukesh singh All rights reserved. * See COPYING.txt for license details. */ use Magento\Framework\Component\ComponentRegistrar; ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Bluethinkinc_CheckoutCustomField', __DIR__); ?> |
Step 2: Create module.xml
app/code/Bluethinkinc/CheckoutCustomField/etc/module.xml
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="Bluethinkinc_CheckoutCustomField"/> </config> |
Step 3: Create events.xml
app/code/Bluethinkinc/CheckoutCustomField/etc/events.xml
1 2 3 4 5 6 |
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> <event name="sales_model_service_quote_submit_before"> <observer name="save_delivery_note_to_order" instance="Bluethinkinc\CheckoutCustomField\Observer\SaveToOrder" /> </event> </config> |
Step 4: Create db_schema.xml
app/code/Bluethinkinc/CheckoutCustomField/etc/db_schema.xml
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0"?> <schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> <table name="quote" resource="default" engine="innodb"> <column xsi:type="text" name="delivery_note" nullable="true" comment="Delivery Note"/> </table> <table name="sales_order" resource="default" engine="innodb"> <column xsi:type="text" name="delivery_note" nullable="true" comment="Delivery Note"/> </table> </schema> |
Step 5: Create frontend di.xml
app/code/Bluethinkinc/CheckoutCustomField/etc/frontend/di.xml
1 2 3 4 5 6 7 |
<?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_delivery_note_field" type="Bluethinkinc\CheckoutCustomField\Plugin\Checkout\LayoutProcessorPlugin" sortOrder="10"/> </type> </config> |
Step 6: Create frontend routes.xml
app/code/Bluethinkinc/CheckoutCustomField/etc/frontend/routes.xml
1 2 3 4 5 6 7 8 |
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> <router id="standard"> <route id="checkoutcustomfield" frontName="checkoutcustomfield"> <module name="Bluethinkinc_CheckoutCustomField" /> </route> </router> </config> |
Step 7: Create LayoutProcessorPlugin.php
app/code/Bluethinkinc/CheckoutCustomField/Plugin/Checkout/LayoutProcessorPlugin.php
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 |
<?php namespace Bluethinkinc\CheckoutCustomField\Plugin\Checkout; class LayoutProcessorPlugin { /** * @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']['shipping-address-fieldset']['children']['delivery_note'] = [ 'component' => 'Magento_Ui/js/form/element/textarea', 'config' => [ 'customScope' => 'shippingAddress', 'template' => 'ui/form/field', 'elementTmpl' => 'ui/form/element/textarea', 'tooltip' => [ 'description' => 'Here you can leave delivery notes', ], 'options' => [], 'id' => 'delivery_note' ], 'dataScope' => 'shippingAddress.delivery_note', 'label' => __('Delivery Note'), 'provider' => 'checkoutProvider', 'visible' => true, 'validation' => [ 'required-entry' => true ], 'sortOrder' => 1000, 'id' => 'delivery_note' ]; return $jsLayout; } } ?> |
Step 8: Create SaveToOrder.php
app/code/Bluethinkinc/CheckoutCustomField/Observer/SaveToOrder.php
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php namespace Bluethinkinc\CheckoutCustomField\Observer; class SaveToOrder implements \Magento\Framework\Event\ObserverInterface { public function execute(\Magento\Framework\Event\Observer $observer) { $event = $observer->getEvent(); $quote = $event->getQuote(); $order = $event->getOrder(); $order->setData('delivery_note', $quote->getData('delivery_note')); } } ?> |
Step 9: Create Save.php
app/code/Bluethinkinc/CheckoutCustomField/Controller/Quote/Save.php
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 |
<?php namespace Bluethinkinc\CheckoutCustomField\Controller\Quote; class Save extends \Magento\Framework\App\Action\Action { protected $quoteIdMaskFactory; protected $quoteRepository; public function __construct( \Magento\Framework\App\Action\Context $context, \Magento\Quote\Model\QuoteIdMaskFactory $quoteIdMaskFactory, \Magento\Quote\Api\CartRepositoryInterface $quoteRepository ) { parent::__construct($context); $this->quoteRepository = $quoteRepository; $this->quoteIdMaskFactory = $quoteIdMaskFactory; } /** * @return \Magento\Framework\Controller\Result\Raw */ public function execute() { $post = $this->getRequest()->getPostValue(); if ($post) { $cartId = $post['cartId']; $deliveryNote = $post['delivery_note']; $loggin = $post['is_customer']; if ($loggin === 'false') { $cartId = $this->quoteIdMaskFactory->create()->load($cartId, 'masked_id')->getQuoteId(); } $quote = $this->quoteRepository->getActive($cartId); if (!$quote->getItemsCount()) { throw new NoSuchEntityException(__('Cart %1 doesn\'t contain products', $cartId)); } $quote->setData('delivery_note', $deliveryNote); $this->quoteRepository->save($quote); } } } ?> |
Step 10: Create Attributes.php
app/code/Bluethinkinc/CheckoutCustomField/Block/Adminhtml/Attributes.php
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 |
<?php namespace Bluethinkinc\CheckoutCustomField\Block\Adminhtml; use Magento\Framework\AppInterface; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Sales\Api\Data\OrderInterface; class Attributes extends \Magento\Backend\Block\Template { public $orderRepository; public function __construct( \Magento\Backend\Block\Template\Context $context, \Magento\Sales\Api\OrderRepositoryInterface $orderRepository, array $data = [] ) { $this->orderRepository = $orderRepository; parent::__construct($context, $data); } public function getOrder() { try { $orderId = $this->getRequest()->getParam('order_id'); return $this->orderRepository->get($orderId); } catch (NoSuchEntityException $e) { return false; } } }?> |
Step 11: Create DeliveryNote.php
app/code/Bluethinkinc/CheckoutCustomField/Ui/Component/Listing/Column/DeliveryNote.php
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 |
<?php namespace Bluethinkinc\CheckoutCustomField\Ui\Component\Listing\Column; use \Magento\Sales\Api\OrderRepositoryInterface; use \Magento\Framework\View\Element\UiComponent\ContextInterface; use \Magento\Framework\View\Element\UiComponentFactory; use \Magento\Ui\Component\Listing\Columns\Column; use \Magento\Framework\Api\SearchCriteriaBuilder; class DeliveryNote extends Column { protected $_orderRepository; protected $_searchCriteria; public function __construct(ContextInterface $context, UiComponentFactory $uiComponentFactory, OrderRepositoryInterface $orderRepository, SearchCriteriaBuilder $criteria, array $components = [], array $data = []) { $this->_orderRepository = $orderRepository; $this->_searchCriteria = $criteria; parent::__construct($context, $uiComponentFactory, $components, $data); } public function prepareDataSource(array $dataSource) { if (isset($dataSource['data']['items'])) { foreach ($dataSource['data']['items'] as & $item) { $order = $this->_orderRepository->get($item["entity_id"]); $date = $order->getData("delivery_note"); $item[$this->getData('name')] = $date; } } return $dataSource; } }?> |
Step 12: Create sales_order_view.xml
app/code/Bluethinkinc/CheckoutCustomField/view/adminhtml/layout/sales_order_view.xml
1 2 3 4 5 6 7 8 9 10 11 12 |
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceContainer name="content"> <referenceContainer name="order_additional_info"> <block class="Bluethinkinc\CheckoutCustomField\Block\Adminhtml\Attributes" name="customfield_order_attributes" template="Bluethinkinc_CheckoutCustomField::attributes.phtml" /> </referenceContainer> </referenceContainer> </body> </page> |
Step 13: Create attributes.phtml
app/code/Bluethinkinc/CheckoutCustomField/view/adminhtml/templates/attributes.phtml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<?php $order = $block->getOrder(); ?> <?php if ($order) : ?> <section class="admin__page-section order-additional-information"> <div class="admin__page-section-title"> <strong class="title"><?php echo /* @escapeNotVerified */ __('Additional Information'); ?></strong> </div> <div id="<?php echo $block->getHtmlId() ?>" class="admin__page-section-content order-additional-information-container"> <div class="admin__page-section-item order-information"> <div class="admin__page-section-item-content"> <table class="admin__table-secondary order-information-table"> <tr> <th>Delivery Note</th> <td><?php echo $order->getDeliveryNote(); ?></td> </tr> </table> </div> </div> </div> </section> <?php endif; ?> |
Step 14: Create sales_order_grid.xml
app/code/Bluethinkinc/CheckoutCustomField/view/adminhtml/ui_component/sales_order_grid.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?xml version="1.0"?> <listing xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd"> <columns name="sales_order_columns"> <column name="delivery_note" class="Bluethinkinc\CheckoutCustomField\Ui\Component\Listing\Column\DeliveryNote"> <argument name="data" xsi:type="array"> <item name="config" xsi:type="array"> <item name="visible" xsi:type="boolean">true</item> <item name="label" xsi:type="string" translate="true">Delivery Note</item> </item> </argument> </column> </columns> </listing> |
Step 15: Create requirejs-config.js
app/code/Bluethinkinc/CheckoutCustomField/view/frontend/requirejs-config.js
1 2 3 4 5 6 7 8 9 |
var config = { config: { mixins: { 'Magento_Checkout/js/action/place-order': { 'Bluethinkinc_CheckoutCustomField/js/order/place-order-mixin': true } } } }; |
Step 16: Create place-order-mixin.js
app/code/Bluethinkinc/CheckoutCustomField/view/frontend/web/js/order/place-order-mixin.js
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 |
define([ 'jquery', 'mage/utils/wrapper', 'Magento_CheckoutAgreements/js/model/agreements-assigner', 'Magento_Checkout/js/model/quote', 'Magento_Customer/js/model/customer', 'Magento_Checkout/js/model/url-builder', 'mage/url', 'Magento_Checkout/js/model/error-processor', 'uiRegistry' ], function ( $, wrapper, agreementsAssigner, quote, customer, urlBuilder, urlFormatter, errorProcessor, registry ) { 'use strict'; return function (placeOrderAction) { /** Override default place order action and add agreement_ids to request */ return wrapper.wrap(placeOrderAction, function (originalAction, paymentData, messageContainer) { agreementsAssigner(paymentData); var quoteId = quote.getQuoteId(); var isCustomer = customer.isLoggedIn(); var url = urlFormatter.build('checkoutcustomfield/quote/save'); var deliveryNote = $('[name="delivery_note"]').val(); if (deliveryNote) { var payload = { 'cartId': quoteId, 'delivery_note': deliveryNote, 'is_customer': isCustomer }; if (!payload.delivery_note) { return true; } var result = true; $.ajax({ url: url, data: payload, dataType: 'text', type: 'POST', }).done( function (response) { result = true; } ).fail( function (response) { result = false; errorProcessor.process(response); } ); } return originalAction(paymentData, messageContainer); }); }; }); |
Step 17: After create the module if you run the command as
php bin/magento module:status
You should see the module is disable now:
List of disabled modules: Bluethinkinc_ CheckoutCustomField
enable the module right now, let run the command as:
php bin/magento module:enable Bluethinkinc_ CheckoutCustomField
After Enable Module Then Run this Command
sudo php bin/magento setup:upgrade
sudo php bin/magento setup:di:compile
sudo php bin/magento setup:static-content:deploy -f
sudo php bin/magento c:f
sudo chmod -R 777 var/ pub/static generated/
Now, please see the result
Bacekend sales order and order details
Mukesh Singh
2024-01-22