Search code examples
javascriptgoogle-closure-librarygoogle-material-icons

Click event in event listener written in Google Closure not working?


I am new to JavaScript, My question is when I try this JS in chrome browser console it works, But in my JS file it's not working

I attached the code, For HTML design I used google MDL, For JS I used Google Closure

HTML :

<HTML>
 <head>
    <script src="../closure-library/closure/goog/base.js"></script>
    <script src="../js/add.js"></script>
    <script src="../js/material.js"></script>
    <link rel="stylesheet" href="../css/material.css">
    <link rel="stylesheet" href="../css/test_add.css">
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
 </head>
 <body>
   <div>
     <button id="add" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect">
       <i class="material-icons">add</i>
     </button>
   </div>
</body>
</HTML>

JS:

goog.provide('sample.add');

goog.require('goog.dom');
goog.require('goog.events');

sample.add = function() {
    self = this;
};
goog.inherits(sample.add, goog.base);
sample.add.prototype.bindEvent = function() {
    goog.events.listen(goog.dom.getElement('add'),
         goog.events.EventType.CLICK, function(e) {
            alert("HAPPY");
    });
};

What is wrong with this code

  1. When I try without goog.provide and goog.require its show error to all
  2. When I use this there is no reaction to the click event
  3. Is there any other best resource to see online

Kindly help me


Solution

  • So there's a few things I'd change here.

    The biggest issue is that you're never calling sample.add or sample.add.bindEvent.

    Then, your script will have to be moved to below your button, so that the button will be on the page when your script runs. Or you could use JS to delay the script running, up to you, but I will say, its pretty common to see scripts just before the end of the body tag.

    <HTML>
     <head>
        <script src="../closure-library/closure/goog/base.js"></script>
        <script src="../js/material.js"></script>
        <link rel="stylesheet" href="../css/material.css">
        <link rel="stylesheet" href="../css/test_add.css">
        <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
     </head>
     <body>
       <div>
         <button id="add" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect">
           <i class="material-icons">add</i>
         </button>
       </div>
       <script src="../js/add.js"></script>
    </body>
    </HTML>
    

    Also, I'd ditch the goog.base call, unless you specifically need that. If you do need that, please explain why and maybe we can help.

    Finally we just need a few subtle tweaks;

    goog.provide('sample.add');
    
    goog.require('goog.dom');
    goog.require('goog.events');
    /** @export */
    sample.add = function() {
        self = this;
        self.bindEvent();
    };
    sample.add.prototype.bindEvent = function() {
        goog.events.listen(goog.dom.getElement('add'),
             goog.events.EventType.CLICK, function(e) {
                alert("HAPPY");
        });
    };
    sample.add();
    

    I suppose you could call sample.add.bindEvent directly, but I felt like this was probably just the first step to something larger and you'd want to go this way.