JSFiddle - React, Tailwind, and code Playground
HTML
<h2>Your Classroom Gradebook</h2>
<div>
<button data-bind="click: addStudent">Add a Student</button>
<button data-bind="click: addWork">Add New Assignment</button>
<button data-bind="click: dropLowestScores">Drop Lowest Scores</button>
<table>
<thead>
<tr>
<th>Name</th>
<!-- ko foreach: assignments -->
<th><p>
<b data-bind="visible: !editing(), text: workName(), click: edit"> </b>
<input data-bind="value: workName, visible: editing, hasFocus: editing"/>
<select data-bind="options: $root.workTypes, value: workType, optionsText: 'workType'"></select>
</p></th>
<!-- /ko -->
<th>Student Grade</th>
</tr>
</thead>
<tbody>
<!-- ko foreach: students -->
<tr>
<td>
<b data-bind="text: $index()+1"></b>
<span data-bind="visible: !editing(), text: fullName(), click: edit"> </span>
<input data-bind="value: fullName, visible: editing, hasFocus: editing"/>
</td>
<!-- ko foreach: scores -->
<td><input data-bind="value: $rawData"/></td>
<!-- /ko -->
<td data-bind="text: mean, uniqueName: console.log('mean ' + mean())" />
<td><input type="button" value="remove" data-bind="click: $root.removeStudent.bind($root)". /></td>
</tr>
<!-- /ko -->
<tr>
<td><b>Class Assignment Average</b></td>
<!-- ko foreach: assignments -->
<td data-bind="text: $root.workMean($data, $index())"></td>
<!-- /ko -->
<td></td>
</tr>
</tbody>
</table>
JavaScript
var Gradebook;
var Gradebook;
(function (Gradebook) {
(function (Model) {
var StudentModel = (function () {
function StudentModel(fullName) {
var _this = this;
this.fullName = ko.observable(fullName);
this.editing = ko.observable(false);
this.edit = function() { _this.editing(true); };
this.scores = ko.observableArray();
this.lowest = ko.observableArray();
this.mean = ko.computed(
function() {
var sum = 0;
var count = 0;
var n = 0;
for(n;n < _this.scores().length;n++)
{
var score = _this.scores()[n];
if (_this.lowest.indexOf(score)<0) {
sum += parseFloat(score());
count++;
}
}
if (count > 0) {
sum = sum / count;
return sum.toFixed(2);
} else {
return 'N/A';
}
});
}
return StudentModel;
})();
Model.StudentModel = StudentModel;
})(Gradebook.Model || (Gradebook.Model = {}));
var Model = Gradebook.Model;
})(Gradebook || (Gradebook = {}));
var Gradebook;
(function (Gradebook) {
(function (Model) {
var WorkModel = (function () {
function WorkModel(workName,workType) {
var _this = this;
this.workName = ko.observable(workName);
this.workType = ko.observable(workType);
this.editing = ko.observable(false);
this.edit = function() { _this.editing(!_this.editing()); }; ...