What can we help you with?

If you are interested in finding out more about how we can help your organization, please provide your details and project requirements. We'll get back to you soon.

Knockout JS with Magento 2

Magento

Nowadays there are many JavaScript Frameworks available for web application development, which are more or less providing a very interactive way to handle any application. Frameworks such as AngularJS, NodeJS, KnockoutJS and others can even be listed in the set of the most popular and useful frameworks. From that Knockout has been used in one of top most e-commerce framework Magento with version 2.

What is Knockout.js?

Knockout.js is a JavaScript framework for application development. This library allows binding any HTML elements with the data model. As per the most of the JavaScript frameworks, we can work with both client and server side with Knockout. It can be used with any language-specific framework such as Laravel or Magento from PHP.

For web development, we usually prefer MVC approach and sometimes it depends on the framework we are using. However, Knockout.js is working with MVVM architecture design, which provides a packet of few advantages.

Knockout.js Features

  1. MVVM framework
    • Model – It represents data interaction and storing.
    • View – It is specifically that how anything should be visible to the end user.
    • View Model – It basically provides an intermediate path between Model and the View. In Knockout.js, it is mainly used for manipulating data.
  2. Auto Refresh
    Any change in either at the Model side or UI side is affecting automatically vice versa. This allows the developer to handle it without any custom logic.
  3. Templating
    Templating is a good way to represent any UI structure. Knockout is using HTML as its templating. That DOM element on template file is basically connected with Model of Knockout.js
  4. Declarative Binding
    Elements available on HTML DOM have an attribute related to Knockout.js known as data-bind, which is connected to Model specifically through that element.
  5. Dependency Tracking
    Knockout attributes and Knockout framework functions are related to each other, so when any changes are done in functions it automatically tracks the changes to Knockout attribute. In that way, it updates elements where these Knockout attributes are defined.

Usage/Example of Knockout.js in Magento 2

Knockout.js is used in Magento especially to handle some dynamic parts of the frontend. It is used for building dynamic parts in checkout and cart process in Magento 2, where each element are handled through Knockout.js and all dynamic data are bonded with a data model of Knockout.js. So any change in that will require a basic/good knowledge of Knockout.js to interact with any element of Magento 2.

To understand this more with programmatically way, we need to go through one example related to this. For this we are considering to update Shipping Estimation section which is available on cart page, this section loaded using Knockout.js and we will see how we can update or modify anything in this section.

We will display here a banner which represents that if your order more than this amount than you will get free shipping, this banner we will manage from admin side using CMS blocks.

Let’s see how we can implement such things.

Definition: Idea is to take content from CMS block and put it in the Knockout object and then to display it in frontend dynamically. Now, our content will be loaded alongside the other components.

Step: 1

Create a simple Magento module as (Demo/Knockout). Get a better idea for this from https://www.mageplaza.com/magento-2-module-development/

Step: 2

Create a block from Admin side under Admin > Content > Block
Set identifier for this block as “shipping_discount”, see the screen as below.

We can write any content in this block, which can be possibly displayed on the frontend. In our example, we will upload one free shipping banner image to display it in the frontend.

Knockout.js in Magento 2

Step: 3

Setup ConfigProvider dependencies using di.xml
File: Demo/Knockout/etc/frontend/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
   <type name="Magento\Checkout\Model\CompositeConfigProvider">
       <arguments>
           <argument name="configProviders" xsi:type="array">
               <item name="cms_block_config_provider" xsi:type="object">Demo\Knockout\Model\ConfigProvider</item>
           </argument>
       </arguments>
   </type>
   <type name="Demo\Knockout\Model\ConfigProvider">
       <arguments>
           <argument name="blockId" xsi:type="string">shipping_discount</argument>
       </arguments>
   </type>
</config>

This code will add shipping discount block in config-provider, where shipping_discount is a block created on admin side as shown in step 2.

Step: 4

Create config provider file
File: Demo/Knockout/Model/ConfigProvider.php

<?php namespace Demo\Knockout\Model; use Magento\Checkout\Model\ConfigProviderInterface; use Magento\Cms\Block\Widget\Block; class ConfigProvider implements ConfigProviderInterface { protected $cmsBlockWidget; public function __construct(Block $block, $blockId) { $this->cmsBlockWidget = $block;
       $block->setData('block_id', $blockId);
       $block->setTemplate('Magento_Cms::widget/static_block/default.phtml');
   }
 
   public function getConfig()
   {
       return [
           'cms_block' => $this->cmsBlockWidget->toHtml()
       ];
   }
}

Step: 5

In this step, we will define the mapping of override knockout template file shipping-estimation.html in our module using require-js.

File : Demo/Knockout/view/frontend/requirejs-config.js

var config = {
    map: {
        '*': {
          'Magento_Checkout/template/cart/shipping-estimation.html': 
              'Demo_Knockout/template/cart/shipping-estimation.html'
        }
  }
};

Step: 6

Modify the content of shipping-estimation by updating content in our overwrite file.
File: Demo/Knockout/view/frontend/web/template/cart/shipping-estimation.html

<div data-bind="html: window.checkoutConfig.cms_block"></div>
 
<form method="post" id="shipping-zip-form">
    <fieldset class="fieldset estimate">
        <legend class="legend">
            <span data-bind="text: isVirtual ? $t('Estimate Tax') : $t('Estimate Shipping and Tax') "></span>
        </legend><br>
        <p class="field note" data-bind="text: isVirtual ? $t('Enter your billing address to get a tax estimate.') : 	$t('Enter your destination to get a shipping estimate.')"></p>
        <!-- ko foreach: getRegion('address-fieldsets') -->
        <!-- ko template: getTemplate() --><!-- /ko -->
        <!--/ko-->
    </fieldset>
</form>

Here, at the beginning of the file, we have added our div which binds content added in checkoutConfig using knockout js method “data-bind”. Data-bind will work to connect with Model of Knockout.js as mentioned in starting of this article.

We are done with our code part and we can now see that block created on admin side in shipping estimation section on cart page.

As standard, we will run the following command to enable the module and deploy content

1) php bin/magento module:enable Demo/Knockout
2) php bin/magento setup:upgrade
3) php bin/magento setup:static-content:deploy

With this, we will get the output as below screen, where FREE SHIPPING is the banner which we have uploaded on admin block and is displayed here by our module.
Magento 2
These are the basic and standard way to use Knockout.js in Magento and using that we can update any data in the required portion of Magento. It is a very useful way to manipulate any data in these Knockout connected files.