Magento2 – How to Create Custom Checkbox Field for Terms and Conditions in One Page Checkout

checkoutmagento2onepage-checkout

I am new to magento2. I want to create a custom checkbox for a required option without checked checkbox customer cannot place an order.
How to create terms and conditions checkbox custom field using custom code.
I have an issue with magento2 default terms and conditions it is not working.

Best Answer

Create New column 'agree' in 'quote' and 'sales_order' table at DB. and

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\Quote\Api\Data\AddressInterface">
            <attribute code="agree" type="string" />
        </extension_attributes>
    </config>

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="billing-step" xsi:type="array">
                                                <item name="children" xsi:type="array">
                                                    <item name="payment" xsi:type="array">
                                                        <item name="children" xsi:type="array">
    <!-- to show checkbox inside payment section-->
                                                            <item name="payments-list" xsi:type="array">
                                                                <item name="children" xsi:type="array">
                                                                    <item name="before-place-order" xsi:type="array">
                                                                        <item name="children" xsi:type="array">
                                                                            <item name="custom-checkbox" xsi:type="array">
                                                                                <item name="component" xsi:type="string">vendor_module/js/checkout/customJs</item>
                                                                                <item name="displayArea" xsi:type="string">before-place-order</item>
                                                                                <item name="sortOrder" xsi:type="string">3</item>
                                                                                <item name="dataScope" xsi:type="string">checkoutcomments</item>
                                                                                <item name="provider" xsi:type="string">checkoutProvider</item>
                                                                            </item>
                                                                        </item>
                                                                    </item>
                                                                </item>
                                                            </item>
    
    <!-- to show checkbox below the payment methods -->
                                                            <!-- <item name="afterMethods" xsi:type="array">
                                                                <item name="children" xsi:type="array">
                                                                    <item name="custom-checkbox" xsi:type="array">
                                                                        <item name="component" xsi:type="string">vendor_module/js/checkout/customJs</item>
                                                                        <item name="displayArea" xsi:type="string">before-place-order</item>
                                                                        <item name="sortOrder" xsi:type="string">3</item>
                                                                        <item name="dataScope" xsi:type="string">checkoutcomments</item>
                                                                        <item name="provider" xsi:type="string">checkoutProvider</item>
                                                                    </item>
                                                                </item>
                                                            </item> -->
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </argument>
                </arguments>
            </referenceBlock>
        </body>
    </page>

Vendor\Module\view\frontend\web\js\checkout\customJs.js

define(
[
    'ko',
    'jquery',
    'uiComponent',
    'mage/url'
],
function (ko, $, Component,url) {
    'use strict';
    return Component.extend({
        defaults: {
            template: 'vendor_module/checkout/customCheckbox'
        },
        initObservable: function () {

            this._super()
                .observe({
                    CheckVals: ko.observable(true) //default checked(true)
                });
            var checkVal=0;
            self = this;
            this.CheckVals.subscribe(function (newValue) {
                var linkUrls  = url.build('custom/checkout/saveInQuote');
                if(newValue) {
                    checkVal = 1;
                }
                else{
                    checkVal = 0;
                }
                $.ajax({
                    showLoader: true,
                    url: linkUrls,
                    data: {checkVal : checkVal},
                    type: "POST",
                    dataType: 'json'
                }).done(function (data) {
                    console.log('success');
                });
            });
            return this;
        }
    });
});

Vendor\Module\view\frontend\web\template\checkout\customCheckbox.html

<input type="checkbox" id="customCheckbox" name="customCheckbox" value="" data-bind='checked: CheckVals'/><label for="customCheckbox">Please uncheck this box if you <b>do not</b> want to hear from us about our inspirational, new arrivals and latest offers</label><br>

Vendor\Module\Controller\Checkout\saveInQuote.php

    <?php
namespace Vendor\Module\Controller\Checkout;

use Magento\Framework\App\Action\Context;
use Magento\Framework\Controller\Result\ForwardFactory;
use Magento\Framework\View\LayoutFactory;
use Magento\Checkout\Model\Cart;
use Magento\Framework\App\Action\Action;
use Magento\Checkout\Model\Session;
use Magento\Quote\Model\QuoteRepository;

class saveInQuote extends Action
{
    protected $resultForwardFactory;
    protected $layoutFactory;
    protected $cart;

    public function __construct(
        Context $context,
        ForwardFactory $resultForwardFactory,
        LayoutFactory $layoutFactory,
        Cart $cart,
        Session $checkoutSession,
        QuoteRepository $quoteRepository
    )
    {
        $this->resultForwardFactory = $resultForwardFactory;
        $this->layoutFactory = $layoutFactory;
        $this->cart = $cart;
        $this->checkoutSession = $checkoutSession;
        $this->quoteRepository = $quoteRepository;

        parent::__construct($context);
    }

    public function execute()
    {
        $checkVal = $this->getRequest()->getParam('checkVal');
        $quoteId = $this->checkoutSession->getQuoteId();
        $quote = $this->quoteRepository->get($quoteId);
        $quote->setAgree($checkVal);
        $quote->save();
    }
} ?>

Vendor\Module\etc\events.xml

<?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="custom_checkbox_code_order_place_before_action" instance="Vendor\Module\Observer\PlaceOrder"/>
</event>

Vendor\Module\Observer\PlaceOrder.php

<?php
namespace Vendor\Module\Observer;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Quote\Model\QuoteFactory;
use Psr\Log\LoggerInterface;

class PlaceOrder implements ObserverInterface
{
    /**
    * @var \Psr\Log\LoggerInterface
    */
    protected $_logger;

    /**
    * @var \Magento\Customer\Model\Session
    */
    protected $quoteFactory;

    /**
     * Constructor
     *
     * @param \Psr\Log\LoggerInterface $logger
     */

    public function __construct(LoggerInterface $logger,
        QuoteFactory $quoteFactory) {
        $this->_logger = $logger;
        $this->quoteFactory = $quoteFactory;
    }

    public function execute(Observer $observer)
    {
        $order = $observer->getOrder();
        $quoteId = $order->getQuoteId();
        $quote  = $this->quoteFactory->create()->load($quoteId);
        $order->setAgree($quote->getAgree());
        $order->save();
    }
} ?>
Related Topic