Knockout Javascript in Magento 2– In this blog, we will learn about Knockout JS integration with Magento 2.
Magento 2 (adobe commerce) uses Knockout JS heavily on various front-end component. Cart management is the best example of The Knockout JS implementation.
At the shopping cart there are multiple level of changes are happening. Example
- price calculation
- quantity based price manipulation
- coupon management
- taxes calculation
- and shipping rate calculation
All is happening in one single screen. Knockout.js manages all those manipulation using a standard MVVM(model view view-model )concept.
How to use Knockout JS on the custom template in Magento 2
In Magento 2 main chunk of Knockout JS is in use on the checkout page. However, you have no restriction to use knockout JS on the Checkout page only. As a developer, we can Initialize Knockout JS on our custom module’s template files.
1. Create a template phtml file.
File:// Webkul/Knockout/view/frontend/templates/account/knockout.phtml
Create XML file to load this phtml file.
<?xml version="1.0"?>
<!--
/**
* Webkul Software.
*
* @category Webkul
* @package Webkul_Knockout
* @author Webkul
* @copyright Copyright (c) 2010-2023 Webkul Software Private Limited (https://webkul.com)
* @license https://store.webkul.com/license.html
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<update handle="customer_account"/>
<body>
<referenceContainer name="content">
<block class="Magento\Framework\View\Element\Template" name="customer_account_knockout_test" template="Webkul_Knockout::account/knockout.phtml" cacheable="false"/>
</referenceContainer>
</body>
</page>
Now open the phtml file, Webkul/Knockout/view/frontend/templates/account/knockout.phtml to define KO initialization.
<div id="custom-component" data-bind="scope:'customcomponent'">
<!-- ko template: getTemplate() --><!-- /ko -->
<script type="text/x-magento-init">
{
"#custom-component": {
"Magento_Ui/js/core/app": {
"components": {
"customcomponent": {
"component": "Webkul_Knockout/js/custom-component"
}
}
}
}
}
</script>
</div>
Now take a closer look at above defined code.
M2 Initialize Js components by
<script type="text/x-magento-init">
When M2 initialize component, it first looks for the component id (which id #custom-component in our case.).
Next you can see div element has attribute data-bind=”scope:’customcomponent'” Its shows that all the components initialized will load within this scope. you can find the key customcomponent with the same name within
<div id="custom-component" data-bind="scope:'customcomponent'"></div>
Now create component js file which we have defined in our “component”: key
File:// Webkul/Knockout/view/frontend/web/js/custom-component.js
define(['jquery', 'uiComponent', 'ko'], function ($, Component, ko) {
'use strict';
return Component.extend({
defaults: {
template: 'Webkul_Knockout/knockout-test'
},
initialize: function () {
this._super();
}
});
}
);
We can see above View-Model has a dependency, which extends all the KO components. uiCompoent file is Magento_Ui/js/lib/core/collection.js.
Now Create template file which we have defined in our custom-component.js View-Model.
File:// Webkul/Knockout/view/frontend/web/template/knockout-test.html
<div class="component-wrapper">
<div data-bind="text: 'Knockout Works'"></div>
</div>
Now clear the cache, run the M2 static-content: deploy command, and hit this phtml template you will see a text Knockout Works.
Let’s use some observable data binding
Open the Model file which we created before Webkul/Knockout/view/frontend/web/js/custom-component.js
Update it with the below code:
define(['jquery', 'uiComponent', 'ko'], function ($, Component, ko) {
'use strict';
return Component.extend({
defaults: {
template: 'Webkul_Knockout/knockout-test'
},
initialize: function () {
this.customerName = ko.observableArray([]);
this.customerData = ko.observable('');
this._super();
},
addNewCustomer: function () {
this.customerName.push({name:this.customerData()});
this.customerData('');
}
});
}
);
Now open html template file Webkul/Knockout/view/frontend/web/template/knockout-test.html
Update it with the below code.
<div class="component-wrapper">
<div class="field">
<label class="label" for="email"><span data-bind="i18n: 'New Customer'"></span></label>
<div class="control">
<input name="customername"
id="customername"
type="text"
class="input-text"
data-bind="value: customerData">
</div>
</div>
<div class="primary">
<button type="button" class="action action-login secondary" data-bind="click: addNewCustomer">
<span data-bind="i18n: 'Save'"></span>
</button>
</div>
<div class="customer-list" style="width: 20%;background: gray;margin-top: 10px;" data-bind="foreach: customerName">
<li data-bind="text: name"></li>
</div>
</div>
Again refresh cache and check.
Now you will see a text box for Enter Customer Name, and Button. When add a customer it will be listed below.

In JS model we use ko.ObservableArray([]) & ko.obervable() , both uses to update UI automatically if they detect changes in the view model.
In our example when you press the save button obervableArray’s value gets updated and in revert List of Customers gets update.
3 comments