If you are a beginner who just started learning Magento or have already been working with the platform for some time, there is still 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.
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.
Table of Contents
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 read the documentation of Knockout JS.
Knockout is a Javascript library helping in the front end 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.
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.
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 are 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, a 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 of 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 the 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 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 the 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 Overrides the Knockout Template
Overriding a template is considered 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 with 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 to which the template belongs 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
- The second one is the Old deprecated method.
wishlist_index_index.xml
Magento 2 Creates the 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:
- Step 1: Create one PHTML file.
- Step 2: Create a custom component using Magento_UI/js/core/app.
- Step 3: Register New Component within Components.
- Step 4: Call out a custom component template file and pass the variable.
- Step 5: In the JS file, put the knockout library for knockout JS.
- Step 6: Return function is mandatory, thus we put it and the logic out there.
- Step 7: At the moment, data will bind with our HTML tag with the support of the data-bind attribute.
Let us see the Magento 2 knockout js examples.
- First, create a PHTML file following the below path,
app\code\Vendor\Extension\view\frontend\templates\uicomponent.phtml
- Then, create a js file following the below path,
app\code\Vendor\Extension\view\frontend\web\js\uicomponentjs.js
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 front end 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, do 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’s 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 front end dynamically. We hope this article is easy to understand and gives you all the fundamental information about Magento 2 knockout js. In case we missed anything or you need some help configuring Knockout Js in your Magento 2 store, feel free to contact our Magento experts and specialists, and we’ll get back to you as soon as possible. Additionally, we have seasoned Magento development services that can support you in all aspects of developing an eCommerce store based on the Magento platform.