Introduction
Class Activity Calculator is an online application to calculate the students’ class activity grades. The class activity grade (CA) is calculated based on the marks a student gets during the term. Here’s a sample grade sheet we use in class:
Please review the code and provide feedback.
Credit: Special thanks to the JavaScript guru, Paul Wilkins, for his valuable pointers, without which my app wouldn’t work!
Source
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Calculate the class activity grades of the ILI students.">
<title>Class Activity Calculator</title>
<link rel="icon" href="favicon.ico">
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
<img src="logo.png" alt="Logo">
<h1>Class Activity Calculator</h1>
</header>
<nav>
<a href="index.html" id="current">Adults: Old</a>
<a href="adults-new.html">Adults: New</a>
<a href="young-adults.html">Young Adults</a>
<a href="kids.html">Kids</a>
</nav>
<main>
<form autocomplete="off">
<fieldset data-weight="4">
<legend>Listening & Speaking</legend>
<input type="number" step="any" min="0" max="100">
<input type="number" step="any" min="0" max="100">
<input type="number" step="any" min="0" max="100">
<input type="number" step="any" min="0" max="100">
<input type="number" step="any" min="0" max="100">
<output></output>
</fieldset>
<fieldset data-weight="3">
<legend>Reading</legend>
<input type="number" step="any" min="0" max="100">
<input type="number" step="any" min="0" max="100">
<input type="number" step="any" min="0" max="100">
<input type="number" step="any" min="0" max="100">
<input type="number" step="any" min="0" max="100">
<output></output>
</fieldset>
<fieldset data-weight="1">
<legend>Writing</legend>
<input type="number" step="any" min="0" max="100">
<input type="number" step="any" min="0" max="100">
<input type="number" step="any" min="0" max="100">
<input type="number" step="any" min="0" max="100">
<input type="number" step="any" min="0" max="100">
<output></output>
</fieldset>
<div>
<button type="button">Calculate</button>
<output></output>
<button type="reset">Reset</button>
</div>
</form>
</main>
<footer>
Share on <a href="https://t.me/share/url?url=https%3A%2F%2Fclassactivitycalculator.github.io%2F&text=Class%20Activity%20Calculator%3A%20Calculate%20the%20class%20activity%20grades%20of%20the%20ILI%20students." title="Telegram: Share Web Page">Telegram</a> |
<a href="https://www.facebook.com/dialog/share?app_id=2194746457255787&href=https%3A%2F%2Fclassactivitycalculator.github.io%2F" title="Post to Facebook">Facebook</a>
<address><a href="https://t.me/MortezaMirmojarabian" title="Telegram: Contact @MortezaMirmojarabian" rel="author">Give feedback</a></address>
</footer>
<script>
function setOutputValues() {
var totalWeightedAverage = 0;
var totalWeight = 0;
var fieldsets = form.querySelectorAll('fieldset');
for (var fieldset of fieldsets) {
var average = averageInputValues(fieldset);
var fieldsetOutput = fieldset.querySelector('output');
if (average == undefined) {
fieldsetOutput.value = 'You may only enter 0 to 100.';
} else if (isNaN(average)) {
fieldsetOutput.value = 'Please enter a grade.';
} else {
fieldsetOutput.value = 'avg: ' + average.toFixed(1);
}
totalWeightedAverage += average * fieldset.dataset.weight;
totalWeight += Number(fieldset.dataset.weight);
}
var classActivity = totalWeightedAverage / totalWeight;
var divOutput = form.querySelector('div output');
if (isNaN(classActivity)) {
divOutput.value = '';
} else {
divOutput.value = 'CA: ' + classActivity.toFixed(1);
}
}
</script>
<script src="global.js"></script>
</body>
</html>
global.js
var form = document.querySelector('form');
function averageInputValues(fieldset) {
var totalValue = 0;
var totalNumber = 0;
var inputs = fieldset.querySelectorAll('input');
for (var input of inputs) {
if (!input.validity.valid) {
return;
}
totalValue += Number(input.value);
totalNumber += Boolean(input.value);
}
return totalValue / totalNumber;
}
form.querySelector('[type="button"]').addEventListener('click', setOutputValues);
function detectChange() {
var inputs = form.querySelectorAll('input');
for (var input of inputs) {
if (input.value) {
return true;
}
}
}
form.querySelector('[type="reset"]').addEventListener('click', function(event) {
if (detectChange() && !confirm('Your changes will be lost.\nAre you sure you want to reset?')) {
event.preventDefault();
}
});
window.addEventListener('beforeunload', function(event) {
if (detectChange()) {
event.returnValue = 'Your changes may be lost.';
}
});