Skip to content

Instantly share code, notes, and snippets.

@nsmaciej
Created February 26, 2018 16:56
Show Gist options
  • Save nsmaciej/e023e45635d9a51d3c9d827129dd9062 to your computer and use it in GitHub Desktop.
Save nsmaciej/e023e45635d9a51d3c9d827129dd9062 to your computer and use it in GitHub Desktop.
Assignment 1
<!doctype html>
<html>
<head>
<title>Student Assigments</title>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
font-family: Helvetica, "Trebuchet MS", Verdana, sans-serif;
color: #444444;
margin: 40px 20px;
text-align: center;
line-height: 1.5;
}
.center {
display: inline-block;
text-align: left;
}
table {
border-collapse: collapse;
}
h1, h2, th {
color: #000000;
}
h1 {
font-size: 3em;
font-weight: bolder;
}
h2 {
margin-bottom: 2em;
color: #d9d9d9;
}
input {
font: inherit;
}
.st-table th {
text-align: center;
}
.st-table tr:not(:first-child):hover {
background: #d9d9d9;
}
.st-table tr:nth-child(even), .st-table tr:nth-child(even) input {
background: #f4f4f4;
}
.st-table tr td:first-child {
font-weight: bold;
}
.st-table td, .st-table th {
height: 2rem;
padding: 0 10px;
white-space: nowrap;
}
.st-grade-cell {
padding: 0 !important;
}
.st-grade-invalid {
border: 2px solid #ff0000 !important;
}
.st-avg, .st-grade {
text-align: right;
}
.st-grade {
outline: none;
box-sizing: content-box;
transition: border 200ms;
border: 2px solid transparent; /* Keeps the size the same */
height: 100%;
width: 15ex;
border-radius: 0px;
}
.st-grade:focus {
background: #ffffff !important;
border-color: #5294ff;
border-radius: 3px;
}
.st-grade:placeholder-shown:not(:focus) {
background: #ffffad !important;
}
tr:hover .st-grade:placeholder-shown:not(:focus) {
background: #feff55 !important;
}
.st-avg-low {
background: #ff5b57;
color: #ffffff;
}
tr:not(:first-child):hover .st-avg-low {
background: #ff3636;
}
.students {
display: inline-flex;
flex-flow: column;
align-items: center;
}
heading {
align-self: flex-start;
}
button {
border-radius: 3px;
background: transparent;
border: 1px solid #5294ff;
min-width: 20ex;
padding: 5px;
color: #054aff;
font-weight: bold;
margin-top: 8px;
transition: background-color 150ms, color 150ms;
letter-spacing: 0.15ex;
}
button:hover {
background: #5294ff;
color: #ffffff;
}
button:active {
background: #0e64ff;
border-color: #0e64ff;
color: #ffffff;
}
/* We set height to 0 so it doesn't influence flex box offset */
.st-unsubmitted {
align-self: flex-end;
height: 0;
font-style: italic;
}
.students textarea {
resize: none;
margin-top: 30px;
border-radius: 3px;
border: 1px solid #cccccc;
color: #cccccc;
padding: 5px;
width: 50%;
height: 5rem;
}
</style>
</head>
<body>
<div class="center">
<heading>
<h1>Assigment 1</h1>
<h2>Maciej Goszczycki</h2>
</heading>
<div class="students">
<table class="st-table">
<tr>
<th>Name</th>
<th>ID</th>
<th>Assigment 1</th>
<th>Assigment 2</th>
<th>Assigment 3</th>
<th>Assigment 4</th>
<th>Assigment 5</th>
<th>Final Grade</th>
</tr>
</table>
<p class="st-unsubmitted">
<span class="st-assigments">0</span> Unsubmitted assignments
</p>
<button class="st-recalc">Recalculate</button>
<textarea class="st-csv" disabled></textarea>
<button class="st-download">Download</button>
</div>
<script src="index.js"></script>
</div>
<script>
var data = [
["Maciej Ashmore", "13616988"],
["Jessie Murphy", "16782334"],
["Phil Davey", "15789933"],
["Eoin Maguire", "16678931"],
["Julian King", "14678211"],
["Cai O'Brien", "16169837"],
["Liam Wood", "16789223b"],
["Sam Nagi", "17823932"],
["Sara Goszczycki", "14590142"],
["Tomas Honer", "12069170"]
];
function elems(elem, sel) {
var c = sel ? elem.querySelectorAll(sel) : document.querySelectorAll(elem);
return Array.prototype.slice.call(c);
}
function setval(elem, sel, val) {
elems(elem, sel).forEach(function (x) { return x.innerHTML = val; });
}
function avarage(lst) {
return sum(lst) / lst.length;
}
function sum(lst) {
return lst.reduce(function (r, i) { return r + (i || 0); }, 0);
}
function studentTemplate(name) {
var field = '<td class="st-grade-cell"><input type="number" class="st-grade" placeholder="-"></td>';
return "\n <td>" + name[0] + "</th>\n <td>" + name[1] + "</th>\n " + field.repeat(5) + "\n <td class=\"st-avg\">N/A</td>";
}
var StudentTable = (function () {
function StudentTable(wrap) {
var _this = this;
this.rows = [];
this.container = wrap;
this.table = this.container.querySelector(".st-table");
this.table.createTBody();
this.container.querySelector(".st-recalc").addEventListener("click", function () {
_this.recalculate();
});
this.container.querySelector(".st-download").addEventListener("click", function () {
var blob = new Blob([_this.csvValue()], { "type": "text/csv" });
var link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "assinments.csv";
link.click();
});
for (var _i = 0, data_1 = data; _i < data_1.length; _i++) {
var i = data_1[_i];
var row = this.table.insertRow();
this.rows.push(row);
row.innerHTML = studentTemplate(i);
for (var _a = 0, _b = elems(row, ".st-grade"); _a < _b.length; _a++) {
var j = _b[_a];
j.addEventListener("input", function (e) { return _this.handleInput(e); });
}
}
this.recalculate();
}
StudentTable.prototype.recalculate = function () {
var s = 0;
for (var _i = 0, _a = this.rows; _i < _a.length; _i++) {
var row = _a[_i];
var grades = elems(row, ".st-grade").map(function (x) { return parseInt(x.value); });
var percent = Math.round(avarage(grades));
var cell = row.querySelector(".st-avg");
cell.innerHTML = percent + "%";
cell.classList.toggle("st-avg-low", percent < 40);
s += sum(grades.map(function (x) { return +isNaN(x); }));
}
setval(this.container, ".st-assigments", s.toString());
setval(this.container, ".st-csv", this.csvValue());
};
StudentTable.prototype.handleInput = function (evt) {
var p = evt.target;
var v = parseInt(p.value);
if (!/^[0-9]*$/.test(p.value) || v > 100 || v < 0) {
var cname_1 = "st-grade-invalid";
p.classList.add(cname_1);
setTimeout(function () { return p.classList.remove(cname_1); }, 500);
p.value = "";
}
else {
p.value = v.toString(); // Trim any zeros etc.
}
this.recalculate();
};
StudentTable.prototype.csvValue = function () {
return elems(this.table, "tr").map(function (x) {
return elems(x, "td, th").map(function (x) {
var p = x.querySelector("input");
return "\"" + (p ? p.value : x.innerText) + "\"";
}).join(",");
}).join("\n");
};
return StudentTable;
}());
elems(".students").forEach(function (x) { return new StudentTable(x); });
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment