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
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 | <?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> |
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:
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 | 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; } } } ); |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /*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); }); }); |
Let us know if you are facing an issue while implementing using this code by commenting below.
Happy knocking!