Easiest way to load your custom JS Component in Magento 2

In this post, I will be guiding you on creating a JavaScript Component and load it on any page you need.

Let's do it

Understanding the JS Components in Magento 2

  1. KnockoutJS component - 'ko'
    • Checkout page is full of knockout js bindings
  2. jQueryUI component - 'jquery/ui'
    • Add to cart on the product page & product listing page

Note: You cannot mix both the components code within a single JS component.

Technologies usage

  1. RequireJs
    • It is used for dependency management for all the javascript files
  2. KnockoutJs
    • MVVM pattern using data-bind
  3. jQuery UI Widgets
    • Create stateful jQuery plugins using the same abstraction as all jQuery UI widgets.

First create a custom module

KnockoutJS component

In your module’s web directory, create a simple.js.
Like, app/code/Aureatelabs/JSComponent/view/frontend/web/js/simple.js

define([
        'ko',
        'uiComponent'
    ],
    function(ko, Component) {
        'use strict';
        return Component.extend({
            firstName: ko.observable(''),
            initialize: function() {
                this._super();
            }
        });
    });

Create a simple.phtml file in the frontend or CMS block and add below content:

<div data-bind="scope: 'component-name'">First name:
<div><input type="text" data-bind="textInput: firstName" /></div>
</div>
<p>Notes: Magento_Ui/js/core/app - this js is responsible for binding Knockout JS components with the DOM elements then you can use ko methods. Scope attribute - it is used to chain the JS and the HTML DOM together using the knockoutjs. Component-name - Must be unique on the current page. It can be any meaningful word and could be js file name. Use same name used in the</p>

Advantages

  1. You can make use of MVVM technique via data-bind & methods of knockoutjs
  2. Assign external HTML template after js component is loaded
  3. Less dependent on jQuery and use of data-bind any elements is recommended.
  4. Changing the HTML template without modifying .PHTML template file.
  5. i18n translation supported
  6. You can set the default options if not given from the frontend
  7. Reusable code
  8. It can contain a list of components in a group like on the checkout page

Disadvantages

  1. Template is rendered after the JS is loaded in the browser and takes time to display.
  2. External html template is already loaded then the new version will be loaded from the browser cache.

jQuery UI component

This method is used to add events to the HTML element when the JS component is loaded. Here you don’t cannot use the scope binding. While your JS component will get the DOM element object to implement the logic on it.How to use
data-mage-init attribute is used to bind the HTML DOM with the JS component.
simple2.js

define([
    'jquery',
    'jquery/ui'
], function($) {
    'use strict';

    $.widget('mage.simple2', { // component name = simple2
        options: {
            text: null,
            displayEle: null
        },
        /**
         * Bind handlers to events
         */
        _create: function() {
            console.info(this.options); // print the options in console
            // Save options to the element for later
            this.element.data('options', this.options);
            // Add event and method to the element
            this._on({
                'keyup': $.proxy(this._method, this.element)
            });
        },
        _method: function() {
            // fetch the element options
            var options = this.data('options');
            $(options.displayEle).text(this.val());
        }
    });

    return $.mage.simple2; // return simple2 component
});

Then in your HTML template file use like the below:

<div>
<h2>Simple2 demo</h2>
<label> Name: <input type="text" data-mage-init="{"Aureatelabs_Simple2/js/simple2": { "text": "to-send-in-the-js-file", "displayEle": "#text"} }" /> </label>
<h2>Your text here: <small></small></h2>
</div>
<p>Notes: You can use the alias from the requirejs-config(1) or use the full path of the js file(2): For example: 1. RequireJS alias: <input type="text" data-mage-init="{"simple2": { "text": "to-send-in-the-js-file", "displayEle": "#text"} }" /> 2. RequireJS full path: <input type="text" data-mage-init="{"Aureatelabs_Simple2/js/simple2": { "text": "to-send-in-the-js-file", "displayEle": "#text"} }" /> 3. The data json inside the simple2 object is optional so you can use the empty object like: {} I.e. { "text": "to-send-in-the-js-file", "displayEle": "#text"}</p>

You will see the jQueryUI component:

Advantages

  1. You can use the jQuery UI Widget to create a component
  2. This component has a constructor function _create to initialize your logic
  3. You can set the default options if not given from the frontend
  4. You can trigger this component from the element itself so you don't have to rely on the page load using data-mage-init.
  5. Reusable code

Disadvantages

  1. You cannot use the knockout js methods and data-bind here.
  2. You cannot use it in the checkout layout customizations.


  • Share :