3

I am a beginner in javascript and am doing an MMA score, I would like to know how I could access the changed value of result1Red.

<span><a id="result1Red">0</a></span>

which is changed by choosing one of the buttons that activates its respective function:

function tenRed1() {
  var i = 10;
  result1Red += 1*i;
  if (result1Red > 10) {return;}
  document.getElementById("result1Red").innerHTML = result1Red;
};

function nineRed1() {
  var i = 9;
  result1Red += 1*i;
  if (result1Red > 10) {return;}
  document.getElementById("result1Red").innerHTML = result1Red;
};

function eightRed1() {
  var i = 8;
  result1Red += 1*i;
  if (result1Red > 10) {return;}
  document.getElementById("result1Red").innerHTML = result1Red;
};

When I try with "innerHTML" it returns 0 (the initial value) and not the determined value. I need this value to add up with the other inputs and get the total result.

Complete code:

// Round 1
function tenRed1() {
  var i = 10;
  result1Red += 1*i;
  if (result1Red > 10) {return;}
  document.getElementById("result1Red").innerHTML = result1Red;
};

function nineRed1() {
  var i = 9;
  result1Red += 1*i;
  if (result1Red > 10) {return;}
  document.getElementById("result1Red").innerHTML = result1Red;
};

function eightRed1() {
  var i = 8;
  result1Red += 1*i;
  if (result1Red > 10) {return;}
  document.getElementById("result1Red").innerHTML = result1Red;
};

function tenBlue1() {
  var i = 10;
  result1Blue += 1*i;
  if (result1Blue > 10) {return;}
  document.getElementById("result1Blue").innerHTML = result1Blue;
};

function nineBlue1() {
  var i = 9;
  result1Blue += 1*i;
  if (result1Blue > 10) {return;}
  document.getElementById("result1Blue").innerHTML = result1Blue;
};

function eightBlue1() {
  var i = 8;
  result1Blue += 1*i;
  if (result1Blue > 10) {return;}
  document.getElementById("result1Blue").innerHTML = result1Blue;
}


// Round 2
function tenRed2() {
  var i = 10;
  result2Red += 1*i;
  if (result2Red > 10) {return;}
  document.getElementById("result2Red").innerHTML = result2Red;
};

function nineRed2() {
  var i = 9;
  result2Red += 1*i;
  if (result2Red > 10) {return;}
  document.getElementById("result2Red").innerHTML = result2Red;
};

function eightRed2() {
  var i = 8;
  result2Red += 1*i;
  if (result2Red > 10) {return;}
  document.getElementById("result2Red").innerHTML = result2Red;
};

function tenBlue2() {
  var i = 10;
  result2Blue += 1*i;
  if (result2Blue > 10) {return;}
  document.getElementById("result2Blue").innerHTML = result2Blue;
};

function nineBlue2() {
  var i = 9;
  result2Blue += 1*i;
  if (result2Blue > 10) {return;}
  document.getElementById("result2Blue").innerHTML = result2Blue;
};

function eightBlue2() {
  var i = 8;
  result2Blue += 1*i;
  if (result2Blue > 10) {return;}
  document.getElementById("result2Blue").innerHTML = result2Blue;
};


// Round 3
function tenRed3() {
  var i = 10;
  result3Red += 1*i;
  if (result3Red > 10) {return;}
  document.getElementById("result3Red").innerHTML = result3Red;
};

function nineRed3() {
  var i = 9;
  result3Red += 1*i;
  if (result3Red > 10) {return;}
  document.getElementById("result3Red").innerHTML = result3Red;
};

function eightRed3() {
  var i = 8;
  result3Red += 1*i;
  if (result3Red > 10) {return;}
  document.getElementById("result3Red").innerHTML = result3Red;
};

function tenBlue3() {
  var i = 10;
  result3Blue += 1*i;
  if (result3Blue > 10) {return;}
  document.getElementById("result3Blue").innerHTML = result3Blue;
};

function nineBlue3() {
  var i = 9;
  result3Blue += 1*i;
  if (result3Blue > 10) {return;}
  document.getElementById("result3Blue").innerHTML = result3Blue;
};

function eightBlue3() {
  var i = 8;
  result3Blue += 1*i;
  if (result3Blue>  10) {return;}
  document.getElementById("result3Blue").innerHTML = result3Blue;
};
<html>
<head>
 <title>MMAScore Beta</title>
 <link rel="styleesheet" type="text/css" href="style/style.css">
</head>
<body>

<header>
 <h1>mmaScore 0.1 Version</h1>
</header>

<!-- Round 1 -->
<div class="roundOne">
 <button type="button" onclick="eightRed1()">8</button>
 <button type="button" onclick="nineRed1()">9</button>
 <button type="button" onclick="tenRed1()">10</button>
 <span><a id="result1Red">0</a></span> - 
 <span><a id="result1Blue">0</a></span>
 <button type="button" onclick="tenBlue1()">10</button>
 <button type="button" onclick="nineBlue1()">9</button>
 <button type="button" onclick="eightBlue1()">8</button>
</div>
<!-- Round 2 -->
<div class="roundTwo">
 <button type="button" onclick="eightRed2()">8</button>
 <button type="button" onclick="nineRed2()">9</button>
 <button type="button" onclick="tenRed2()">10</button>
 <span><a id="result2Red">0</a></span> - 
 <span><a id="result2Blue">0</a></span>
 <button type="button" onclick="tenBlue2()">10</button>
 <button type="button" onclick="nineBlue2()">9</button>
 <button type="button" onclick="eightBlue2()">8</button>
</div>
<!-- Round 3 -->
<div class="roundThree">
 <button type="button" onclick="eightRed3()">8</button>
 <button type="button" onclick="nineRed3()">9</button>
 <button type="button" onclick="tenRed3()">10</button>
 <span><a id="result3Red">0</a></span> - 
 <span><a id="result3Blue">0</a></span>
 <button type="button" onclick="tenBlue3()">10</button>
 <button type="button" onclick="nineBlue3()">9</button>
 <button type="button" onclick="eightBlue3()">8</button>
</div>



<h3>Total:</h3>
<span id="resultRed">0</span> - 
<span id="resultBlue">0</span>
<footer>
</footer>



<script type="text/javascript" src="script/script.js"></script>
</body>
</html>
Tony
  • 16,527
  • 15
  • 80
  • 134

2 Answers2

3

Regarding your code

First I would like to point a couple of issues with your code and give you some advice :

  • write <span> instead of <spam>

  • <a> tags are for links only you don't need to have <span><a>...</a></span>

  • try to use less ìds and class names

  • don't use .innerHTML if you're not planning on adding HTML, use .textContent instead

  • your JavaScript code is way too redundant: you've defined 18 similar functions! Functions need to be reusable.


A proposal

Here's how you could implement your process.

  • we will add an event listener to the document to listen to any clicks inside the page. We'll use addEventListener for that.

    document.addEventListener('click', function() {})
    

    As you can see it takes the event type ('click') and a callback function that it will execute when the event happens. We need to define this callback.

  • The callback needs to first check that the clicked item is indeed a button and it's parent (if he has any) has the class name: .round.

    const parent = event.target.parentElement;
    if (parent && parent.classList.contains('round')) {
      ...
    }
    

    If the condition is met then it means the user has clicked on one of the buttons.

  • In the if block we can start working with event.target which is the element that has been clicked (in our case it will be one of the <button> element). We will start by saving some variables: button (the <button> element), amount (the button's value) and team (the team: either 'Red' or 'Blue').

    const button = event.target;
    const amount = button.textContent;
    const team = button.className.substr(3);
    
  • Then we will update the round's point:

    parent.querySelector('.result'+team).textContent = amount;
    
  • And finally, update the total amount using updateTotals:

    updateTotals('.result'+team);
    

Full code:

const updateTotals = function(className) {
  const total = [...document.querySelectorAll('.round '+className)]
    .map(e=> parseInt(e.textContent))
    .reduce((a,b) => a+b);
  document.querySelector('.results > '+className).textContent = total;
};

document.addEventListener('click', function() {
  const parent = event.target.parentElement;
  if (parent && parent.classList.contains('round')) { // this is a <button>
  
    const button = event.target;
    const amount = button.textContent;
    const team = button.className.substr(3);
    
    // update team score
    parent.querySelector('.result'+team).textContent = amount;
    
    // update total for each team
    updateTotals('.result'+team);
    
  }
});
<h1>mmaScore 0.1 Version</h1>

<!-- Round 1 -->
<div class="round round1">
  <button class="btnRed" type="button">8</button>
  <button class="btnRed" type="button">9</button>
  <button class="btnRed" type="button">10</button>
  <span class="resultRed">0</span> -
  <span class="resultBlue">0</span>
  <button class="btnBlue" type="button">10</button>
  <button class="btnBlue" type="button">9</button>
  <button class="btnBlue" type="button">8</button>
</div>

<!-- Round 2 -->
<div class="round round2">
  <button class="btnRed" type="button">8</button>
  <button class="btnRed" type="button">9</button>
  <button class="btnRed" type="button">10</button>
  <span class="resultRed">0</span> -
  <span class="resultBlue">0</span>
  <button class="btnBlue" type="button">10</button>
  <button class="btnBlue" type="button">9</button>
  <button class="btnBlue" type="button">8</button>
</div>

<!-- Round 3 -->
<div class="round round3">
  <button class="btnRed" type="button">8</button>
  <button class="btnRed" type="button">9</button>
  <button class="btnRed" type="button">10</button>
  <span class="resultRed">0</span> -
  <span class="resultBlue">0</span>
  <button class="btnBlue" type="button">10</button>
  <button class="btnBlue" type="button">9</button>
  <button class="btnBlue" type="button">8</button>
</div>

<h3>Total:</h3>
<div class="results">
  <span class="resultRed">0</span> -
  <span class="resultBlue">0</span>
</div>

About updateTotals:

The function allows to take the sum of all points for the specified team. It takes as argument className of type String which can either be 'resultRed' or 'resultBlue'.

Here's how it works:

  1. it starts by selecting all of the point elements and spreading the selection returned by querySelectorAll into an array.

    [...document.querySelectorAll('.round '+className)]
    
  2. then we can map this array like so HTMLElement => Number using .map

    .map(e=> parseInt(e.textContent))
    
  3. then the resulting mapped array can be reduced to a single integer: the sum of all the elements of the array using a .reduce. Here's a Stack Overflow thread on How to find the sum of an array of numbers.

  4. Finally change the team's total count in the DOM with the calculated sum total.

As a result we have:

const updateTotals = function(className) {
  const total = [...document.querySelectorAll('.round '+className)]
    .map(e=> parseInt(e.textContent))
    .reduce((a,b) => a+b);
  document.querySelector('.results > '+className).textContent = total;
};
Ivan
  • 34,531
  • 8
  • 55
  • 100
  • first of all thanks for the JavaScript writing tips! quick response and very very helpful. I'll have enough to study for days with your answer. Testing your suggestion I get this error: { "message": "Uncaught TypeError: Can not set property 'textContent' of null", "filename": "https://stacksnippets.net/js", "lineno": 71, "colno": 54 } what could it be? – Rodrigo Liva Jun 22 '18 at 00:40
  • me? I'm sure I did not do that. – Rodrigo Liva Jun 22 '18 at 11:00
  • No, I don't know if it's you. It's someone else. – Ivan Jun 22 '18 at 11:17
1

Found post already has accepted answer and 4 upvotes when I finished this. I'm going to post it anyway, just for ref.

NodeList.prototype.map=Array.prototype.map;

const sum=()=>{
 resultRed.innerText=document.querySelectorAll(".resultRed").map(x=>x.innerText).reduce((a,b)=>Number(a)+Number(b));
 resultBlue.innerText=document.querySelectorAll(".resultBlue").map(x=>x.innerText).reduce((a,b)=>Number(a)+Number(b));
}

for(const cn of document.querySelectorAll("body>div").map(x=>x.className)){
 const parent=document.getElementsByClassName(cn)[0];
 parent.querySelectorAll("button").forEach((v,i)=>{
  if(i<=2) v.onclick=()=>{
   parent.querySelector(".resultRed").innerText=v.innerText;
   sum();
  }
  else v.onclick=()=>{
   parent.querySelector(".resultBlue").innerText=v.innerText;
   sum();
  }
 });
}
<!-- Round 1 -->
<div class="roundOne">
 <button type="button">8</button>
 <button type="button">9</button>
 <button type="button">10</button>
 <spam><a class="resultRed">0</a></spam> - 
 <spam><a class="resultBlue">0</a></spam>
 <button type="button">10</button>
 <button type="button">9</button>
 <button type="button">8</button>
</div>
<!-- Round 2 -->
<div class="roundTwo">
 <button type="button">8</button>
 <button type="button">9</button>
 <button type="button">10</button>
 <spam><a class="resultRed">0</a></spam> - 
 <spam><a class="resultBlue">0</a></spam>
 <button type="button">10</button>
 <button type="button">9</button>
 <button type="button">8</button>
</div>
<!-- Round 3 -->
<div class="roundThree">
 <button type="button">8</button>
 <button type="button">9</button>
 <button type="button">10</button>
 <spam><a class="resultRed">0</a></spam> - 
 <spam><a class="resultBlue">0</a></spam>
 <button type="button">10</button>
 <button type="button">9</button>
 <button type="button">8</button>
</div>



<h3>Total:</h3>
<spam id="resultRed">0</spam> - 
<spam id="resultBlue">0</spam>
<footer>
</footer>
Liang
  • 507
  • 2
  • 9