Tor
Tor

Reputation: 21

eventListener on table not working

I'm making a calculator and I'm stumbling at the first JS hurdle. I'm trying to set up event listeners on the number buttons so that a functions runs on click, but I get the error that I can't set up an event handler on null. But I can't see where I am going wrong!?

I am trying to organise my code as I go along similar to an online course that I did - separating out all the functions and trying to keep it easy to read.

See code and thanks in advance:

//TOTAL CONTROLLER
var totalController = (function () {

})();

//UI CONTROLLER
var UIController = (function () {

    var DOMstrings = {
        calcbuttons: '.calcButtons',
        number: '.number',
        operator: '.operator',
        equals: '.equals',
        total: '#total'
    };

    return {

        getDOMstrings: function () {
            return DOMstrings;
        }
    };

})();


//GLOBAL CONTROLLER
var controller = (function (totalCTRL, UICtrl) {

    var setupEventListeners = function () {
        var DOM = UICtrl.getDOMstrings();

        var el = document.querySelector(".calcButtons");

        el.addEventListener('click', function (e) {
            //var table = e.target;
            //if (table.classList) 

            console.log(e);
            //ctrlAddNumber();

        });

        // click operator
        //click C
        //click AC
        //click equals

    };

    var ctrlAddNumber = function () {
        var selectedNumber;

        //1. get number from html from click
        selectedNumber = document.querySelector(DOM.number).innerHTML;
        console.log(number);
        //2. add to display

    };

    return {
        init: function () {
            console.log('Application has started.');
            setupEventListeners();
        }
    };

})(totalController, UIController);

controller.init();
<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
    <link type="text/css" rel="stylesheet" href="calc_style.css" />
    <style>
        @import url('https://fonts.googleapis.com/css?family=Lato');
    </style>
    <script type='text/javascript' src='calcjs.js'></script>
    <title>JavaScript Calculator</title>
</head>
<body>
    <div id="container">
        <div id="calculator">
            <div id=t otal></div>

            <table class="calcButtons" cellspacing="0" cellpadding="0">
                <tr>
                    <td class="wide">AC</td>
                    <td class="wide">&larr;</td>
                    <td class="wide"></td>
                    <td class="operator"></td>
                </tr>
                <tr>
                    <td class="number">7</td>
                    <td class="number">8</td>
                    <td class="number">9</td>
                    <td class="operator">&#247;</td>
                </tr>
                <tr>
                    <td class="number">4</td>
                    <td class="number">5</td>
                    <td class="number">6</td>
                    <td class="operator">&#215;</td>
                </tr>
                <tr>
                    <td class="number">1</td>
                    <td class="number">2</td>
                    <td class="number">3</td>
                    <td class="operator">-</td>
                </tr>
                <tr>
                    <td class="number">0</td>
                    <td>.</td>
                    <td id="equals" class="equals">=</td>
                    <td class="operator">&#43;</td>
                </tr>
            </table>

        </div>
    </div>
</body>
</html>

Upvotes: 2

Views: 918

Answers (1)

Thijs
Thijs

Reputation: 2351

A couple of things:

  • Move your JS out of the head and just below where you close the body. The script tag is blocking and the browser won't continue with rendering your site till it has processed the script element.
  • If you want an element to be interactive, try to use an element that was meant for it. Use an anchor (a) element to navigate betweens documents and buttons (button) for most other interactions.
  • An HTML table needs a tbody.
  • Your JS code is quite a lot and I didn't have time to go through all of it so I made this small example on how it could work. I hope you can translate it to your situation.

const
  calcButtons = document.querySelector('.calcButtons');
  

function onCalcButtonClicked(event) {
    debugger;  
  const
    clickedButton = event.target;

  if (clickedButton.hasAttribute('data-number')) {
    console.log('The user inputted a number: ', clickedButton.getAttribute('data-number'));
  } else if (clickedButton.hasAttribute('data-action')) {
    console.log('The user selected an action: ', clickedButton.getAttribute('data-action'));
  }
}


calcButtons.addEventListener('click', onCalcButtonClicked);
<div id="container">
    <div id="calculator">
        <div id="total"></div>

        <table class="calcButtons" cellspacing="0" cellpadding="0">
            <tbody>
                <tr>
                    <td><button type="button" data-action="" class="wide">AC</button></td>
                    <td><button type="button" data-action="" class="wide">&larr;</button></td>
                    <td><button type="button" data-action="" class="wide"></button></td>
                    <td><button type="button" data-action="" class="operator"></button></td>
                </tr>
                <tr>
                    <td><button type="button" data-number="7" class="number">7</button></td>
                    <td><button type="button" data-number="8" class="number">8</button></td>
                    <td><button type="button" data-number="9" class="number">9</button></td>
                    <td><button type="button" data-action="plus" class="operator">&#247;</button></td>
                </tr>
                <tr>
                    <td><button type="button" data-number="4" class="number">4</button></td>
                    <td><button type="button" data-number="5" class="number">5</button></td>
                    <td><button type="button" data-number="6" class="number">6</button></td>
                    <td><button type="button" data-action="times" class="operator">&#215;</button></td>
                </tr>
                <tr>
                    <td><button type="button" data-number="1" class="number">1</button></td>
                    <td><button type="button" data-number="2" class="number">2</button></td>
                    <td><button type="button" data-number="3" class="number">3</button></td>
                    <td><button type="button" data-action="minus" class="operator">-</button></td>
                </tr>
                <tr>
                    <td><button type="button" data-number="0" class="number">0</button></td>
                    <td><button type="button" data-number=".">.</button></td>
                    <td><button type="button" data-action="equals" id="equals" class="equals">=</button></td>
                    <td><button type="button" data-action="divide" class="operator">&#43;</button></td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

Upvotes: 1

Related Questions