Guide 3.12: Real Projects
Save Exam Results
Right now, if the student clicks "Take Another Exam", their previous score is lost forever. A good CBT application should keep a history of the user's past performances so they can track their progress over time. Let's use localStorage to save this data.
Saving to LocalStorage
3.12.1Update your submitExam() function. After calculating the score, we will create a history object, fetch any existing history from the browser's memory, append our new object, and save it back.
function submitExam() {
// ... existing grading logic ...
const percentage = Math.round((score / examQuestions.length) * 100);
// NEW: Save Result History
const resultRecord = {
date: new Date().toISOString(),
subject: subjectSelect.options[subjectSelect.selectedIndex].text,
score: score,
total: examQuestions.length,
percentage: percentage
};
// Retrieve existing array or start a new one
const pastResults = JSON.parse(localStorage.getItem('cbt_history')) || [];
pastResults.push(resultRecord);
// Save back to browser storage
localStorage.setItem('cbt_history', JSON.stringify(pastResults));
// Transition to result screen
showResultScreen(score, attempted, percentage);
}Displaying History on the Home Screen
3.12.2To make this useful, we should display a "Recent Scores" table on the Home Screen so the user sees it as soon as they open the app.
// Call this function when the app loads
function renderHistory() {
const historyData = JSON.parse(localStorage.getItem('cbt_history')) || [];
const historyContainer = document.getElementById('historyTableBody');
if (!historyContainer) return; // Ensure element exists in HTML
historyContainer.innerHTML = '';
// Show the 5 most recent exams
historyData.slice(-5).reverse().forEach(record => {
const row = document.createElement('tr');
// Format date nicely
const dateObj = new Date(record.date);
const dateStr = dateObj.toLocaleDateString();
row.innerHTML = `
<td>${dateStr}</td>
<td>${record.subject}</td>
<td>${record.score}/${record.total} (${record.percentage}%)</td>
`;
historyContainer.appendChild(row);
});
}