How to add custom javascript in Magento 2 with requireJS

requirejs_js_m2_featured

Magento 2 brings some new features in javascript. One of them is “requireJS” (javascript file loader) and second is “jQuery“, a very popular js library. One of the biggest benefits is using requireJS which means that Magento 2 is ready for the upcoming HTTP2 protocol. In the next few steps we will explain how to create valid javascript code for use in requireJS. Let’s start with an example.

As usual, we need to create a valid Magento 2 module like seen on the screen shoot below:

js_modul

You may notice some differences between Magento 1 and Magento 2 in the fact that all javascript, layout and template phtml files now belong to the module. Also, our javascript files are in our module located on the directory path: “app/code/Inchoo/Js/view/frontend/web/js/“. For this example we created two js files: “inchoo.js” and “logger.js

Take a look at our javascript code which is valid for using in requireJS environment.

define([
    "jquery",
    "logger",
    "jquery/ui"
], function($, logger) {
    "use strict";
    logger.log('inchoo.js is loaded!!');
    logger.log(logger);
 
        //creating jquery widget
        $.widget('inchoo.js', {
            _create: function() {
 
                //options which you can pass from js.phtml file in json format
                logger.log(this.options);
 
                //access to element p#test
                logger.log(this.element);
 
                //for exmple, you can create some click event or something else
                this.element.on('click', function(e){
                    logger.log("You click on element: " + e.target);
                });
            }
 
        });
 
    return $.inchoo.js;
});

You will notice that the javascript code on the top uses “define” function.

This function is from requireJs – first parameter of “define” function is array of dependency and second parameter is definition of our function.
Definition function should always return an object. In our example our function returns “$.inchoo.js”.
You can read more about define function on url: http://requirejs.org/docs/api.html#define

In our example, our javascript uses jQuery, jQueryUI and logger. All dependency should be declared in “define” function. You can see that we put as the first argument next array:

["jquery", "logger", "jquery/ui"]

In definition of our function we created jquery widget and we put all logic in widget constructor “_create“. JQuery and logger are passed as next parameters: “$” and “logger”.

Source code of our logger class is below. You can notice that our class doesn’t need any dependency and that in “define” function there’s only definition function which returns object as we mentioned before.

define(function() {
    "use strict";
 
    return {
        log : function(param){
            console.log(param);
        }
    };
});

All files should be declared in “requirejs-config.js” file – this is config file which uses requireJs.

var config = {
    map: {
        '*': {
            inchoojs:      'Inchoo_Js/js/inchoo',
            logger:      'Inchoo_Js/js/logger'
        }
    }
};

Next step will be to explain how to load and use our javascript. In order to use/load our javascript, you have to add the next code in some phtml file. Our complete example of js.phtml file is below:

<div>
     <p id="test">Test element</p>
</div>
<script type="text/x-magento-init">// <![CDATA[
{ "#test": { "Inchoo_Js/js/inchoo": {"url":"http://www.example.url", "method":"post"} } }
// ]]></script>

In Magento 2 there is a javascript parser (located in script “lib/web/mage/apply/scripts.js”) which reads script tags with attribute type=”text/x-magento-init” and load/process them with “child” json data in curly brakets:

"#test": {
            "Inchoo_Js/js/inchoo":
                {"url":"http://www.example.url", "method":"post"}
	}

You will notice “#test“, this is id of html element which is passed to jquery widget and it is available in our script, over property “this.element“. Other elements “url” and “method” are options which are also passed from json object to our widget and these options are available in the script over js property “this.options“. These options can be defined as you want.

If you did everything as above, javascript should work and you should have a script tag in html head like in a screen shot below 🙂 .

javascript


About Domagoj Potkoc

Backend Developer

Domagoj is Magento Certified Developer who enjoys playing tennis after long hours in front of computer screen.

Read more posts by Domagoj / Visit Domagoj's profile

10 comments

    1. How are you loading the js.phtml? What little magic piece am I missing? YES, what goes in the default.xml? Obviously not a block because you didn’t include any block classes. Doesn’t requirejs-config.js have to go in /frontend and not frontend/web to get it to actually load?

  1. hmm. It`s strange because I have problem with .phtml step
    //
    still getting errors about :
    Uncaught SyntaxError: Unexpected token /
    two slashes before CDATA are causing this error.
    Any ideas why ?

    1. Got this solved by removing comments.

      I had something like this
      “componentName”: {} //comment

      taking the co
      “componentName”: {}

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.