Back to Top

How to Use Knockout JS on Custom Template in Magento 2

Updated 26 February 2024

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.

Searching for an experienced
Magento 2 Company ?
Find out More

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.

KnockoutJS magento 2

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.

. . .

Leave a Comment

Your email address will not be published. Required fields are marked*


3 comments

  • Mukesh Kumar Pandit
  • Banvari Lal
    • Mahesh Singh (Moderator)
  • Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home