3

I'd like to ask on how to add label, input, and br in for loop please. I'm trying to create an application to calculate score/GPA with for loop. Basically, if I enter 4 then 4 boxes of test scores will show up for me to enter (the default value is 150) - and the maximum I can go is 5.

I'm having problem putting label, input, and br in the for loop - the code is fine and it ran, but you obviously see that I'm not using label, input, and br tags. How may I add these in please?

For example, if I enter 3 in the number of exams, then setupInputBox() will generate three label, three input and three br elements.

I attached my codes below.

Thank you so much!

// define a function so that in js code, $ can be used to replace document.getElementById
var $ = function(id) {
  return document.getElementById(id);
};

var numInputs = 1; //default setting, showing one test score input box

//define setupInputBox function to add more test score inputs boxes 
var setupInputBox = function() {

  $('testInputs').innerHTML = "";
  $('scoreTotal').value = "";
  $('scoreAvg').value = "";
  $('scoreFinal').value = "";

  numInputs = $('numscores').value;
  numInputs = parseInt(numInputs);
  // convert inputs into integer numerical value
  //step-1.1: Add a condition in if() statement
  //if user input for number of test scores is valid and in the range 1 to 5
  if (Number.isInteger(numInputs) && numInputs >= 1 && numInputs <= 5) {
    var mainDiv = document.getElementById("testInputs");
    for (var i = 0; i < numInputs; i++) {
      //Step-1.2.1: create new <label>, <input>, and <br> elements (use createElement() method)
      var lbl = document.createElement('label');
      var inp = document.createElement("input");
      var br = document.createElement("br");

      //Step-1.2.2: create text content node for each new <label> element  ( use createTextNode() method )
      lbl.append(document.createTextNode("Test-" + (i + 1)));

      //Step-1.3.1: add for attribute to each new <label> element  ( use setAttribute() method)
      lbl.setAttribute("for", "score" + (i + 1));

      //Step-1.3.2: add id, type, and value attributes to new <input> elements ( use setAttribute() method)
      inp.setAttribute("id", "score" + (i + 1));
      inp.setAttribute("value", "150");
      inp.setAttribute("type", "number");

      //Step-1.4: append each new <label>, <input>, and <br> elements to the <div> element with id=”testInputs”.
      mainDiv.append(lbl, inp, br);

    }
  }
};
//whenever user changes selection on number of test scores to consider, setupInputBox function will be executed again
$('numscores').oninput = setupInputBox;

//define processEntries function to get user inputted test scores, do input validation, and caculate total and average points and 
//determine the final letter grade.  Display all results on web page.
var processEntries = function() {
  $('scoreTotal').value = "";
  $('scoreAvg').value = "";
  $('scoreFinal').value = "";

  var score = []; //define an array to hold test scores

  var message = ""; //define a variable for containing and displaying error message

  var totalscore = 0,
    avgScore, finalScore;

  var isValid = true;

  for (var i = 0; i < numInputs; i++) //
  {
    $("score" + (i + 1)).className = "";

    //step 2.1: add js code to read in each user inputted test score(s) from input test score boxes on the web page.
    var test = document.getElementById("score" + (i + 1));
    var testScore = parseFloat(test.value);

    //step 2.2: add js code to validate each test score to make sure all inputted test scores are numerical values
    //between 0 and 150 (i.e., no less than 0 and no greater than 150 points).
    if (!Number.isNaN(testScore) && testScore >= 0 && testScore <= 150) {
      //if a test score is valid, add that test score to the score array.
      score.push(testScore);
    } else {
      isValid = false;
      //if a test score is invalid, generate error message, and add that error messge to message string.
      message += "Test-" + (i + 1) + " score input is invalid. Should be a number between 0 and 150.\n"
      test.setAttribute("class", "error");
    }

  }
  console.log(score); //print out score array in console
  console.log(message); //print out message string in console


  if (isValid) {
    //step2.3: add js so that when all inputted test scores are valid, compute total points, average points (with zero decimal place), and
    //final letter grade, and display them in the input boxes in the <div> element with id=’result’ on the web page.
    for (var j = 0; j < numInputs; j++) {
      totalscore += score[j];
    }

    totalscore = totalscore.toFixed(1);

    avgScore = totalscore / numInputs;
    avgScore = avgScore.toFixed(1);

    var scoreTotal = document.getElementById('scoreTotal');
    scoreTotal.value = totalscore.toString();

    var scoreAvg = document.getElementById('scoreAvg');
    scoreAvg.value = avgScore.toString();

    avgScore = parseFloat(avgScore);

    if (avgScore <= 150 && avgScore >= 120)
      finalScore = "A";
    else if (avgScore < 120 && avgScore >= 100)
      finalScore = "B";
    else if (avgScore < 100 && avgScore >= 80)
      finalScore = "C";
    else if (avgScore < 80 && avgScore >= 60)
      finalScore = "D";
    else if (avgScore < 60)
      finalScore = "F";

    var scoreFinal = document.getElementById("scoreFinal")
    scoreFinal.value = finalScore
  } else {
    //If not all inputted test scores are valid, then create an alert box to display an error message
    alert(message);
  }
}; //end of processEntries function

//each time when calculate button is clicked, inputted test scores will be evaluated and 
$("calculate").onclick = function() {
  if (numInputs > 0 && numInputs < 6)
    processEntries();
};
$("numscores").focus();
@import url(http://fonts.googleapis.com/css?family=Wellfleet);
body {
  font-family: 'Wellfleet', Arial, Helvetica, sans-serif;
  background-color: white;
  margin: 0 auto;
  width: 60%;
  min-width: 600px;
  border: 3px solid blue;
  padding: 0 1em .5em;
}

h1 {
  color: blue;
  margin: .5em 0;
}

#teacher {
  float: right;
  margin: 0px 30px 0px 0px;
}

label {
  float: left;
  width: 10em;
  text-align: right;
  margin-bottom: .5em;
}

input {
  width: 5em;
  margin-left: 1em;
  margin-bottom: .5em;
}

input.error {
  background-color: yellow;
}

#s1 {
  display: inline-block;
}

#s1 input {
  vertical-align: center;
  float: left;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>Test Score App</title>
  <link rel="stylesheet" href="score.css">
</head>

<body>
  <main>
    <h2>The Test Scores App</h2>
    <img src="teacher.png" id="teacher" alt="teacher" width="177" height="277">

    <div id="s1">
      <label for="numscores">How many tests you want to consider?</label>
      <input type='number' id='numscores' min='1' max='10' value='1'>
    </div>

    <div id="testInputs">
      <label for="score1">Test-1:</label>
      <input type='number' id='score1' value='150' /><br>
    </div>

    <div id='result'>
      <label for="scoreTotal">Total Points:</label>
      <input type="number" id="scoreTotal" disabled><br>

      <label for="scoreAvg">Avg Grade:</label>
      <input type="number" id="scoreAvg" disabled><br>

      <label for="scoreFinal">Final Letter Grade:</label>
      <input type="text" id="scoreFinal" disabled><br>

      <label>&nbsp;</label>
      <input type="button" id="calculate" value="Calculate">
    </div>

  </main>
  <script src="testScoreV2.js">
  </script>
</body>

</html>

4
  • not sure what is missing in your code currently. Where do you need these elements? Commented Oct 22, 2019 at 2:55
  • Currently I'm using var lbl = document.createElement('label');, however I'd like to use <label>, <input>, and <br> Commented Oct 22, 2019 at 2:55
  • @SteveFranchise shouldn't you create each element then..? Commented Oct 22, 2019 at 2:59
  • @Phix I did try to add <label> and the other 2 in my code but then I'm stuck - my instructor says that if the number of tests that the user selects is 2 then setupInputBox() will generate 2 <label>, 2 <input> and 2 <br> elements. I'm can create the <label> as: <label for="score1">Test-1:</label> and also <input type='number' id='score1' value='100'/>, but I'm don't know what she means by "setupInputBox() will generate 2" - would I still need to create all 5? (because the max number of tests is only 5) Commented Oct 22, 2019 at 3:04

1 Answer 1

2

Use a template literal and you can make this a lot simpler

// define a function so that in js code, $ can be used to replace document.getElementById
var $ = function(id) {
  return document.getElementById(id);
};

var numInputs = 1; //default setting, showing one test score input box

//define setupInputBox function to add more test score inputs boxes 
var setupInputBox = function() {

  $('testInputs').innerHTML = "";
  $('scoreTotal').value = "";
  $('scoreAvg').value = "";
  $('scoreFinal').value = "";
  //string to hold our new html
  let newHTML = "";

  numInputs = $('numscores').value;
  numInputs = parseInt(numInputs);
  // convert inputs into integer numerical value
  //step-1.1: Add a condition in if() statement
  //if user input for number of test scores is valid and in the range 1 to 5
  if (Number.isInteger(numInputs) && numInputs >= 1 && numInputs <= 5) {
    var mainDiv = document.getElementById("testInputs");
    for (var i = 0; i < numInputs; i++) {
      //Create new html using template literal
      newHTML += `<label for='score${i+1}'>Test - ${i+1}</label><input type='number' value='150' id='score${i+1}'><br>`;
    }
    //Update the div
    mainDiv.innerHTML += newHTML;
  }
};
//whenever user changes selection on number of test scores to consider, setupInputBox function will be executed again
$('numscores').oninput = setupInputBox;

//define processEntries function to get user inputted test scores, do input validation, and caculate total and average points and 
//determine the final letter grade.  Display all results on web page.
var processEntries = function() {
  $('scoreTotal').value = "";
  $('scoreAvg').value = "";
  $('scoreFinal').value = "";

  var score = []; //define an array to hold test scores

  var message = ""; //define a variable for containing and displaying error message

  var totalscore = 0,
    avgScore, finalScore;

  var isValid = true;

  for (var i = 0; i < numInputs; i++) //
  {
    $("score" + (i + 1)).className = "";

    //step 2.1: add js code to read in each user inputted test score(s) from input test score boxes on the web page.
    var test = document.getElementById("score" + (i + 1));
    var testScore = parseFloat(test.value);

    //step 2.2: add js code to validate each test score to make sure all inputted test scores are numerical values
    //between 0 and 150 (i.e., no less than 0 and no greater than 150 points).
    if (!Number.isNaN(testScore) && testScore >= 0 && testScore <= 150) {
      //if a test score is valid, add that test score to the score array.
      score.push(testScore);
    } else {
      isValid = false;
      //if a test score is invalid, generate error message, and add that error messge to message string.
      message += "Test-" + (i + 1) + " score input is invalid. Should be a number between 0 and 150.\n"
      test.setAttribute("class", "error");
    }

  }
  console.log(score); //print out score array in console
  console.log(message); //print out message string in console


  if (isValid) {
    //step2.3: add js so that when all inputted test scores are valid, compute total points, average points (with zero decimal place), and
    //final letter grade, and display them in the input boxes in the <div> element with id=’result’ on the web page.
    for (var j = 0; j < numInputs; j++) {
      totalscore += score[j];
    }

    totalscore = totalscore.toFixed(1);

    avgScore = totalscore / numInputs;
    avgScore = avgScore.toFixed(1);

    var scoreTotal = document.getElementById('scoreTotal');
    scoreTotal.value = totalscore.toString();

    var scoreAvg = document.getElementById('scoreAvg');
    scoreAvg.value = avgScore.toString();

    avgScore = parseFloat(avgScore);

    if (avgScore <= 150 && avgScore >= 120)
      finalScore = "A";
    else if (avgScore < 120 && avgScore >= 100)
      finalScore = "B";
    else if (avgScore < 100 && avgScore >= 80)
      finalScore = "C";
    else if (avgScore < 80 && avgScore >= 60)
      finalScore = "D";
    else if (avgScore < 60)
      finalScore = "F";

    var scoreFinal = document.getElementById("scoreFinal")
    scoreFinal.value = finalScore
  } else {
    //If not all inputted test scores are valid, then create an alert box to display an error message
    alert(message);
  }
}; //end of processEntries function

//each time when calculate button is clicked, inputted test scores will be evaluated and 
$("calculate").onclick = function() {
  if (numInputs > 0 && numInputs < 6)
    processEntries();
};
$("numscores").focus();
@import url(http://fonts.googleapis.com/css?family=Wellfleet);
body {
  font-family: 'Wellfleet', Arial, Helvetica, sans-serif;
  background-color: white;
  margin: 0 auto;
  width: 60%;
  min-width: 600px;
  border: 3px solid blue;
  padding: 0 1em .5em;
}

h1 {
  color: blue;
  margin: .5em 0;
}

#teacher {
  float: right;
  margin: 0px 30px 0px 0px;
}

label {
  float: left;
  width: 10em;
  text-align: right;
  margin-bottom: .5em;
}

input {
  width: 5em;
  margin-left: 1em;
  margin-bottom: .5em;
}

input.error {
  background-color: yellow;
}

#s1 {
  display: inline-block;
}

#s1 input {
  vertical-align: center;
  float: left;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>Test Score App</title>
  <link rel="stylesheet" href="score.css">
</head>

<body>
  <main>
    <h2>The Test Scores App</h2>
    <img src="teacher.png" id="teacher" alt="teacher" width="177" height="277">

    <div id="s1">
      <label for="numscores">How many tests you want to consider?</label>
      <input type='number' id='numscores' min='1' max='10' value='1'>
    </div>

    <div id="testInputs">
      <label for="score1">Test-1:</label>
      <input type='number' id='score1' value='150' /><br>
    </div>

    <div id='result'>
      <label for="scoreTotal">Total Points:</label>
      <input type="number" id="scoreTotal" disabled><br>

      <label for="scoreAvg">Avg Grade:</label>
      <input type="number" id="scoreAvg" disabled><br>

      <label for="scoreFinal">Final Letter Grade:</label>
      <input type="text" id="scoreFinal" disabled><br>

      <label>&nbsp;</label>
      <input type="button" id="calculate" value="Calculate">
    </div>

  </main>
  <script src="testScoreV2.js">
  </script>
</body>

</html>

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

3 Comments

An interesting suggestion! Unfortunately I cannot seem to get the code work. :(
Fascinating...it seems that I can calculate my score when the number of tests is 1, but if there is more than that, I cannot seem to calculate my score.
Fixed - a couple of errors on my part with the id attribute on the input.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.