1

I am new to Javascript and learning to build a calculator as my first project. I don't understand why I am unable to get the value from the display to pass through the function via DOM. I've looked at other examples with a similar implementation, but don't understand why mine does not work. Can someone help explain this to me?

HTML:

<form class="output-wrapper" name="output-wrapper"> <input type="text" name="display" disabled> <div class="calc-btn-wrapper"> <div class="nmb-btn container"> <button type="button" value="1" onclick="calcfunc(1)">1</button> <button type="button" value="2" onclick="calcfunc(2)">2</button> <!-- ... --> <!-- ... --> </form> 

JavaScript:

function calcfunc (num){ var display = document.form['output-wrapper']['display'].value; if (display ==="" || display===0){ let newvalu = display+num; document.form['output-wrapper']['display'].value=newvalu; }; 
3
  • typo - you want document.forms, not document.form. Commented Aug 31, 2020 at 21:52
  • 1
    the developer console is your friend.... Commented Sep 1, 2020 at 0:39
  • On a side note, your code looks quite "old school". Look for some more modern tutorials. Try and avoid inline javascript event handlers, and look for more modern ways of referencing elements : getElementById, querySelector, querySlectorAll , getElementsByClassName etc. Commented Sep 1, 2020 at 1:51

3 Answers 3

3
  • Should be document.forms (plural!)
  • Input values are always Strings! Use parseFloat() and parseInt() to convert a string to the desired.

function calcfunc(num) { var display = parseFloat(document.forms['output-wrapper']['display'].value) || 0; let newvalu = display + num; document.forms['output-wrapper']['display'].value = newvalu; }
<form class="output-wrapper" name="output-wrapper"> <input type="text" name="display" disabled> <div class="calc-btn-wrapper"> <div class="nmb-btn container"> <button type="button" value="1" onclick="calcfunc(1)">1</button> <button type="button" value="2" onclick="calcfunc(2)">2</button> </div> </div> </form>

Anyways, you should use class, IDs, and data-* attributes, and try never to use inline JavaScript handlers, just as you (hopefully) don't use inline CSS. JS should be in one place only, easy to debug - and that's your script file of tag.

const EL = document.querySelector("#calculator"); const EL_display = EL.querySelector("#display"); const ELS_int = EL.querySelectorAll("[data-int]"); function calcfunc() { const int = parseInt(this.dataset.int); const display = parseFloat(EL_display.value) || 0; const newValue = int + display; // ...only adding? :) EL_display.value = newValue; } ELS_int.forEach(btn => btn.addEventListener("click", calcfunc));
<form id="calculator"> <input type="text" id="display" disabled> <div class="calc-btn-wrapper"> <div class="nmb-btn container"> <button type="button" data-int="1">1</button> <button type="button" data-int="2">2</button> </div> </div> </form>

Sign up to request clarification or add additional context in comments.

Comments

0

There are few issues with your implementation.

Your input field is disabled. So the user cannot modify it.

 <input type="text" name="display" disabled> 

Also, consider using type number instead. Remember, type text will return a string so you will need to convert it to an integer or float.

<input type="text" type="text" name="display" disabled> 

Another issue is that output-wrapper is not a form. Its a div. So you cannot use javascript to index a form while its a div.

Here is an idea, that shows you how to add 2 numbers. Also shows you how to get and set values rather than trying to pass them in the click method parameter.

-

function add() { let inputA = document.getElementById("inputA"); let inputB = document.getElementById("inputB"); let inputC = document.getElementById("result"); inputC.value = parseInt(inputA.value) + parseInt(inputB.value); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form class="output-wrapper" name="output-wrapper"> <input type="text" id="inputA" name="inputA"> <input type="text" id="inputB" name="inputB"> <input type="text" id="result" name="result"> <div class="calc-btn-wrapper"> <div class="nmb-btn container"> <button type="button" value="1" onclick="add()">Add</button> </div> </div> </form>

Comments

0

the more simple is to use event delegation:

const zDisplay = document.getElementById('display') , zButtons = document.querySelector('div.nmb-btn') ; zButtons.onclick =e=> { if (!e.target.matches('button[data-int]')) return zDisplay.value += e.target.dataset.int }
<input type="text" id="display" disabled> <div class="calc-btn-wrapper"> <div class="nmb-btn container"> <button data-int="1">1</button> <button data-int="2">2</button> </div> </div>

see: event.stopPropagation() not working - Capturing still passes on function

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.