dev-vp
dev-vp

Reputation: 13

Unable to get value using DOM

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;
};

Upvotes: 1

Views: 544

Answers (3)

Mister Jojo
Mister Jojo

Reputation: 22265

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

Upvotes: 0

AHT Cloud
AHT Cloud

Reputation: 51

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>

Upvotes: 0

Roko C. Buljan
Roko C. Buljan

Reputation: 205979

  • 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>

Upvotes: 3

Related Questions