magento2_javascript

Javascript in Magento 2, the way to do it

Magento 2 provides a standard mechanism to discourage directly embedding javascript into a page and it is actually considered a bad practice, so let’s stop embedding it.

Why?

  1. It helps to minify the javascript, so it reduces page weight and it can be cached.
  2. It can be migrated or used for other pages.
  3. Separation of concerns, therefore better maintainability.
  4. It provides a way to pass that program a server side generated JSON object.

The most frequence cases we can face are the next:

Implement script without a clear target element and without passing parameters.

Implement script with a clear target element and without passing parameters.

Implement script passing parameters.

Override a js file.

Override/Extend a widget method.

Override/Extend a component method.

 

Implement script without a clear target element and without passing parameters

Here we don’t need any requirejs config file or component. All we need is this script in our phtml template:

Note: We can also include our js file via layout (which is even more clean), however we may need in some cases js at specific templates, this last case is what we face in this example.

<script type="text/x-magento-init">
{
    "*": {
        "Namespace_Module/js/jsfilename": {}
    }
}
</script>

And at the same module we need to create our js file: Namespace/Module/view/frontend/web/js/jsfilename.js

require([],
function(){
    "use strict";
    //your js goes here
});

Implement script with a clear target element and without passing parameters

For passing a target or parameters (next section) we should create a component as follows:

1°) In the template, there are two ways:
Option 1:

<script type="text/x-magento-init">
{
    "#some-element-id": { 
        "Namespace_Module/js/jsfilename": {} 
    } 
} 
</script>

Option 2:

<div id="some-element-id" 
         data-mage-init='{"Namespace_Module/js/jsfilename":{}}'>
    <!-- some elements and content -->
</div>

2°) Into js file: Namespace/Module/view/frontend/web/js/jsfilename.js

define(
[
    'uiComponent'
],
function (Component) {
    'use strict';

    return Component.extend({

        initialize: function (config, node) {
            node; //#some-element-id
        }
    });
});

Implement script passing parameters

As mentioned in previous section, first we need this in the template:

<script type="text/x-magento-init">
{
    "#some-element-id": {
        "Namespace_Module/js/jsfilename": {"parameter":"value"} 
    } 
} 
</script>

or you may also have this in the template:

<div id="some-element-id" 
         data-mage-init='{"Namespace_Module/js/jsfilename":{"parameter":"value"}}'>
    <!-- some elements and content -->
</div>

And finally in the js file: Namespace/Module/view/frontend/web/js/jsfilename.js

define(
[
    'uiComponent'
],
function (Component) {
    'use strict';

    return Component.extend({

        initialize: function (config, node) {
            var value = config.parameter; 
            node; //#some-element-id
        }
    });
});

Override a js file:

We just need a requirejs-config.js file like the one bellow and the file Namespace/Module/view/frontend/web/js/original-file-name.js with a copy of the content which can be modified or replaced.

var config = {
    map: {
        '*': {
            'Magento_ModuleName/js/original-file-name':
            'Namespace_Module/js/original-file-name'
        }
    }
};

Override/Extend a widget method:

Using mixins, in the example the method _initContent from sidebar is overwritten.

Original file where we can find _initContent method:

module-checkout/view/frontend/web/js/sidebar.js

Our customized _initContent file path:

app/code/Namespace/Checkout/view/frontend/web/js/sidebar-mixin.js

Note: Mixin (within Magento 2 context) is a powerful feature which allows us to listen for the initial instantiation of any requirejs module and manipulate that module before returning it. This brilliant post from Alan Storm explains magnificently what there is behind mixins.

1°) We need to create requirejs-config.js with the next code

var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/sidebar': {
                'Namespace_Module/js/sidebar-mixin': true
            }
        }
    }
};

2°) Into our file sidebar-mixin.js

define([
    'jquery'
],
function($){
    'use strict';
    return function (widget) {
        $.widget('mage.sidebar', widget, {
            _initContent: function () {
                //add new functionality or extend using this._super()
            }
        });
        return $.mage.sidebar;
    }
});

Where ‚mage.sidebar‘ is just the name of your extension, widget (passed as a parameter) is the original widget, and sidebar-mixin.js is just a name and i could be something else like awesome-name.js

Override/Extend a component method:

It is quite similar to override a widget, so we use mixin in a requirejs file as follows:

var config = {
    config: {
        mixins: {
            'Magento_Ui/js/form/form': { 
                'Namespace_Module/js/form-mixin': true
            }
        }
    }
};

And then into our file form-mixin.js we can override any method of the form component, in this case we override the method initialize:

define([],
function(){
    'use strict';
    return function (Component) {
        return Component.extend({
                initialize: function () {
                //add new functionality or extend using this._super()
            }
        });
    }
});

Where form-mixin.js is just a name and i could be something else like another-awesome-name.js

Pablo Sanchez
Pablo Sanchez ist Frontend Developer bei Flagbit und gibt in seinen Beiträgen regelmäßige Einblicke in die Codeoptimierung.

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

Benachrichtige mich zu:
avatar

wpDiscuz
Weitere Beiträge zum Thema
Flagbit auf der MagentoLive Germany in München
User-Agent wechsel dich: Pfusch beim T-Online-Browser
Produktkategorien in Magento sinnvoll sortieren
Expires Header mit TYPO3