I have a lectures table that is empty at first, but when the user clicks the add lecture button, it generates a new row using this function. Here is the event listener for adding rows:
const addLectureScoreBtn = document.getElementById("add-lecture-score-btn");
addLectureScoreBtn.addEventListener("click", () => {
const lectureScoresTable = document.getElementById("lecture-score-table");
const newRow = document.createElement("tr");
const lectureNameCell = document.createElement("td");
const lectureNameSelect = document.createElement("select");
lectureNameSelect.id = "lecture-name";
lectureNameSelect.name = "lecture-name";
lectures.forEach((lecture) => {
const option = document.createElement("option");
option.value = lecture.name;
option.text = lecture.name;
lectureNameSelect.add(option);
});
console.log(lectureNameSelect)
lectureNameCell.appendChild(lectureNameSelect);
newRow.appendChild(lectureNameCell);
const midtermCell = document.createElement("td");
const midtermInput = document.createElement("input");
midtermCell.appendChild(midtermInput);
midtermInput.type = "number";
midtermInput.value = 0;
midtermInput.addEventListener("change", () => {
if (midtermInput.value < 0 || midtermInput.value > 100) {
midtermInput.value = 0;
}
});
newRow.appendChild(midtermCell);
const finalCell = document.createElement("td");
const finalInput = document.createElement("input");
finalInput.type = "number";
finalInput.value = 0;
finalCell.appendChild(finalInput);
newRow.appendChild(finalCell);
lectureScoresTable.appendChild(newRow);
const actionsCell = document.createElement("td");
const deleteBtn = document.createElement("button");
deleteBtn.type = "button";
deleteBtn.textContent = "Delete";
deleteBtn.addEventListener("click", () => deleteRow(newRow));
actionsCell.appendChild(deleteBtn);
newRow.appendChild(actionsCell);
});
After user creates table with grades and selection of lectures, they click save button, when save button clicked, an item like this should be created and added to the students array that was already defined
//it is just an example object
const exampleStudent = {
id:'123456'
name:'John'
surname:'Doe'
lectures: [
{
lecture:{code:'2332',name:'Web Development'}, //Whole lecture object
midterm:40,
final:50 }]
The problem is most likely here in the createStudent() function, i have tried several methods, but apparently, none of the rows of the table is identified by the code, all of their values are undefined. Here is a version of what i tried already:
function createStudent() {
// create a new student object
const student = {
id: 0,
name: '',
surname: '',
lectures: [], //push lecture object
gpa: 0
};
//get id from input
const studentId = document.getElementById('student-id');
const studentName = document.getElementById('student-name');
const studentSurname = document.getElementById('student-surname');
const lectureScoresTable = document.getElementById("lecture-score-table");
lectureScoresTable.querySelectorAll('tr').forEach((row) => {
const lectureName = row.querySelectorAll('lecture-name');
const midterm = row.querySelector('#midterm');
const final = row.querySelector('#final');
const lecture = {
lecture: lectures.find((lecture) => lecture.name === lectureName.value),
midterm: midterm.value,
final: final.value
};
student.lectures.push(lecture);
}
);
student.id = studentId.value;
student.name = studentName.value;
student.surname = studentSurname.value;
student.gpa = calculateGPA(student.lectures);
//TODO
}
This code throws an error that says, cannot read properties of null PS: Please do not respond in JQuery or any other frameworks, services, i am only using vanilla js html and css
CodePudding user response:
Check if this suits your needs.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<label>Id</label> <input id="student-id" type="text" />
<br />
<label>Name</label> <input id="student-name" type="text" />
<br />
<label>Surname</label> <input id="student-surname" type="text" />
<br />
<button id="add-lecture-score-btn">Add Lecture</button>
<table id="lecture-score-table"></table>
<button id="create-student-btn">Create Student</button>
<script>
const lectures = [
{ code: "2332", name: "Web Development" },
{ code: "2339", name: "Databases" },
{ code: "5332", name: "Project Managing" },
{ code: "8332", name: "Requirement Elicitation" },
];
const calculateGPA = () => {
//TODO
return "GPA";
};
document.getElementById("add-lecture-score-btn").addEventListener("click", () => {
const lectureScoresTable = document.getElementById("lecture-score-table");
const newRow = document.createElement("tr");
const lectureNameCell = document.createElement("td");
const lecturesSelect = document.createElement("select");
lecturesSelect.classList.add("lectures");
const selectOption = document.createElement("option");
selectOption.value = "";
selectOption.text = " - Select - ";
lecturesSelect.add(selectOption);
lectures.forEach((lecture) => {
const option = document.createElement("option");
option.value = lecture.code;
option.text = lecture.name;
lecturesSelect.add(option);
});
lectureNameCell.appendChild(lecturesSelect);
newRow.appendChild(lectureNameCell);
const midtermCell = document.createElement("td");
const midtermInput = document.createElement("input");
midtermInput.type = "number";
midtermInput.value = 0;
midtermInput.classList.add("midterm");
midtermCell.appendChild(midtermInput);
midtermInput.addEventListener("change", () => {
if (midtermInput.value < 0 || midtermInput.value > 100) {
midtermInput.value = 0;
}
});
newRow.appendChild(midtermCell);
const finalCell = document.createElement("td");
const finalInput = document.createElement("input");
finalInput.type = "number";
finalInput.value = 0;
finalInput.classList.add("final");
finalCell.appendChild(finalInput);
newRow.appendChild(finalCell);
lectureScoresTable.appendChild(newRow);
const actionsCell = document.createElement("td");
const deleteBtn = document.createElement("button");
deleteBtn.type = "button";
deleteBtn.textContent = "Delete";
deleteBtn.addEventListener("click", () => newRow.remove());
actionsCell.appendChild(deleteBtn);
newRow.appendChild(actionsCell);
});
const exampleStudent = {
id: "123456",
name: "John",
surname: "Doe",
lectures: [
{
lecture: { code: "2332", name: "Web Development" }, //Whole lecture object
midterm: 40,
final: 50,
},
],
};
document.getElementById("create-student-btn").addEventListener("click", () => {
const student = {
id: 0,
name: "",
surname: "",
lectures: [],
gpa: 0,
};
student.id = document.getElementById("student-id").value;
student.name = document.getElementById("student-name").value;
student.surname = document.getElementById("student-surname").value;
document
.getElementById("lecture-score-table")
.querySelectorAll("tr")
.forEach((row) => {
const lectureId = row.querySelector(".lectures").value;
const lecture = {
lecture: lectures.find((lecture) => lecture.code == lectureId),
midterm: row.querySelector(".midterm").value,
final: row.querySelector(".final").value,
};
student.lectures.push(lecture);
});
student.gpa = calculateGPA(student.lectures);
//TODO
console.log(student);
});
</script>
</body>
</html>