-1

UPDATE so here is a better code for you. I cut it down to have only what's strictly necessary for you to reproduce the problem.

// change the color of the button when mousedown/up

let button = document.getElementsByClassName('button');
  for(i = 0; i < button.length; i++){
    button[i].onmousedown = function() {
      this.style.backgroundColor = "#a3a3a3";
    };

    button[i].onmouseup = function() {
      this.style.backgroundColor = "#808080";
    };
}

let buttonLg = document.getElementsByClassName('button-lg');
  for(i = 0; i < buttonLg.length; i++){
    buttonLg[i].onmousedown = function() {
      this.style.backgroundColor = "#a3a3a3";
    };

    buttonLg[i].onmouseup = function() {
      this.style.backgroundColor = "#808080";
    };
}

let button2 = document.getElementsByClassName('button2');
  for(i = 0; i < button2.length; i++){
    button2[i].onmousedown = function() {
      this.style.backgroundColor = "#ffe299";
    };

    button2[i].onmouseup = function() {
      this.style.backgroundColor = "#ffca47";
    };
}

// show the numbers typed or result

let result = document.getElementById('result');

let preview = [];


let buttonAc = document.getElementById('ac');
let plusMinus = document.getElementById('plus-minus');
let plusMinus2 = document.getElementById('plus-minus2');

let buttonN7 = document.getElementById('seven');
let buttonN72 = document.getElementById('seven2');
let buttonN8 = document.getElementById('eight');
let buttonN82 = document.getElementById('eight2');
let buttonN9 = document.getElementById('nine');
let buttonN92 = document.getElementById('nine2');


// button AC erasing result and changing outlook to C when other buttons are clicked
// number 0 disapear when there is only zero and when a key is clicked

buttonAc.onclick = function () {
  buttonAc.innerHTML = "AC";
  preview = [];
  result.innerHTML = 0;
}

// concatenation of the buttons numbers without any commas

buttonN7.onclick = function () {
  document.getElementById('ac').innerHTML = "C";
  buttonN7 = 7;
  preview.push(buttonN7);
  const a = preview.join('');
  result.innerHTML = a;
}

buttonN8.onclick = function () {
  document.getElementById('ac').innerHTML = "C";
  buttonN8 = 8;
  preview.push(buttonN8);
  const a = preview.join('');
  result.innerHTML = a;
}

buttonN9.onclick = function () {
  document.getElementById('ac').innerHTML = "C";
  buttonN9 = 9;
  preview.push(buttonN9);
  const a = preview.join('');
  result.innerHTML = a;
}

// positive to negative value and vice versa with the plus, minus key

plusMinus.onclick = function(){

  let a = preview.join('');
  let b = parseInt(a, 10);
  let c = b * -1;

  result.innerHTML = c;
  plusMinus.style.display = "none";
  plusMinus2.style.display = "block";

  //this code below works
  //document.getElementById('nine').style.display = "none";
  
  //that one does not work
  buttonN9.style.display = "none";
  
  buttonN92.style.display = "block";
}

plusMinus2.onclick = function(){

  let a = preview.join('');
  let b = parseInt(a, 10);
  let c = b * -1;

  result.innerHTML = b;
  plusMinus2.style.display = "none";
  plusMinus.style.display = "block";
}

buttonN92.onclick = function(){
  result.innerHTML = 0;
  preview = [];
  
  //this code below works
  //document.getElementById('nine').style.display = "block";
  
  //that one does not work
  buttonN9.style.display = "block";
  
  buttonN92.style.display = "none";
}
h1 {
  padding: 30px;
}

.result {
  font-size: 80px;
  border: 2px solid #000;
  color: #f9f9f9;
  padding-right: 20px;
  background-color: #696969;
}

.row1 {
  border: 2px solid #000;
}

.button,
.button2,
.button-lg {
  width: 25%;
}

p {
  cursor: pointer;
}

#ac,
#plus-minus,
#plus-minus2,
#percentage,
#seven,
#eight,
#nine,
#seven2,
#eight2,
#nine2 {
  font-size: 40px;
  background-color: #808080;
  color: #f9f9f9;
  height: 140px;
  padding-top: 50px;
  margin-bottom: 0px;
  border-right: 1px solid #696969;
}

#ac,
#plus-minus,
#percentage,
#seven,
#eight,
#nine {
  display: block;
}

#plus-minus2,
#seven2,
#eight2,
#nine2 {
  display: none;
}

#division,
#multiplication{
  font-size: 40px;
  background-color: #ffca47;
  color: #f9f9f9;
  height: 140px;
  margin-bottom: 0px;
  padding-top: 50px;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
    <title>Calculator</title>
  </head>
  <body>
    <h1 class="text-center">Calculator</h1>

    <div class="container">
      <div class="row">
        <div class="col-xl-12">
          <h5 id="result" class="card-title text-right result">0</h5>
        </div>
      </div>
      <div class="row">
        <div class="col-xl-12">
          <div class="card-group row1">
            <p id="ac" class="card-text text-center button">AC</p>
            <p id="plus-minus" class="card-text text-center button">+ | -</p>
            <p id="plus-minus2" class="card-text text-center button">+ | -</p>
            <p id="percentage" class="card-text text-center button">%</p>
            <p id="division" class="card-text text-center button2">/</p>
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-xl-12">
          <div class="card-group row2">
            <p id="seven" class="card-text text-center button">7</p>
            <p id="seven2" class="card-text text-center button">7</p>
            <p id="eight" class="card-text text-center button">8</p>
            <p id="eight2" class="card-text text-center button">8</p>
            <p id="nine" class="card-text text-center button">9</p>
            <p id="nine2" class="card-text text-center button">9</p>
            <p id="multiplication" class="card-text text-center button2">X</p>
          </div>
        </div>
      </div>
    </div>
    <script type="text/javascript" src="script.js"></script>
    <script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
  </body>
</html>

So here is the idea: It's a calculator, so I opened my calculator from my iMac and I just checked the behavior to try to reproduce it.

What you can do: - clicking on the number, showing them on the screen result. - Clicking on AC make the button change to C and clear the screen result. - Clicking on %, / and X makes nothing yet. - Clicking on "+|-" swap the number to it's minus.

Here is what I'm trying to do. Normally, when you click the "+|-" key several time, it's going from negative to positive etc. ... and, normally if you click on a number it should go back to 0. I tried first with an external button to test and then I used the key 9 to see if it will work fine, with that code here:

document.getElementById('nine').style.display = "block"; //or none

It works perfectly! But, when I throw that code instead (I marked them up on the whole snippet to you identify them better)

buttonN9.style.display = "block"; //or none

BADABOOM, red alert on the console.

I've tried everything on every sens since hours; return my brain as much as I can; I'm still doing it. This evening, I must go somewhere with my wife. It's going to be hard to not think about it.

I will be honest with you, the calculator from the iPhone does not have the same behavior. If you fire 1,2,3 then +|- it goes -123. If you fire again 7, it goes -1237. So, maybe I mess up my brain too much, but I want to do it :)

Makyen
  • 27,758
  • 11
  • 68
  • 106
  • Your code is correct. You probably is calling the JS before the DOM is loaded. – Azametzin Jul 20 '19 at 13:23
  • I'm not sure how you created that snippet, but you ended up with two snippets overlapping each other. When I fix that, the code works (of course). Please update the question with a [mcve] demonstrating the problem. – T.J. Crowder Jul 20 '19 at 13:23
  • @Azametzin - That would be a different error, not the error the OP quoeted. – T.J. Crowder Jul 20 '19 at 13:24
  • @T.J.Crowder Not necessarily. It was an assumption and usually when it returns undefined that is one of the reasons. – Azametzin Jul 20 '19 at 13:25
  • The name of the function the error occurred in, `HTMLParagraphElement.plusMinus.onclick` suggests that possibly, your real code uses `this.style.display = "none";` and `this` isn't what you expect it to be. See [here](http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback) and [here](https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work). – T.J. Crowder Jul 20 '19 at 13:26
  • @Azametzin - Yes, necessarily. :-) If it were before the button exists in the DOM, the error would be accessing `style` on `null`, not accessing `display` on `undefined`. – T.J. Crowder Jul 20 '19 at 13:26
  • 1
    True. Didn't read all of it. – Azametzin Jul 20 '19 at 13:27
  • Yes i see what you mean @T.J.Crowder ! I'm gone check right now ! Thanks guys ! I updated a bit ... – Jeremy Bertin Jul 20 '19 at 13:30
  • @Azametzin nope sir. My js is at the end :) – Jeremy Bertin Jul 20 '19 at 13:39
  • @T.J.Crowder what do you mean by "I'm not sure how you created that snippet" I'm beginner so i'm just trying to build something to get experience and earn knowledges :) Your comment is more negative or positive ? haha ! Just to know, then i can learn from my mistakes :) – Jeremy Bertin Jul 20 '19 at 13:41
  • 1
    @JeremyBertin - I meant it literally. If you use the Create Snippet dailog box, it doesn't do what was in your question, so... – T.J. Crowder Jul 20 '19 at 13:44
  • @JeremyBertin - Your update does not provide a [mcve]. Please read the link and provide an MCVE. That's the only way we'll be able to help you, other than to say: Clearly, one of those variables refers to something that is not a DOM element. – T.J. Crowder Jul 20 '19 at 13:46
  • So when i trigger "plusMinus" the line where there is "buttonN9.style.display = "none";" is throwing red at the console. Does not matter, where i put that line ... – Jeremy Bertin Jul 20 '19 at 13:50
  • @T.J.Crowder i see and i'm already thankful for your help ! I'm not used of all terms sorry ... I have the project on Github, i'm gone throw what i have done since and put it here maybe ? Thanks again :) – Jeremy Bertin Jul 20 '19 at 13:52
  • @JeremyBertin - No, don't post all of your code. Please. Read. The. Link: [mcve] – T.J. Crowder Jul 20 '19 at 13:52
  • @Jeremy, have you tried giving an **initial** inline or external css display style of `block` to your button, before applying Javascript? – Udo E. Jul 20 '19 at 13:54
  • @Crowder is right. Also, these codes should be entered using inline code botton with the `{}` symbol. You should only use the code snippet button (`<>`) for complete runnable codes. – Udo E. Jul 20 '19 at 14:00
  • @T.J.Crowder you have a link for the repository if you want :) – Jeremy Bertin Jul 20 '19 at 14:02
  • @UdoE. yes sir, it's initialise at my CSS folder :) Is that repository will help better maybe ? https://github.com/jeanjacquesaka1980/calculator – Jeremy Bertin Jul 20 '19 at 14:04
  • @T.J.Crowder i've checked thousand times (maybe more) and all that variables refers to something that is a DOM element ... Will check again and again, i hope i've made a stupid mistake ... – Jeremy Bertin Jul 20 '19 at 14:08
  • The way SO works, your whole question (including any necessary code) has to be **in** your question, not just linked. Two reasons: People shouldn't have to go off-site to help you; and links rot, making the question and its answers useless to people in the future. **Again**, please put a [mcve] **in** the question. More: [*How do I ask a good question?*](/help/how-to-ask) and [*Something in my web site or project doesn't work. Can I just paste a link to it?*](https://meta.stackoverflow.com/questions/254428/) – T.J. Crowder Jul 20 '19 at 14:09
  • @T.J.Crowder well ... i see always many guys put in jsfiddle link so ... i'm gone do it on next week only :) Anyway, thanks for your help ^^ – Jeremy Bertin Jul 20 '19 at 14:16

2 Answers2

0

Simply put all your code that accesses the DOM in a window.onload() handler, like this:

<script>
    window.onload = function() {

        let plusMinus = document.getElementById('plus-minus');
        let buttonN9 = document.getElementById('nine');
        // other variable initialization 

        plusMinus.onclick = function() { 

            buttonN9.style.display = "none"; 
            // other handler code logic
        }

        // other event handlers
    };
</script>

This way, you are sure the DOM is ready before accessing or manipulating it.

Also, from the html file in your Github repository here; you included several external scripts (including jquery) after your script. Except these scripts depend on your own script - which is not likely, you should always place your own script last after other external scripts that your code may likely depend on.

UPDATE: There are issues with firing window.onload from within the body tag. see the answer on this post. In addition to my previous answer, try putting your scripts in the header tag like this:

<head>
    <!-- Place other external scripts here -->
    <script src='myscript.js'></script>
</head>
Udo E.
  • 1,958
  • 1
  • 13
  • 24
0

So, here is the solution. As a beginner, i made first some mistakes, i was repeating the functions. I've created for each behavior one function. The main problem is i wanted to get to an index thru an array without using any loop. The loop for made the deal and now it's behaving as i want ...

The list of the buttons did not change. What you have: - A function to handle a reset button. - A function to handle the value of the numbers buttons - A function to the positive/negative number - A function to reset the positive/negative number in case you click on one number.

This is how behave the calculator that i have so i'm just trying to do the exactly same thing. Thanks a lot for your help !

function buttonResetHandler(button){
  button.onclick = function (){
    button.innerHTML = "AC";
    preview = [];
    result.innerHTML = 0;
  }
}

buttonResetHandler(buttonAc);

// concatenation of the buttons numbers without any commas

function buttonNumberHandler(button, value){
  button.onclick = function(){
    buttonAc.innerHTML = "C";
    button = value;
    preview.push(button);
    const a = preview.join('');
    result.innerHTML = a;
  }
}

buttonNumberHandler(buttonN0, 0);
buttonNumberHandler(buttonN1, 1);
buttonNumberHandler(buttonN2, 2);
buttonNumberHandler(buttonN3, 3);
buttonNumberHandler(buttonN4, 4);
buttonNumberHandler(buttonN5, 5);
buttonNumberHandler(buttonN6, 6);
buttonNumberHandler(buttonN7, 7);
buttonNumberHandler(buttonN8, 8);
buttonNumberHandler(buttonN9, 9);


// positive to negative value and vice versa with the plus, minus key

function buttonPlusMinusHandler(button1, button2, button3, button4){
  button1.onclick = function(){

    let a = preview.join('');
    let b = parseInt(a, 10);
    let c = b * -1;

    result.innerHTML = c;
    button1.style.display = "none";
    button2.style.display = "block";
    for(i = 0; i < button3.length; i++){
      button3[i].style.display = "none";
    }

    for(i = 0; i < button4.length; i++){
      button4[i].style.display = "block";
    }

    if(result.innerHTML == c){
      button2.onclick = function(){
        result.innerHTML = b;
        button2.style.display = "none";
        button1.style.display = "block";
        }
      }
    }
  }

buttonPlusMinusHandler(plusMinus, plusMinus2, allButtonsN, allButtonsN2);

function buttonNumberResetPlusMinus(button, button2){
  for(i = 0; i < button.length; i++){
    button[i].onclick = function(){
      preview = [];
      result.innerHTML = 0;
      for(i = 0; i < button2.length; i++){
        button[i].style.display = "none";
        button2[i].style.display = "block";
      }
    }
  }
}

buttonNumberResetPlusMinus(allButtonsN2, allButtonsN);