How to add custom javascript in Magento 2 with requireJS
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:
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:
<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 🙂 .
If this or anything else regarding Magento development confuses you, we will gladly check out your site and offer technical insights on what to improve based on our detailed custom report. Feel free to get in touch!