How To

How to add Checkout Custom Form Validation using knockout JS in Magento 2

The knockout JS is one of the biggest change ever introduced in Magento 2 frontend which can be a little hard but it comes out as a really useful tool. Basically, Knockout JS is nothing but one kind of Javascript library that uses the MVVM pattern to bind data to certain DOM elements. In your Magento source code, we usually define a View-Model and a Template and the data bound to the Magento 2 view-model which means whenever any data changes happen to view-model changes, it reflects the template too.
Many developers new to Magento 2 thinks that Knockout JS is only used at checkout but In reality, Knockout JS can be used anywhere within the frontend even in creating your color picker, image viewer or whatever. But before we move on to anything else let’s first start with implementing our own Custom Form Validation using knockout JS in Magento 2.
Consider a situation, where you have an Extension that provides a custom form on checkout and we needed to validate on the place order button at that time we need to restrict the user from moving further and validate that all required form fields is completed or not? If yes, then the only user is allowed to place an order.
Here is a small piece of code to do the same.
First, we need to create “checkout_index_index.xml” inside our layout folder.
app\code\Vendor\Extension\frontend\view\layout\checkout_index_index.xml

<pre class="lang:default decode:true">
<?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>
        <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="component" xsi:type="string">uiComponent</item>
                                            <item name="children" xsi:type="array">
                                                <item name="payment" xsi:type="array">
                                                    <item name="children" xsi:type="array">
                                                        <item name="beforeMethods" xsi:type="array">
                                                            <item name="children" xsi:type="array">
                                                                <item name="custom-checkout-form-container" xsi:type="array">
                                                                    <item name="component" xsi:type="string">Vendor_Extension/js/view/checkout/custom-checkout-form</item>
                                                                    <item name="provider" xsi:type="string">checkoutProvider</item>
                                                                    <item name="config" xsi:type="array">
                                                                        <item name="template" xsi:type="string">Vendor_Extension/checkout/custom-checkout-form</item>
                                                                    </item>
                                                                 <item name="children" xsi:type="array">
                                                                        <item name="custom-checkout-form-fieldset" xsi:type="array">
                                                                         <item name="component" xsi:type="string">uiComponent</item>
                                                                            <item name="displayArea" xsi:type="string">custom-checkout-form-fields</item>
                                                                         <item name="children" xsi:type="array">
                                                                                <item name="checkout_additional_name" xsi:type="array">
                                                                                    <item name="component" xsi:type="string">Magento_Ui/js/form/element/abstract</item>
                                                                                    <item name="config" xsi:type="array">
                                                                                        <item name="customScope" xsi:type="string">customCheckoutForm</item>
                                                                                        <item name="template" xsi:type="string">ui/form/field</item>
                                                                                        <item name="elementTmpl" xsi:type="string">ui/form/element/input</item>
                                                                                 </item>
                                                                                    <item name="provider" xsi:type="string">checkoutProvider</item>
                                                                                 <item name="dataScope" xsi:type="string">customCheckoutForm.checkout_additional_name</item>
                                                                                    <item name="label" xsi:type="string">Codice fiscale</item>
                                                                                    <item name="sortOrder" xsi:type="string">16</item>
                                                                                    <item name="validation" xsi:type="array">
                                                                                        <item name="pattern" xsi:type="string">^[A-Z0-9]{11,16}$</item>
                                                                                        <item name="required-entry" xsi:type="boolean">true</item>
                                                                                    </item>
                                                                                    <item name="tooltip" xsi:type="array">
                                                                                        <item name="description" xsi:type="string" translate="true">You can use A to Z and 0 to 9 Digit And Minimum Length 11 and Maximum Length 16.</item>
                                                                                    </item>
                                                                                </item>
                                                                            </item>
                                                                        </item>
                                                                    </item>
                                                             </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                             </item>
                                            </item>
                                        </item>
                                    </item>
                             </item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>
</pre>

In the above code, we just put a field in checkout before payment list.
Now we have to define our “custom-checkout-form.js” at this location.
app\code\Vendor\Extension\view\frontend\web\js\modal\checkout\custom-checkout-form.js and add this code to the file:

<pre class="lang:default decode:true">define(
 [
     'ko',
        'jquery',
 ],
    function(ko,$) {
     'use strict';
     return{
            customFieldsData: ko.observable(null),
         /**
          * Validate checkout agreements
          *
          * @returns {Boolean}
          */            validate: function () {
                var canRun = true;
 
                var temp_checkout_additional_name = $("input[name=checkout_additional_name]").val();
                var reg_checkout_additional_name=/^[A-Z0-9]{11,16}$/;
            
                if(temp_checkout_additional_name == "" || !reg_checkout_additional_name.test(temp_checkout_additional_name)  ){
                    var canRun = false;
                }
                return canRun;
         }
     }
 }
);
</pre>

In last step, we need to create one more “custom-checkout-form.js” file inside our custom extension checkout folder.
app\code\Vendor\Extension\view\frontend\web\js\view\checkout\custom-checkout-form.js

<pre class="lang:default decode:true">
/*global define*/define([
 'knockout',
 'jquery',
 'mage/url',
    'Magento_Ui/js/form/form',
    'Bodak_CheckoutCustomForm/js/model/checkout/custom-checkout-form',
 'Magento_Checkout/js/model/payment/additional-validators'
], function(ko, $, urlFormatter, Component, customer, quote, urlBuilder, errorProcessor, cartCache, formData, additionalValidators) {
 'use strict';
 var isCustomer = customer.isLoggedIn();
    additionalValidators.registerValidator(formData);
 
 });
 
});
</pre>

That’s it you are done! You have successfully placed a field validation in checkout and restrict user from placing an Order. Also, you are free to play and manipulate this according to your need for adding one or more elements to the grid.
Let us know if you are facing an issue while implementing using this code by commenting below.
Happy knocking!

Click to rate this post!
[Total: 22 Average: 4.5]
Dhiren Vasoya

Dhiren Vasoya is a Director and Co-founder at MageComp, Passionate 🎖️ Certified Magento Developer👨‍💻. He has more than 9 years of experience in Magento Development and completed 850+ projects to solve the most important E-commerce challenges. He is fond❤️ of coding and if he is not busy developing then you can find him at the cricket ground, hitting boundaries.🏏

Recent Posts

How to Delete Product Variant in a Shopify Remix App using GraphQL Mutations?

Managing a Shopify store efficiently involves keeping your product catalog organized. This includes removing outdated…

4 hours ago

6 Innovative Tools Revolutionizing E-Commerce Operations

E-commerce has transformed the way consumers shop for products and services and interact with businesses.…

2 days ago

How Upcoming Cookie Changes Will Affect Your E-commerce Website?

The e-commerce world is constantly in flux. New tech and strategies emerge daily to help…

2 days ago

Magento 2: How to Add Header and Footer in Checkout

Hello Magento Friends, In today’s blog, we will discuss adding a header and footer to…

3 days ago

Understanding Flexbox Layout in React Native

Hello React Native Friends, Building a visually appealing and responsive mobile app is crucial in…

5 days ago

HYVĂ„ Themes Releases: 1.3.6 & 1.3.7 – What’s New

We have brought exciting news for Magento store owners. Hyvä Themes recently released 1.3.6 and…

5 days ago