Magento 2 : How to use Javascript in Magento

Updated . Posted . Visible to the public.

Javascript in Magento 2

Magento 2 uses Require JS lib and Knockout JS lib to solve the page speed and manage the JS dependency.

As JS are loaded asynchronously in backend, it helps to increase the page speed.

The JS files can be found in following locations :

lib/web
view/area/web
theme/module/web
theme/web

Magento 2 uses requirejs-config.js in module view/area/ folder to map the JS file with alias.

Magento 2 declares JS using following ways :

data-mage-init
<script type="text/x-magento-init"> ........... </script>
<script> only widgets with requireJS </script> 

The customization can be done to modify the existing JS file in following files

  • layout xml file (for static config)
  • component and template (JS + HTML)
  • Layout Processor (for dynamic config)
  • Config Provider (to pass the config data to JS)

Simple JS declaration in phtml

<script type="text/x-magento-init">
    {
        "*":
            {
            "LearnKo_FirstKo/js/firstko_wayone":
                {
                    "name": "Vasan"
                }
            }
    }
</script>

JS file declaration with alias in phtml

<div data-mage-init='{"waytwo": {"name": "Suresh"}}'>

Example of reuirejs-config.js

var config = {
    map: {
        "*": {
            waytwo: "LearnKo_FirstKo/js/firstko_waytwo"
        }
    }
};

The waytwo.js file like as follows

define([
    "jquery"
], function($) {
    "use strict";

    return function (options, element) {
        $(element).click(function (event) {
            //window.open(options['path']);
            alert(options['suresh']);
        });
    };

});

Following example show the how to use the component and template in Magento 2 to display data with binding

secondko_booklists.js

define(['jquery', 'uiComponent', 'ko'],
    function ($, Component, ko) {
        'use strict';
        return Component.extend({
            defaults: {
                template: 'LearnKo_SecondKo/booklists'
            },
            initialize: function () {
                this._super();
                this.booknamelist = ko.observableArray([]);
                this.bookname = ko.observable('');
            },

            addNewBook: function () {
                this.booknamelist.push({name:this.bookname()});
                this.bookname('');
            }


        });
    }
);

booklists.html

<div class="component-wrapper">
    <div class="field">
        <label class="label" for="book"><span data-bind="i18n: 'New Book'"></span></label>
        <div class="control">
            <input name="book"
                   id="book"
                   type="text"
                   class="input-text"
                   data-bind="value: bookname">
        </div>
    </div>
    <div class="primary">
        <button type="button" class="action action-login secondary" data-bind="click: addNewBook">
            <span data-bind="i18n: 'Save'"></span>
        </button>
    </div>

    <div class="list" style="width: 20%;background: gray;margin-top: 10px;" data-bind="foreach: booknamelist">
        <li data-bind="text: name"></li>
    </div>
</div>

Following example shows how to customize checkout page

checkout_index_index.xml

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
    <referenceBlock name="checkout.root">
        <arguments>
            <argument name="jsLayout" xsi:type="array">
                <item name="components" xsi:type="array">
                    <item name="checkout" xsi:type="array">
                        <item name="children" xsi:type="array">
                            <item name="steps" xsi:type="array">
                                <item name="children" xsi:type="array">
                                    <item name="billing-step" xsi:type="array">
                                        <item name="children" xsi:type="array">
                                            <item name="payment" xsi:type="array">
                                                <item name="children" xsi:type="array">
                                                    <item name="beforeMethods" xsi:type="array">
                                                        <item name="children" xsi:type="array">
                                                            <item name="orderlist" xsi:type="array">
                                                                <item name="component" xsi:type="string">LearnKo_ThirdKo/js/payment_aggreement</item>
                                                                <item name="config" xsi:type="array">
                                                                    <item name="template" xsi:type="string">LearnKo_ThirdKo/payment_aggreement</item>
                                                                    <item name="isVisble" xsi:type="boolean">false</item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </item>
            </argument>
        </arguments>
    </referenceBlock>


    </body>
</page>

js file

define(['jquery', 'uiComponent', 'ko'],
    function ($, Component, ko) {
        'use strict';
        return Component.extend({
            initialize: function () {
                this._super();
                this.isVisble = ko.observable(true);

            }
        });
    }
);

html file

<div class="component-wrapper">

    <div class="primary">
        <div data-bind="visible: isVisble">
            <span data-bind="i18n: 'Increase (+)'"></span>
        </div>
    </div>
</div>

How to pass the data to custom checkout component

Steps

1.Define config provider in /etc/frontend/di.xml

<type name="Magento\Checkout\Model\CompositeConfigProvider">
        <arguments>
            <argument name="configProviders" xsi:type="array">
                <item name="userStoreLists" xsi:type="object">Vasan\CheckoutNote\Model\CheckoutNoteConfigProvider</item>
            </argument>
        </arguments>
    </type>

2.Create ConfigProvider in Model

namespace Vasan\CheckoutNote\Model;


use Magento\Checkout\Model\ConfigProviderInterface;

class CheckoutNoteConfigProvider implements ConfigProviderInterface
{

    public function getConfig()
    {
        $config = [];
        $userStoreList = [];
        $userStoreList[] = ['label' => 'BAGS001' , 'value' => 'BAGS001'];
        $userStoreList[] = ['label' => 'BAGS002' , 'value' => 'BAGS002'];
        $userStoreList[] = ['label' => 'BAGS003' , 'value' => 'BAGS003'];
        $userStoreList[] = ['label' => 'BAGS004' , 'value' => 'BAGS004'];

        $config['user_store_list'] = $userStoreList;

        return $config;
    }
}

3.Call the ConfigProvider in JS and Html

define(
    [
        'jquery',
        'ko',
        'uiComponent',
        'Vasan_CheckoutNote/js/action/save-checkout-note',
        'Magento_Checkout/js/model/quote'
    ],
    function ($, ko, Component, saveOrderCheckoutNote, quote) {
        'use strict';
        var configValues = window.checkoutConfig;
        console.log(configValues.user_store_list);
        return Component.extend({
            defaults: {
                template: 'Vasan_CheckoutNote/checkout_note',

                userStoreList: configValues.user_store_list,
                selectedUserStore: '',
                userNotes: ''
            },

            initObservable: function () {
                return this._super().observe(['selectedUserStore', 'userNotes'])
            },

            saveCheckoutNote: function () {
                var userNotes = this.userNotes();
                var userStore = this.selectedUserStore();
                saveOrderCheckoutNote.save(userStore, userNotes);
            },

            getUserStoreList: function () {
                return configValues.user_store_list;
            }
        });
    }
);

<div class="order-checkout-note-wrapper">
    <div class="field">
        <label class="label" for="user_store">
            <span data-bind="i18n: 'Add User Store'"></span>
        </label>
        <select id="user_store" data-bind="
        optionsValue: 'value',
        optionsText: 'label',
        value: selectedUserStore, options: getUserStoreList()"> </select>

        <label class="label" for="user_notes">
            <span data-bind="i18n: 'Add User Notes'"></span>
        </label>
        <input type="textarea"
               class="input-text"
               id="user_notes"
               data-bind="value: userNotes"
               placeholder="Notes"
        />

        <div class="primary">
            <button type="button" class="action secondary" data-bind="click: saveCheckoutNote">
                <span data-bind="i18n: 'Submit Notes'"></span>
            </button>
        </div>
    </div>
</div>

How to debug js issue with chrome?

Steps

  1. Open the Js file which through the in chrome developer tool
  2. Add the debugger point before the error and investigate the issue.
  3. Check the call stack to identify previous file which trigger this js method.

How to pass additional data in magento 2 shipping estimation?

Steps

  1. Check the ajax request of the shipping estimation
  2. Identify how to pass the additional data to model js of shipping.
vasan
Last edit
vasan
Keywords
Magento, 2
Posted by vasan to vasan's deck (2018-12-03 04:58)