These rather challenging lab activities exposes how functions can be used within JavaScript, and how it can interact with web elements in the HTML Document Object Model (DOM).
Should you require more guidance, there are plenty of online tutorials detailing multiple solutions - it's best if you can explore and test them out to the best of your ability.
School teachers are often advised to look for creative methods into their lessons in order to help engage with students better or help students learn concepts easier with different methods.
The multiplication box is one of many creative methods concocted by elementary school math teachers to help students understand multiplication between two-digit numbers (i.e., integer values).
@importurl("https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;0,800;1,200;1,300;1,400;1,500;1,600;1,700;1,800&display=swap");:root{--table-cell-dimension:100px;--text-size:32px;}*{font-family:"Plus Jakarta Sans",sans-serif;}body{padding-top:2rem;text-align:center;}h1{font-size:48px;}#num_entry,#num_entryinput[type="number"]{font-size:var(--text-size);margin-bottom:1rem;}#num_entryinput[type="number"]{text-align:center;width:var(--table-cell-dimension);}input[type="number"]:disabled{background-color:white;border:2pxsolidblack;cursor:not-allowed;}/* For Chrome, Safari, Edge, Opera */input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0;}/* For Firefox */input[type="number"]{-moz-appearance:textfield;}input[type="button"]{font-size:20px;padding:0.5rem1rem;}hr{margin:2rem0;}table#multiplication-box{/* border: 1px solid black; */border-collapse:collapse;display:inline-block;margin-left:auto;}table#multiplication-boxth,table#multiplication-boxtd:not(.td-hidden){border:1pxsolidblack;font-size:var(--text-size);height:var(--table-cell-dimension);width:var(--table-cell-dimension);}
You should be able to see the following in your web browser:
Multiplication Box Page
This method using the multiplication box involves separating both numbers into tens and units, and then multiplying them separately before adding their horizontal and vertical totals up.
The cell at the bottom right denotes the eventual product between the two numbers.
For instance, with \(49 \times 16\), both numbers are separated as the pairs (40, 9) and (10, 6) respectively.
The following multiplication operations are then carried out first:
\(40 \times 10 = 400\)
\(40 \times 6 = 240\)
\(9 \times 10 = 90\)
\(9 \times 6 = 54\)
The numbers are populated as shown in the figure below, where their horizontal totals and vertical totals are calculated and displayed.
Between both sets of totals, they produce the same correct product after being added together (i.e., \(490 + 294 = 640 + 144 = 784\)).
Multiplication Box Page
Take note that the only input fields of concern are the three which make up the equation on top of the multiply button, which is associated with the JavaScript multiply() function we will be completing in this activity.
Only the first two are allowed to be populated manually by the user.
The third representing the calculated product is set to be read-only.
Let's work on obtaining the values entered into the first two input fields.
The first two lines in the multiply() function is used to obtain the values from input fields input#num1 and input#num2.
TL;DR: In nearly all cases, .value is only used with <input> whilst .innerHTML is for getting values from any non-self-closing tags.
Let's take a <p> element, for example.
<p> Content/text/etc. inside here
</p>
The content placed in between the opening <p> and closing </p> tags is what we refer to as inner HTML.
Therefore, we use .innerHTML to obtain values that are stored in between similarly structured HTML tags.
document.querySelector("p").innerHTML
However, when it comes to <input> elements, these are represented with self-closing tags.
Thus, there isn't really any inner HTML to target.
<input> elements do have the a value attribute that contains entered text, though.
In this case, it only makes sense to use .value to elicit values out of <input> fields.
document.querySelector("input").innerHTML// does not workdocument.querySelector("input").value// use this for <input> elements instead
Here, we observe that the parseInt() function is applied surrounding the expression used to obtain the value from input#num1 and input#num2.
This function ensures that an integer is obtained from the <input> elements, as the value obtained from them typically defaults to being of a "string" type.
Before we proceed to use these values we've entered, we're going to implement a few checks to see if the numbers entered are two-digit integers.
This means that:
none of the two input fields (i.e., input#num1 and input#num2) should be empty
no non-integer values or any value outside of the 10-99 range can be entered
The first criterion is pretty straightforward - we check to see if the value of input#num1 and/or input#num2 results in an empty string (i.e., "").
To implement the second criterion, we'll be using the sister variant function of parseInt() called parseFloat().
While parseInt() obtains an integer from the passed in string (in this case the value of the <input> field), parseFloat() obtains any number (with decimal points) from the passed in string.
In summary,
Function
"17"
"17.5"
"17as"
"17.5as"
"as17"
"asap"
parseInt()
17
17
17
17
NaN
Nan
parseFloat()
17
17.5
17
17.5
NaN
Nan
From the table above, we can probably tell that parseFloat("17.5")!==parseInt("17.5").
We use this idea here to determine if the input number in either input#num1 or input#num2 or both are not integers, and then we proceed to replace them with the integer obtained after using the parseInt() function.
For both criteria, we use an alert box to alert the user of any problems found.
functionmultiply(){letnum1=parseInt(document.querySelector("#num1").value);letnum2=parseInt(document.querySelector("#num2").value);// replace num1 and num2 with parsed integer (if not integers)// alert user when number is replacedif(parseFloat(document.querySelector("#num1").value)!==parseInt(document.querySelector("#num1").value)){if(document.querySelector("#num1").value==""){alert("First number input is empty.");}else{alert("First number isn't an integer. Replacing value at input field with parsed integer value instead.",);document.querySelector("#num1").value=num1;}}if(parseFloat(document.querySelector("#num2").value)!==parseInt(document.querySelector("#num2").value)){if(document.querySelector("#num2").value==""){alert("Second number input is empty.");}else{alert("Second number isn't an integer. Replacing value at input field with parsed integer value instead.",);document.querySelector("#num2").value=num2;}}}
Alert box pop-up if first number has not been entered.
Alert box pop-up if second number has not been entered.
Alert box pop-up if first number is not an integer.
Alert box pop-up if second number is not an integer.
Now, onward to checking whether the input integers (i.e., num1 and num2) are within the correct range.
A two-digit integer can only be either one of the numbers between 10 and 99; the rest of which simply will not fit.
For the sake of simplicity, we will only consider positive values.
We implement this check using a compound condition of 4 conditions to be met simultaneously:
num1>=10
num1<=99
num2>=10
num2<=99
If all four of these conditions are met, we proceed to display num1 and num2 in td#num1_show and td#num2_show respectively.
We will expand on the further logic to be implemented from here.
Otherwise, we check to see either num1<10||num1>99 or num2<10||num2>99, and display an appropriate error message in an alert box.
functionmultiply(){letnum1=parseInt(document.querySelector("#num1").value);letnum2=parseInt(document.querySelector("#num2").value);// replace num1 and num2 with parsed integer (if not integers)// alert user when number is replacedif(parseFloat(document.querySelector("#num1").value)!==parseInt(document.querySelector("#num1").value)){if(document.querySelector("#num1").value==""){alert("First number input is empty.");}else{alert("First number isn't an integer. Replacing value at input field with parsed integer value instead.",);document.querySelector("#num1").value=num1;}}if(parseFloat(document.querySelector("#num2").value)!==parseInt(document.querySelector("#num2").value)){if(document.querySelector("#num2").value==""){alert("Second number input is empty.");}else{alert("Second number isn't an integer. Replacing value at input field with parsed integer value instead.",);document.querySelector("#num2").value=num2;}}// check if num1 and num2 is between 10 and 99 (inclusive)if(num1>=10&&num1<=99&&num2>=10&&num2<=99){// show number in num?_showdocument.querySelector("#num1_show").innerHTML=num1;document.querySelector("#num2_show").innerHTML=num2;// to continue more here}else{// if first number is not between 10 and 99 (inclusive)if(num1<10||num1>99){alert("First number should be between 10 and 99!");document.querySelector("#num1").value="";// empty first input field}// if secondnumber is not between 10 and 99 (inclusive)if(num2<10||num2>99){alert("Second number should be between 10 and 99!");document.querySelector("#num2").value="";// empty second input field}}}
Alert box pop-up if first number is not between 10 and 99 (inclusive).
Alert box pop-up if second number is not between 10 and 99 (inclusive).
Otherwise, your multiplication table should start being populated from here.
Step 3: Populating the Table: Tens and Units Split¶
The key ideas behind using the multiplication box/table as shown here is to split the two-digit numbers into the tens and units places.
In order to elicit the tens digit from the number, we simply obtain the quotient after dividing it by 10.
This quotient is then passed into one of the Math functions, namely the floor() function which rounds down a number to the lower boundary (e.g., 3.4 to 3, and 4.9 to 4).
The units digit is obtained simply by using the modulo operator on the number; basically, what the remainder is after dividing the number by 10.
These values are then stored contiguously in an array for each number (e.g., \(49 \times 16\) produces [4,9] and [1,6]).
Each of these digit are then placed in the respective cells: td#num1a, td#num1b, td#num2a, td#num2b.
functionmultiply(){letnum1=parseInt(document.querySelector("#num1").value);letnum2=parseInt(document.querySelector("#num2").value);// replace num1 and num2 with parsed integer (if not integers)// alert user when number is replacedif(parseFloat(document.querySelector("#num1").value)!==parseInt(document.querySelector("#num1").value)){if(document.querySelector("#num1").value==""){alert("First number input is empty.");}else{alert("First number isn't an integer. Replacing value at input field with parsed integer value instead.",);document.querySelector("#num1").value=num1;}}if(parseFloat(document.querySelector("#num2").value)!==parseInt(document.querySelector("#num2").value)){if(document.querySelector("#num2").value==""){alert("Second number input is empty.");}else{alert("Second number isn't an integer. Replacing value at input field with parsed integer value instead.",);document.querySelector("#num2").value=num2;}}// check if num1 and num2 is between 10 and 99 (inclusive)if(num1>=10&&num1<=99&&num2>=10&&num2<=99){// show number in num?_showdocument.querySelector("#num1_show").innerHTML=num1;document.querySelector("#num2_show").innerHTML=num2;// split number into digits based on tens and units valueletarr_num1=[Math.floor(num1/10)*10,num1%10];letarr_num2=[Math.floor(num2/10)*10,num2%10];// show digits in num?a or num?bdocument.querySelector("#num1a").innerHTML=arr_num1[0];document.querySelector("#num1b").innerHTML=arr_num1[1];document.querySelector("#num2a").innerHTML=arr_num2[0];document.querySelector("#num2b").innerHTML=arr_num2[1];// to continue more here}else{// if first number is not between 10 and 99 (inclusive)if(num1<10||num1>99){alert("First number should be between 10 and 99!");document.querySelector("#num1").value="";// empty first input field}// if secondnumber is not between 10 and 99 (inclusive)if(num2<10||num2>99){alert("Second number should be between 10 and 99!");document.querySelector("#num2").value="";// empty second input field}}}
Your function should now produce this result after clicking the button.
Step 4: Populating the Table: Calculating Intermediary Products¶
By splitting both numbers into the tens and units digits, we can now carry out the following intermediary multiplications operations (taking \(49 \times 16\) for example):
\(40 \times 10 = 400\)
\(40 \times 6 = 240\)
\(9 \times 10 = 90\)
\(9 \times 6 = 54\)
Each of these products are placed like as shown in the following output.
functionmultiply(){letnum1=parseInt(document.querySelector("#num1").value);letnum2=parseInt(document.querySelector("#num2").value);// replace num1 and num2 with parsed integer (if not integers)// alert user when number is replacedif(parseFloat(document.querySelector("#num1").value)!==parseInt(document.querySelector("#num1").value)){if(document.querySelector("#num1").value==""){alert("First number input is empty.");}else{alert("First number isn't an integer. Replacing value at input field with parsed integer value instead.",);document.querySelector("#num1").value=num1;}}if(parseFloat(document.querySelector("#num2").value)!==parseInt(document.querySelector("#num2").value)){if(document.querySelector("#num2").value==""){alert("Second number input is empty.");}else{alert("Second number isn't an integer. Replacing value at input field with parsed integer value instead.",);document.querySelector("#num2").value=num2;}}// check if num1 and num2 is between 10 and 99 (inclusive)if(num1>=10&&num1<=99&&num2>=10&&num2<=99){// show number in num?_showdocument.querySelector("#num1_show").innerHTML=num1;document.querySelector("#num2_show").innerHTML=num2;// split number into digits based on tens and units valueletarr_num1=[Math.floor(num1/10)*10,num1%10];letarr_num2=[Math.floor(num2/10)*10,num2%10];// show digits in num?a or num?bdocument.querySelector("#num1a").innerHTML=arr_num1[0];document.querySelector("#num1b").innerHTML=arr_num1[1];document.querySelector("#num2a").innerHTML=arr_num2[0];document.querySelector("#num2b").innerHTML=arr_num2[1];/** * Calculate intermediary multiplication values * * Key: * m1 = num1a * num2a * m2 = num1b * num2a * m3 = num1a * num2b * m4 = num1b * num2b */constm1=arr_num1[0]*arr_num2[0];constm2=arr_num1[1]*arr_num2[0];constm3=arr_num1[0]*arr_num2[1];constm4=arr_num1[1]*arr_num2[1];// Display intermediary multiplication valuesdocument.querySelector("#m1").innerHTML=m1;document.querySelector("#m2").innerHTML=m2;document.querySelector("#m3").innerHTML=m3;document.querySelector("#m4").innerHTML=m4;// to continue more here}else{// if first number is not between 10 and 99 (inclusive)if(num1<10||num1>99){alert("First number should be between 10 and 99!");document.querySelector("#num1").value="";// empty first input field}// if secondnumber is not between 10 and 99 (inclusive)if(num2<10||num2>99){alert("Second number should be between 10 and 99!");document.querySelector("#num2").value="";// empty second input field}}}
Each of the four separate products should now populate the center table cells.
Step 5: Populating the Table: Obtaining Horizontal and Vertical Totals¶
Now, we focus on getting the horizontal and vertical totals of the intermediary products.
The cell containing the sum across
functionmultiply(){letnum1=parseInt(document.querySelector("#num1").value);letnum2=parseInt(document.querySelector("#num2").value);// replace num1 and num2 with parsed integer (if not integers)// alert user when number is replacedif(parseFloat(document.querySelector("#num1").value)!==parseInt(document.querySelector("#num1").value)){if(document.querySelector("#num1").value==""){alert("First number input is empty.");}else{alert("First number isn't an integer. Replacing value at input field with parsed integer value instead.",);document.querySelector("#num1").value=num1;}}if(parseFloat(document.querySelector("#num2").value)!==parseInt(document.querySelector("#num2").value)){if(document.querySelector("#num2").value==""){alert("Second number input is empty.");}else{alert("Second number isn't an integer. Replacing value at input field with parsed integer value instead.",);document.querySelector("#num2").value=num2;}}// check if num1 and num2 is between 10 and 99 (inclusive)if(num1>=10&&num1<=99&&num2>=10&&num2<=99){// show number in num?_showdocument.querySelector("#num1_show").innerHTML=num1;document.querySelector("#num2_show").innerHTML=num2;// split number into digits based on tens and units valueletarr_num1=[Math.floor(num1/10)*10,num1%10];letarr_num2=[Math.floor(num2/10)*10,num2%10];// show digits in num?a or num?bdocument.querySelector("#num1a").innerHTML=arr_num1[0];document.querySelector("#num1b").innerHTML=arr_num1[1];document.querySelector("#num2a").innerHTML=arr_num2[0];document.querySelector("#num2b").innerHTML=arr_num2[1];/** * Calculate intermediary multiplication values * * Key: * m1 = num1a * num2a * m2 = num1b * num2a * m3 = num1a * num2b * m4 = num1b * num2b */constm1=arr_num1[0]*arr_num2[0];constm2=arr_num1[1]*arr_num2[0];constm3=arr_num1[0]*arr_num2[1];constm4=arr_num1[1]*arr_num2[1];// Display intermediary multiplication valuesdocument.querySelector("#m1").innerHTML=m1;document.querySelector("#m2").innerHTML=m2;document.querySelector("#m3").innerHTML=m3;document.querySelector("#m4").innerHTML=m4;// add horizontal row values and display the sumsdocument.querySelector("#m1_m2").innerHTML=m1+m2;document.querySelector("#m3_m4").innerHTML=m3+m4;// add vertical column values and display the sumsdocument.querySelector("#m1_m3").innerHTML=m1+m3;document.querySelector("#m2_m4").innerHTML=m2+m4;// to continue more here}else{// if first number is not between 10 and 99 (inclusive)if(num1<10||num1>99){alert("First number should be between 10 and 99!");document.querySelector("#num1").value="";// empty first input field}// if secondnumber is not between 10 and 99 (inclusive)if(num2<10||num2>99){alert("Second number should be between 10 and 99!");document.querySelector("#num2").value="";// empty second input field}}}
The table should now contain the horizontal and vertical totals as shown.
Step 6: Retrieving and Displaying the Final Product¶
Finally, we get to displaying the final product from multiplying the integers in the input fields.
The vertical sum between values in cells #m1_m2 and #m3_m4 or #m1_m3 and #m2_m4 will suffice in this case.
We first store this sum in a variable first before displaying them in the table cell #m_total and the #numAns input field.
functionmultiply(){letnum1=parseInt(document.querySelector("#num1").value);letnum2=parseInt(document.querySelector("#num2").value);// replace num1 and num2 with parsed integer (if not integers)// alert user when number is replacedif(parseFloat(document.querySelector("#num1").value)!==parseInt(document.querySelector("#num1").value)){if(document.querySelector("#num1").value==""){alert("First number input is empty.");}else{alert("First number isn't an integer. Replacing value at input field with parsed integer value instead.",);document.querySelector("#num1").value=num1;}}if(parseFloat(document.querySelector("#num2").value)!==parseInt(document.querySelector("#num2").value)){if(document.querySelector("#num2").value==""){alert("Second number input is empty.");}else{alert("Second number isn't an integer. Replacing value at input field with parsed integer value instead.",);document.querySelector("#num2").value=num2;}}// check if num1 and num2 is between 10 and 99 (inclusive)if(num1>=10&&num1<=99&&num2>=10&&num2<=99){// show number in num?_showdocument.querySelector("#num1_show").innerHTML=num1;document.querySelector("#num2_show").innerHTML=num2;// split number into digits based on tens and units valueletarr_num1=[Math.floor(num1/10)*10,num1%10];letarr_num2=[Math.floor(num2/10)*10,num2%10];// show digits in num?a or num?bdocument.querySelector("#num1a").innerHTML=arr_num1[0];document.querySelector("#num1b").innerHTML=arr_num1[1];document.querySelector("#num2a").innerHTML=arr_num2[0];document.querySelector("#num2b").innerHTML=arr_num2[1];/** * Calculate intermediary multiplication values * * Key: * m1 = num1a * num2a * m2 = num1b * num2a * m3 = num1a * num2b * m4 = num1b * num2b */constm1=arr_num1[0]*arr_num2[0];constm2=arr_num1[1]*arr_num2[0];constm3=arr_num1[0]*arr_num2[1];constm4=arr_num1[1]*arr_num2[1];// Display intermediary multiplication valuesdocument.querySelector("#m1").innerHTML=m1;document.querySelector("#m2").innerHTML=m2;document.querySelector("#m3").innerHTML=m3;document.querySelector("#m4").innerHTML=m4;// add horizontal row values and display the sumsdocument.querySelector("#m1_m2").innerHTML=m1+m2;document.querySelector("#m3_m4").innerHTML=m3+m4;// add vertical column values and display the sumsdocument.querySelector("#m1_m3").innerHTML=m1+m3;document.querySelector("#m2_m4").innerHTML=m2+m4;// calculate productconstproduct=parseInt(document.querySelector("#m1_m2").innerHTML)+parseInt(document.querySelector("#m3_m4").innerHTML);// or// const product =// parseInt(document.querySelector("#m1_m3").innerHTML) + parseInt(document.querySelector("#m2_m4").innerHTML);// display full product in tabledocument.querySelector("#m_total").innerHTML=product;// display full product in answer input fielddocument.querySelector("#numAns").value=product;}else{// if first number is not between 10 and 99 (inclusive)if(num1<10||num1>99){alert("First number should be between 10 and 99!");document.querySelector("#num1").value="";// empty first input field}// if secondnumber is not between 10 and 99 (inclusive)if(num2<10||num2>99){alert("Second number should be between 10 and 99!");document.querySelector("#num2").value="";// empty second input field}}}
And.. it's complete. Well done!
And voila, we've just created a replica of the multiplication box/table used by some teachers to help teach children about multiplication between two-digit numbers!
This intermediate-level activity will provide a guide as to how you can effectively use program control structures to skillfully loop through the same calculation process with different sets of inputs at a time.
@font-face{font-family:"SF Pro Display";src:url("../fonts/SF-Pro-Display-Regular.otf");}*{font-family:"SF Pro Display",sans-serif;}h1{font-size:48px;}hr{margin:2rem0;}button{background-color:transparent;border-radius:1rem;font-size:24px;padding:0.5rem1rem;}button:hover{box-shadow:001remyellowgreen,005remlemonchiffon;cursor:pointer;}button:active{background-color:lemonchiffon;}.text-center{text-align:center;}
input[type="number"]{text-align:right;}input:read-only{background-color:khaki;}/* For Chrome, Safari, Edge, Opera */input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0;}/* For Firefox */input[type="number"]{-moz-appearance:textfield;}
functioncalculate(){// Variables to contain total valuesletasgn1_total=0,asgn2_total=0,grand_total=0;// We'll use a constant to referece the <table> element to try to shorten the code.constTABLE=document.querySelector("table");// Calculate number of rows in between top and bottom rowconstNUMBER_OF_STUDENTS=TABLE.rows.length-2;// we will be adding code from here}functionclearTable(){// Initialize Asgn 1 & Asgn 2 (100% each) to 0document.querySelectorAll(`input:not(:read-only)`).forEach((inputField)=>(inputField.value="0"));// Initialize Asgn & Total Points to 0.00document.querySelectorAll(`input:read-only`).forEach((inputField)=>(inputField.value="0.00"));}window.onload=clearTable();
You should be able to see the following in your web browser:
Mark Demo Page
Here, each row represents a student's record.
Each student would have had 2 assessment components graded on a 0 to 100 percent scale.
When the button at the bottom of the page (i.e., Calculate Total and Average) is selected, each student's Assignment 1 and 2's respective point weightage is calculated based on the input marks.
This is followed up by the calculation of points obtained by each student, along with the cumulative average of each point component.
The button has an onclick attribute that invokes the calculate() function when clicked on.
Another button to clear the table is present alongside while having its functionality tied in with the clearTable() function.
The clearTable() function contains two statements.
The first statement targets all input fields not set to read-only to "0", whilst the second statement sets the remaining input fields' value attribute to "0.00".
Both statements use the forEach() method, but a regular for loop will also suffice here.
The forEach() method retrieves each related input field and autonomously sets their value attributes accordingly.
The starting point in script.js should give some light onto the function of concern: the calculate() function.
At first, we initialize variables asgn1_total, asgn2_total and grand_total to contain the total sum of all points.
We will revisit them later, but for now we initialize all of them with the value 0.
We will also make reference to the <table> element a lot here.
In order to shorten the code as to simplify the process, we declare a constant variable named TABLE referencing this <table> element.
In addition, we refer to the number of student records to be put in as TABLE.rows.length - 2.
Of course, we can immediately take it as just 3 since there isn't any functionality to add more rows that'll question whether the number of records will stay put.
Not only that, the way you calculate the number of students will depend on whether you semantic tags within your <table> element; if so, the value of NUMBER_OF_STUDENTS constant should be calculated differently.
functioncalculate(){// Variables to contain total valuesletasgn1_total=0,asgn2_total=0,grand_total=0;// We'll use a constant to referece the <table> element to try to shorten the code.constTABLE=document.querySelector("table");// Calculate number of rows in between top and bottom rowconstNUMBER_OF_STUDENTS=TABLE.rows.length-2;// we will be adding code from here}functionclearTable(){// Initialize Asgn 1 & Asgn 2 (100% each) to 0document.querySelectorAll(`input:not(:read-only)`).forEach((inputField)=>(inputField.value="0"));// Initialize Asgn & Total Points to 0.00document.querySelectorAll(`input:read-only`).forEach((inputField)=>(inputField.value="0.00"));}window.onload=clearTable();
Now here's the bit that would take many lines if done without any program control structures in place.
We mitigate needing to write numerous lines of code by introducing a for loop that will iterate over each row while obtaining values from each of its associated input fields.
The id attribute values for each input field referencing the total marks (100%) for each student is named in a fashion similar to this: #stu${i}_asgn1 and #stu${i}_asgn2.
More specifically, you will find input fields with the following id attribute values:
Student 1: #stu1_asgn1, #stu1_asgn2
Student 2: #stu2_asgn1, #stu2_asgn2
Student 3: #stu3_asgn1, #stu3_asgn2
Notice a pattern in how the id attribute values are aptly named?
By iterating an iterator variable (we'll be using i here), we can run this in a for loop to write out each required statement once!
The first order of action in this for loop is to check whether there are any unfilled input fields in any of the six input fields with the aforementioned id attribute values.
Should there be any, they will be automatically filled with "0".
This will help prevent errors during the calculation of total and average points.
functioncalculate(){// Variables to contain total valuesletasgn1_total=0,asgn2_total=0,grand_total=0;// We'll use a constant to referece the <table> element to try to shorten the code.constTABLE=document.querySelector("table");// Calculate number of rows in between top and bottom rowconstNUMBER_OF_STUDENTS=TABLE.rows.length-2;for(leti=1;i<=NUMBER_OF_STUDENTS;++i){/** * Check if #stu?_asgn1 and #stu?_asgn2 are empty * If empty, place in 0 values. */if(document.querySelector(`#stu${i}_asgn1`).value==""){document.querySelector(`#stu${i}_asgn1`).value="0";}if(document.querySelector(`#stu${i}_asgn2`).value==""){document.querySelector(`#stu${i}_asgn2`).value="0";}// we will be adding code from here}}functionclearTable(){// Initialize Asgn 1 & Asgn 2 (100% each) to 0document.querySelectorAll(`input:not(:read-only)`).forEach((inputField)=>(inputField.value="0"));// Initialize Asgn & Total Points to 0.00document.querySelectorAll(`input:read-only`).forEach((inputField)=>(inputField.value="0.00"));}window.onload=clearTable();
Negative Value for Marks
The procedure above doesn't cater for negative marks.
Assuming that the marks entered should be nonnegative, how would you go about catering for this requirement?
Now we get to calculating the total points obtained from the entered Assignment 1 and 2 marks.
From the table, we can probably guess that the total points obtained for the
Assignment 1 component is to be scaled from 100% to 20 points (i.e., multiply by 0.2)
Assignment 2 component is to be scaled from 100% to 30 points (i.e., multiply by 0.3)
During each for loop iteration, we store the points obtained for Assignment 1 and Assignment 2 into asgn1_points and asgn2_points respectively.
Then from here, we display them in #stu${i}_asgn1_points and #stu${i}_asgn2_points, where i still represents the iteration number/row count/student count.
These point values are displayed in 2 decimal places using an appended .toFixed() function, which takes in 2 as the parameter denoting the number of decimal places to be shown.
After both asgn1_points and asgn2_points have been calculated, we proceed with adding both of them to stu_total before displaying them in a similar fashion in #stu${i}_total_points with the same number of decimal places shown.
Also, during each iteration,
the value of asgn1_points is added to asgn1_total,
the value of asgn2_points is added to asgn2_total, and
the value of grand_points is added to grand_total.
functioncalculate(){// Variables to contain total valuesletasgn1_total=0,asgn2_total=0,grand_total=0;// We'll use a constant to referece the <table> element to try to shorten the code.constTABLE=document.querySelector("table");// Calculate number of rows in between top and bottom rowconstNUMBER_OF_STUDENTS=TABLE.rows.length-2;for(leti=1;i<=NUMBER_OF_STUDENTS;++i){/** * Check if #stu?_asgn1 and #stu?_asgn2 are empty * If empty, place in 0 values. */if(document.querySelector(`#stu${i}_asgn1`).value==""){document.querySelector(`#stu${i}_asgn1`).value="0";}if(document.querySelector(`#stu${i}_asgn2`).value==""){document.querySelector(`#stu${i}_asgn2`).value="0";}// calculate the marks from total percentageletasgn1_points=parseFloat(document.querySelector(`#stu${i}_asgn1`).value)*0.2;letasgn2_points=parseFloat(document.querySelector(`#stu${i}_asgn2`).value)*0.3;document.querySelector(`#stu${i}_asgn1_points`).value=asgn1_points.toFixed(2);document.querySelector(`#stu${i}_asgn2_points`).value=asgn2_points.toFixed(2);// calculate total marks for given studentletstu_total=parseFloat(document.querySelector(`#stu${i}_asgn1_points`).value)+parseFloat(document.querySelector(`#stu${i}_asgn2_points`).value);document.querySelector(`#stu${i}_total_points`).value=stu_total.toFixed(2);// add to respective totalsasgn1_total+=asgn1_points;asgn2_total+=asgn2_points;grand_total+=stu_total;}// Note: use parseFloat() to get number with decimal places, and parseInt() to get Integer values (non-decimal)// we will be adding code from here}functionclearTable(){// Initialize Asgn 1 & Asgn 2 (100% each) to 0document.querySelectorAll(`input:not(:read-only)`).forEach((inputField)=>(inputField.value="0"));// Initialize Asgn & Total Points to 0.00document.querySelectorAll(`input:read-only`).forEach((inputField)=>(inputField.value="0.00"));}window.onload=clearTable();
Finally, we get to calculating the average points obtained among all students for Assignment 1, Assignment 2, and accumulatively.
The averages for each component are stored in asgn1_avg, asgn2_avg, and grand_avg respectively.
These averages are calculated by dividing their respective totals by the number of students (i.e., NUMBER_OF_STUDENTS).
The last course of action is to display them in the input fields with id attribute values #avg1, #avg2, #avg_total.
functioncalculate(){// Variables to contain total valuesletasgn1_total=0,asgn2_total=0,grand_total=0;// We'll use a constant to referece the <table> element to try to shorten the code.constTABLE=document.querySelector("table");// Calculate number of rows in between top and bottom rowconstNUMBER_OF_STUDENTS=TABLE.rows.length-2;for(leti=1;i<=NUMBER_OF_STUDENTS;++i){/** * Check if #stu?_asgn1 and #stu?_asgn2 are empty * If empty, place in 0 values. */if(document.querySelector(`#stu${i}_asgn1`).value==""){document.querySelector(`#stu${i}_asgn1`).value="0";}if(document.querySelector(`#stu${i}_asgn2`).value==""){document.querySelector(`#stu${i}_asgn2`).value="0";}// calculate the marks from total percentageletasgn1_points=parseFloat(document.querySelector(`#stu${i}_asgn1`).value)*0.2;letasgn2_points=parseFloat(document.querySelector(`#stu${i}_asgn2`).value)*0.3;document.querySelector(`#stu${i}_asgn1_points`).value=asgn1_points.toFixed(2);document.querySelector(`#stu${i}_asgn2_points`).value=asgn2_points.toFixed(2);// calculate total marks for given studentletstu_total=parseFloat(document.querySelector(`#stu${i}_asgn1_points`).value)+parseFloat(document.querySelector(`#stu${i}_asgn2_points`).value);document.querySelector(`#stu${i}_total_points`).value=stu_total.toFixed(2);// add to respective totalsasgn1_total+=asgn1_points;asgn2_total+=asgn2_points;grand_total+=stu_total;}// Note: use parseFloat() to get number with decimal places, and parseInt() to get Integer values (non-decimal)// calculate averageconstasgn1_avg=asgn1_total/NUMBER_OF_STUDENTS;constasgn2_avg=asgn2_total/NUMBER_OF_STUDENTS;constgrand_avg=grand_total/NUMBER_OF_STUDENTS;// assign average to correct input fieldsdocument.querySelector(`#avg1`).value=asgn1_avg.toFixed(2);document.querySelector(`#avg2`).value=asgn2_avg.toFixed(2);document.querySelector(`#avg_total`).value=grand_avg.toFixed(2);// Note: toFixed(2) sets number values to display 2 decimal places}functionclearTable(){// Initialize Asgn 1 & Asgn 2 (100% each) to 0document.querySelectorAll(`input:not(:read-only)`).forEach((inputField)=>(inputField.value="0"));// Initialize Asgn & Total Points to 0.00document.querySelectorAll(`input:read-only`).forEach((inputField)=>(inputField.value="0.00"));}window.onload=clearTable();
This is the end - you've successfully completed the Mark Demo page.. congrats!!