Guide 3.7: Real Projects
Add Question Number Navigation
In a real JAMB exam, students don't just click "Next" 40 times. They have a grid of numbers on the side of the screen allowing them to instantly jump to any question. Let's build this grid.
Update HTML
3.7.1In index.html, add a new sidebar container inside the #examScreen div to hold the number grid.
<div id="examScreen" class="screen" style="display:flex; gap: 24px;">
<!-- Main Content (Question Interface) -->
<div class="main-content" style="flex: 1;">
<!-- Existing question UI goes here -->
</div>
<!-- NEW: Right Sidebar Grid -->
<div class="nav-sidebar" style="width: 250px;">
<h3>Navigation</h3>
<div class="number-grid" id="numberGrid" style="display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px;">
<!-- Numbers injected here -->
</div>
<button id="submitExamBtn" style="background: red; margin-top: 32px;">Submit Exam</button>
</div>
</div>Generate the Grid
3.7.2When the exam starts, we need to generate a button for all 40 questions. Add this function to app.js and call it from inside your startExam() function.
function generateNumberGrid() {
const grid = document.getElementById('numberGrid');
grid.innerHTML = '';
examQuestions.forEach((_, index) => {
const btn = document.createElement('button');
btn.textContent = index + 1;
btn.className = 'nav-num-btn';
btn.style.padding = '8px';
// Jump to question when clicked
btn.addEventListener('click', () => {
currentQuestionIndex = index;
renderQuestion(currentQuestionIndex);
});
grid.appendChild(btn);
});
}Highlight the Active Number
3.7.3We should highlight the current question number in the grid so the student knows where they are. Update the renderQuestion() function to handle this.
// Inside renderQuestion()
const allNavBtns = document.querySelectorAll('.nav-num-btn');
allNavBtns.forEach((btn, idx) => {
if (idx === index) {
btn.style.background = '#007bff'; // Active blue
btn.style.color = 'white';
} else {
// If they have already answered this question, color it green
if (userAnswers[idx]) {
btn.style.background = '#28a745'; // Answered green
btn.style.color = 'white';
} else {
btn.style.background = '#eee'; // Unanswered gray
btn.style.color = '#333';
}
}
});