Magento 2 knockout js: Component, Form validation, Template

If you are a beginner,  just started to learn Magento or have already been doing for some time, there is a higher chance that you have not given a deeper thought about learning Magento 2 Knockout JS. But, it is important to understand Knockout JS because its “data-binding” concept has been used pretty well in some vital elements of Magento such as a mini cart and checkout.

Magento 2 Knockout JS

Knockout JS is appreciated as a more simple and lighter framework than others and Magento just needs some functions of Knockout such as data-binding and components. Because of its simplicity, Knockout is stable and reduces potential problems while other frameworks are in development.  

Knockout Magento 2

This article aims at explaining the basic concepts of Magento 2 Knockout JS which are effective to use in Magento 2 as well as implementing a very simple logic. If you are not familiar with the Knockout Javascript library, we would recommend you to read the documentation of Knockout JS.

Knockout is a Javascript library helping in the frontend of Magento 2. It implements the Model-View-View-Model (MVVM) design pattern. You can find Magento 2 Knockout JS on almost every page, but mostly on the checkout page. The addition of Magento 2 Knockout JS is a bit tricky.

Knockout Magento 2

Magento 2 is now using a text field with a view to handling quantity on the product page. But if you want your page to have quantity increment buttons, you can easily add this kind of behavior by using Magento 2 Knockout JS.

>>>> Read more: How to use Knockout JS on a Magento 2 Frontend Page

Why is Knockout JS used in Magento 2?

Observables and Dependency tracking

Observables are useful for updating your user interface (UI) automatically while the view model or content will be changed. Thus, you need to declare your model properties as observables. It can notify subscribers about changes and will automatically detect dependencies.

For instance:

var rhViewModel = {
personName: ko.observable(‘Rohan’),
personAge: ko.observable(10)
};

Dependency tracking is definitely working whenever you declare a computed observable. When observables declared, knockout will automatically invoke and get its initial value. Whenever that appropriate function runs, knockout will set up a subscription to all observables and looping process till ends additionally reading values and then setting new values to computed observables.

Declarative bindings

Declarative binding is one of the best ways to interact with Magento 2 UI Components. It’s useful for understanding the relationship between binding and knockout observables. Declarative binding in Knockout JS provides a powerful technique to connect data to UI. The binding value can be a single value, literal, a variable, or even a JavaScript expression. If the binding refers to some invalid expression or reference, then knockout will show an error and stop processing the binding.

Take note the following points: 

  • Whitespaces actually do not make any difference
  • Starting from Knockout 3.0, you are able to skip the binding value which will give binding an undefined value

Magento 2 knockout js tutorial

If you want to make a knockout app in Magento 2, first of all, you have to create a new module. Take a look at the knockout js Magento 2 tutorial below.

<?php
/* @var Codilar\HelloWorld\Block\Hello $block */
?>
<div data-bind=”scope: ‘knockout-tutorial'”>
<!– ko template: getTemplate() –><!– /ko –>
</div>
<script type=”text/x-magento-init”>
{
     “*”: {
            “Magento_Ui/js/core/app”: {
                “components”: {
                    “knockout-tutorial”: {
                        “component”: “Codilar_HelloWorld/js/viewModel”,
                        “template” : “Codilar_HelloWorld/template”
                 }
             }
         }
     }
}
</script>

This is basically initiating the Magento_Ui/js/core/app widget with the components known as options, taking full use of the text/x-magento-init tag. The data-bind=”scope: ‘knockout-tutorial'” shows knockout to use the knockout-tutorial component and template inside that DIV.

Then, we will write a component file:

app/code/Codilar/HelloWorld/view/frontend/web/js/viewModel.js

define([
‘uiComponent’,
‘ko’
], function(Component, ko) {
return Component.extend({
     clock: ko.observable(“”),
     initialize: function () {
         this._super();
         setInterval(this.reloadTime.bind(this), 1000);
     },
     reloadTime: function () {
         /* Setting new time to our clock variable. DOM manipulation will happen automatically */
         this.clock(Date());
     },
        getClock: function () {
         return this.clock;
     }
});
});

The View-Models inside of a Magento 2 application, have to return a Component.extend function call, where a Component is an object of the uiComponent required here. Inside the Component.extend, you have to pass an object, which must consist of an initialized function which will be the “constructor of the class”.

And finally, we need to create our template file:

app/code/Codilar/HelloWorld/view/frontend/web/template/template.html

<!– My View-Model file is Codilar_HelloWorld/js/viewModel –>

<h1 data-bind=”text: getClock()”></h1>

Magento 2 Knockout template

Magento 2 Knockout template

Magento 2 knockout template is a customization of the existing Knockout template binding. It is used to render a template inside of the associated element. The original of it was overridden to support loading of templates by the provided path, instead of searching for them on the page.

Source: 

<Magento_Ui_module_dir>/view/base/web/js/lib/knockout/template/engine.js.

Value type: String | Object

Configuration for the template binding. If the provided value is a string, it is processed as a path to .html file.

Aliases: [render], <render>

Usage example:

1234567
<div data-bind=”template: ‘path/to/the/template'”></div>
<!– ko template: getTemplate() –><!– /ko –>
<render args=”template” />
<div each=”getRegion(‘displayArea’)” render=””/>

Magento 2 override Knockout template

Overriding a template is considered as one of the most vital and common tasks for every developer who works on the Magento 2 platform. In numerous cases, completing this task is quite easy. But, in some other cases, it seems like an impossible mission.

Below, we will provide you some methods that you could use in various cases to override a native template file in Magento 2. 

Theme file path

This method will be used when you want to build a theme.

More specifically, in Magento 2, any module’s or parent theme’s layout, or web can be easily overridden with ease just by placing it in <theme_dir>/<Vendor>_<Module>/path/to/file.

For example, with the Magento_Theme module, you can put your template in <theme_dir>/Magento_Theme/templates/html/header.phtml, if you want the template located at <theme_dir>/<Vendor>_<Module>/view/html/header.phtml to be overridden.

In various cases, you will not be able to specify which module the template belongs to because several block definitions in Magento 2 do not have the Vendor_Module prefix. In these cases, the module with the template belongs to will be defined by the block’s class attribute.

Layout Block Argument

This method is recommended to use when you want to build a module. With a view to using layout XML to override a template, you will only have to override the template argument of the block. Just take the template Magento_Wishlist/view/frontend/templates/view.phtml as an example, for the view.phtml to be overridden with your own template, a new layout file will be created firstly: <Vendor>_<Module>/view/frontend/layout/wishlist_index_index.xml.

Nowadays, there are two methods that could be applied to override a block argument. In this article, we want to recommend both of them.

  • The first one: New method

wishlist_index_index.xml

<?xml version=”1.0″?>
<page xmlns:xsi=”//www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”urn:magento:framework:View/Layout/etc/page_configuration.xsd”>
<body>
     <referenceBlock name=”customer.wishlist”>
         <arguments>
             <argument name=”template” xsi:type=”string”>Vendor_Module::view.phtml</argument>
         </arguments>
     </referenceBlock>
</body>
</page>

  • The second one: Old deprecated method

wishlist_index_index.xml

<?xml version=”1.0″?>
<page xmlns:xsi=”//www.w3.org/2001/XMLSchema-instance” xsi:noNamespaceSchemaLocation=”urn:magento:framework:View/Layout/etc/page_configuration.xsd”>
<body>
     <referenceBlock name=”customer.wishlist”>
         <action method=”setTemplate”>
             <argument name=”template” xsi:type=”string”>Vendor_Module::view.phtml</argument>
         </action>
     </referenceBlock>
</body>
</page>

Magento 2 create Knockout component

With the introduction of the library, it has been possible to create responsive frontend components like date picker, popup, and even more UI components.

UI components are known as a large and complex topic in Magento 2. UI components are used to create elements like tables, buttons, tabs, dialogs, and much more. To be more specific, a UI component is used to implement a part of the MVVM model. And now, we will explain how we can create a custom UI Component template with the support of codes.

First, take a look at the flow:

  1. Step 1: Create one PHTML file
  2. Step 2: Create custom component using “Magento_UI/js/core/app”
  3. Step 3: Register New Component within Components
  4. Step 4: Call out a custom component template file and pass the variable
  5. Step 5: In the JS file, put the knockout library for knockout JS
  6. Step 6: Return function is mandatory, thus we put it and the logic out there
  7. Step 7: At the moment, data will bind with our HTML tag by the support of the “data-bind” attribute

Let us see the Magento 2 knockout js examples.

  • First, create PHTML file following the below path,

app\code\Vendor\Extension\view\frontend\templates\uicomponent.phtml

  • Then, create js file following the below path,

app\code\Vendor\Extension\view\frontend\web\js\uicomponentjs.js

Magento 2 Knockout JS form validation

Magento 2 Knockout JS form validation

Many newbies to Magento 2 suppose that Knockout JS is only used at checkout. But in reality, Knockout JS is able to be used anywhere within the frontend even in creating your color picker, image viewer, or whatever. Before moving on to anything else, just start with implementing your own Magento 2 Knockout JS form validation.

Considering a situation, where you have an opportunity to provide a custom form on checkout additionally, we have to validate on the place order button.  At that time, we have to restrict the user from moving further and confirm that all required form fields are done or not? If yes, then the only user is allowed to place an order.

Below is a small piece of code to do the same.

  • First, we have to create “checkout_index_index.xml” inside our layout folder.

app\code\Vendor\Extension\frontend\view\layout\checkout_index_index.xml

  • Then we need to define our “custom-checkout-form.js” at this location.

app\code\Vendor\Extension\view\frontend\web\js\modal\checkout\custom-checkout-form.js

  • In the last step, we have to create one more “custom-checkout-form.js” file inside your custom extension checkout folder.

app\code\Vendor\Extension\view\frontend\web\js\view\checkout\custom-checkout-form.js

Magento 2 knockout translate

In some cases, your custom theme might contain new strings that are not present in out-of-the-box Magento themes. To ensure your theme displays correctly with any language applied on a store view, verifying the unique strings of your theme are smartly added to the translation i18n tool when generating the dictionary you have to use Magento 2 Knockout JS translation. Also when a new language package is created and used to translate a store view, all theme strings are translated, too.

To be sure that your new string is added to the dictionary and translated, just use the __(‘<your_string>’) method when outputting a string in a .phtml template.

For instance:

1<?= __(‘Create Backup’) ?>

If your string contains a variable, let add a placeholder for this variable in the dictionary and use syntax similar to the following:

1<?= __(‘Hello %1’, $yourVariable) ?>

In this example, the ‘Hello %1’ string is added to the dictionary when the i18n tool is run.

Bottom line

We can’t deny that Magento 2 Knockout JS assists mainly to build a lot of parts in Magento 2 frontend dynamically.

We hope this article is easy to understand and give you all the fundamental information about Magento 2 knockout js. In case we missed anything or need to add some information, feel free to leave a comment below, I’ll get back as soon as possible.

Don't want to miss out on our latest insights?
Subscribe to our newsletter.

Disclaimer: By clicking submit, you agree to share your information with us to receive news, announcements, and resources when they are available.