Revealing Module Pattern in JavaScript, Jquery, for AEM Client Libraries

This is a reference to the code that I have written. I call this my version of the perfect AEM JavaScript Jquery Component that uses the Revealing Module Pattern.

The Revealing Module Pattern in JavaScript is a design pattern that helps us organize our JavaScript in modules. This pattern makes it possible for us not to pollute the global scope, and it also ensures that the JavaScript module is running its own code as it should.

In this example, I have incorporated the best practices, and used special naming conventions, so that the code is organized, and set for scalability.

Skip to the code Example: Revealing Module Pattern in JavaScript, Jquery


Explanation of what each line does

  1. line:1 = this is a self invoking function, while passing a parameter of the window.jQuery object; all functions and variables here will be closed off from the outer scope.
  2. line:82 = on window ready, the MyComponent.init(); public method of the MyComponent will be called.
  3. “use strict” on line:3 = ‘use strict’; states that the JavaScript code should be executed in ‘strict mode’. This makes it easier to write good and secure JavaScript code.
  4. line:11 = this will be the declaration of the Module.
  5. line:13 = this is where the Constants will be used throughout the Module; here you can include the data-arribute names, HTML element classNames, modifier classnames, etc…
  6. line:20 = this is where the Module level variables will be saved;
    • variables like $myComponent, with $ as prefix, means that these variables are holding Jquery objects.
    • variables like pingUrl, with no $, means that these variables are holding standard data.
  7. line:30 = notice the init() function has no under_scores like the other function. No under_score in the function name means that this is a public function.
  8. line:31 = DO NOTHING, do not run any code when the HTML element is NOT on the page.
  9. line:32-34 = set Jquery objects and other types of data to the variables, declaration on line 20.
  10. line:36 && line:37 = here we register the open and close button.
    • functions with the under_scores, means that this is a private function.
    • functions with the without under_scores, means that this is a public function, and public functions should be exposed in line:76, from the return statement.
  11. line:45 = _registerOpenButton(), private function; this cannot be called outside of the Module.
  12. line:57 = _registerCloseButton(), private function; this cannot be called outside of the Module.
  13. line:69 = _makePingCall(), private function; this cannot be called outside of the Module.
  14. line:76 = this return declaration is used to reveal public methods that can be called by the self invoking function. In this case, only the init() function is public.

Code Example: Revealing Module Pattern in JavaScript, Jquery

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
;(function () {

    "use strict";

    /**
     * MyComponent Component
     *
     * @class MyComponent
     * @classdesc initiating javascript for the MyComponent Component.
     */

    var MyComponent = function ($) {

        var CONST = {
            DATA_ATTR_PING_URL: 'ping-url',
            OPEN_BUTTON_CLASS_NAME: '.cmp-mycomponent__open-btn',
            CLOSE_BTN_CLASS_NAME: '.cmp-mycomponent__close-btn',
            OPEN_CLASS_NAME: 'open'
        };

        var $myComponent = $('.cmp-mycomponent'),
        $openBtn,
        $closeBtn,
        pingUrl;

        /**
         * Initializes the MyComponent
         *
         * @public
         */

        function init() {
            if ($myComponent.length <= 0) return;
            $openBtn = $myComponent.find(CONST.OPEN_BUTTON_CLASS_NAME);
            $closeBtn = $myComponent.find(CONST.CLOSE_BTN_CLASS_NAME);
            pingUrl = $myComponent.data(CONST.DATA_ATTR_PING_URL);

            _registerOpenButton();
            _registerCloseButton();
        }

        /**
         * Registers open button
         *
         * @private
         */

        function _registerOpenButton() {
            $closeBtn.click(function() {
                _makePingCall();
                $myComponent.addClass(CONST.OPEN_CLASS_NAME);
            });
        }

        /**
         * Registers close button
         *
         * @private
         */

        function _registerCloseButton() {
           $closeBtn.click(function() {
                _makePingCall();
                $myComponent.removeClass(CONST.OPEN_CLASS_NAME);
            });
        }

        /**
         * Make ping call when open or close action have been made
         *
         * @private
         */

        function _makePingCall() {
            if (!pingUrl) return;
            $.ajax({
                url: pingUrl,
            });
        }

        return {
            init: init
        };

    }();

    $(function() {
        MyComponent.init();
    });

}($));

Was this post helpful?

Hello, I am an active Adobe Community Advisor & a certified Lead AEM Developer who is currently working as a Senior AEM Full Stack Developer. I have over a decade of overall web engineering experience and many years (more than 6) of AEM experience in practice. I hope to give back to the AEM Full Stack Development community by sharing my knowledge with the world.

Leave a Reply

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

Back To Top