Skip to content

Instantly share code, notes, and snippets.

@HilmiZul
Created April 25, 2026 06:22
Show Gist options
  • Select an option

  • Save HilmiZul/2c2e5f2ba97aa57dd6f3bacbb31229a7 to your computer and use it in GitHub Desktop.

Select an option

Save HilmiZul/2c2e5f2ba97aa57dd6f3bacbb31229a7 to your computer and use it in GitHub Desktop.
soal tes eng
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NECTAR CEFR A1 Vocabulary & Grammar Test</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf-autotable/3.5.31/jspdf.plugin.autotable.min.js"></script>
<style>
:root {
/* Navy Blue Theme */
--primary: #000080;
--success: #27ae60;
--danger: #e74c3c;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
color: #333;
min-height: 100vh;
}
.container {
max-width: 820px;
margin: 20px auto;
background: white;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
overflow: hidden;
}
/* Updated Header for Logos */
header {
background: var(--primary);
color: white;
padding: 15px 25px;
display: flex;
justify-content: space-between;
align-items: center;
}
.header-logo {
height: 65px;
width: 65px;
object-fit: contain;
}
.header-title {
text-align: center;
flex-grow: 1;
padding: 0 15px;
}
h1 { font-size: 1.8rem; margin-bottom: 5px; }
.subtitle { font-size: 1rem; opacity: 0.9; }
.tab {
display: flex;
background: #f1f1f1;
}
.tab button {
flex: 1;
padding: 15px;
background: none;
border: none;
font-size: 1.1rem;
cursor: pointer;
}
.tab button.active {
background: white;
border-bottom: 4px solid var(--primary);
font-weight: bold;
}
.warning {
background: #fff3cd;
color: #856404;
padding: 12px;
text-align: center;
font-size: 0.95rem;
}
.form-group {
margin-bottom: 20px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: 600;
color: #444;
}
input[type="text"] {
width: 100%;
padding: 12px 16px;
font-size: 1.05rem;
border: 2px solid #ddd;
border-radius: 8px;
}
.timer {
font-size: 1.3rem;
font-weight: bold;
text-align: center;
padding: 10px;
background: #f8f9fa;
}
.progress-container {
padding: 15px 25px;
background: #f8f9fa;
}
.progress-bar {
height: 10px;
background: var(--primary);
border-radius: 5px;
transition: width 0.3s;
}
.progress-text {
text-align: center;
margin-top: 5px;
font-size: 0.9rem;
color: #666;
}
.question-container {
padding: 30px 40px;
min-height: 280px;
}
.question-number { font-size: 1.1rem; color: var(--primary); margin-bottom: 15px; }
.question { font-size: 1.22rem; margin-bottom: 25px; line-height: 1.5; }
.input-field {
width: 100%;
padding: 14px 18px;
font-size: 1.1rem;
border: 2px solid #ddd;
border-radius: 8px;
margin-top: 10px;
}
.input-field:focus { border-color: var(--primary); outline: none; }
.navigation {
padding: 20px 40px;
display: flex;
justify-content: space-between;
background: #f8f9fa;
border-top: 1px solid #eee;
}
button {
padding: 12px 28px;
font-size: 1.05rem;
border: none;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s;
}
.btn-prev { background: #95a5a6; color: white; }
.btn-next { background: var(--primary); color: white; }
.btn-submit { background: var(--success); color: white; font-weight: bold; }
.btn-pdf { background: #f39c12; color: white; padding: 12px 25px; font-weight: bold; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }
button:hover { transform: translateY(-2px); }
.results { padding: 40px; display: none; }
.score {
text-align: center;
font-size: 3rem;
font-weight: bold;
margin: 20px 0;
color: var(--primary);
}
.feedback { text-align: center; font-size: 1.3rem; margin: 15px 0; color: #2c3e50; }
.review-item {
margin: 20px 0;
padding: 15px;
background: #f8f9fa;
border-radius: 10px;
border-left: 5px solid var(--primary);
}
.correct { color: var(--success); }
.wrong { color: var(--danger); }
footer {
text-align: center;
padding: 15px;
color: #777;
font-size: 0.9rem;
}
</style>
</head>
<body>
<div class="container">
<header>
<img src="NECTAR LOGO.png" id="nectarLogo" class="header-logo" alt="Nectar Logo">
<div class="header-title">
<h1>NECTAR CEFR A1 Test</h1>
<p class="subtitle">Simple Present Tense - Grammar (100 Questions)</p>
</div>
<img src="SMPN3 LOGO.png" id="smpn3Logo" class="header-logo" alt="SMPN 3 Logo">
</header>
<div class="tab">
<button class="active" onclick="showTab(0)" id="tab0">Student Information</button>
<button onclick="showTab(1)" id="tab1">Start Test</button>
</div>
<div class="warning">
<strong>⚠️ Important Rule:</strong> Dilarang menggunakan Google Translate atau aplikasi penerjemah lainnya.<br>
No translation tools allowed. This test checks YOUR own English ability.
</div>
<div id="studentTab">
<div class="question-container">
<h2 style="margin-bottom: 25px; color: var(--primary);">Student Identity</h2>
<div class="form-group">
<label>Full Name</label>
<input type="text" id="studentName" placeholder="Enter your full name">
</div>
<div class="form-group">
<label>Class</label>
<input type="text" id="studentClass" placeholder="Example: 7A or 8B">
</div>
<div class="form-group">
<label>Nectar Student's Class (UK/US)</label>
<input type="text" id="nectarClass" placeholder="Enter your nectar's class">
</div>
<div style="text-align: center; margin-top: 30px;">
<button onclick="startTest()" style="background: var(--primary); color: white; padding: 14px 40px; font-size: 1.1rem;">
Start the Test →
</button>
</div>
</div>
</div>
<div id="testTab" style="display: none;">
<div class="timer" id="timer">Time Left: 60:00</div>
<div class="progress-container">
<div class="progress-bar" id="progressBar" style="width: 0%"></div>
<div class="progress-text">Question <span id="currentQ">1</span> of <span id="totalQ">100</span></div>
</div>
<div class="question-container" id="questionArea">
<div class="question-number">Question <span id="qNumber">1</span></div>
<div class="question" id="questionText"></div>
<input type="text" class="input-field" id="answerInput" placeholder="Type your answer here..." autocomplete="off" autocapitalize="off">
</div>
<div class="navigation">
<button class="btn-prev" id="prevBtn" onclick="prevQuestion()">← Previous</button>
<button class="btn-next" id="nextBtn" onclick="nextQuestion()">Next →</button>
<button class="btn-submit" id="submitBtn" onclick="submitTest()" style="display: none;">Submit Test</button>
</div>
</div>
<div class="results" id="resultsScreen">
<h2 style="text-align: center;">Your Test Result</h2>
<p style="text-align: center; font-size: 1.2rem; margin: 10px 0;" id="studentInfoResult"></p>
<div class="score" id="scoreDisplay">0/100</div>
<div class="feedback" id="feedbackText"></div>
<div style="text-align: center; margin: 25px 0;">
<button onclick="saveAsPDF()" class="btn-pdf">📄 Download Official PDF Report</button>
</div>
<h3 style="margin: 30px 0 15px;">Detailed Review</h3>
<div id="reviewContainer"></div>
<div style="text-align: center; margin-top: 40px;">
<button onclick="restartTest()" style="background: var(--primary); color: white; padding: 12px 35px; border: none; border-radius: 8px; font-size: 1.1rem;">
Take Test Again
</button>
</div>
</div>
</div>
<footer>
NECTAR CEFR Test • Nectar-SMP Negeri 3 Tasikmalaya All right reserved 2026
</footer>
<script>
const questions = [
{ id: 1, question: "My family __________ rice and vegetables for lunch every day.", answer: ["eats"] },
{ id: 2, question: "She __________ fried chicken with sambal almost every weekend.", answer: ["eats"] },
{ id: 3, question: "Rian __________ nasi goreng for breakfast on school days.", answer: ["eats"] },
{ id: 4, question: "We __________ fruit salad when it is very hot outside.", answer: ["eat"] },
{ id: 5, question: "My little brother __________ too many sweets and then he feels sick.", answer: ["eats"] },
{ id: 6, question: "Mrs. Lina __________ delicious rendang for special occasions.", answer: ["cooks"] },
{ id: 7, question: "They __________ bakso at the street stall near the school.", answer: ["eat"] },
{ id: 8, question: "He __________ eggs and toast every morning before school.", answer: ["eats"] },
{ id: 9, question: "I __________ spicy food because it makes me sweat.", answer: ["don't like", "dislike"] },
{ id: 10, question: "My sister __________ chocolate cake on her birthday.", answer: ["bakes", "makes"] },
{ id: 11, question: "Indonesian people often __________ teh manis in the afternoon.", answer: ["drink"] },
{ id: 12, question: "She __________ a glass of warm water every morning.", answer: ["drinks"] },
{ id: 13, question: "My brother __________ milk before he goes to bed.", answer: ["drinks"] },
{ id: 14, question: "They __________ es jeruk when the weather is hot.", answer: ["drink"] },
{ id: 15, question: "He usually __________ kopi susu at the coffee shop.", answer: ["drinks"] },
{ id: 16, question: "We __________ fresh coconut water after playing football.", answer: ["drink"] },
{ id: 17, question: "My mother __________ ginger tea when she has a cold.", answer: ["drinks"] },
{ id: 18, question: "I never __________ soft drinks because they have too much sugar.", answer: ["drink"] },
{ id: 19, question: "My father __________ black coffee without sugar every day.", answer: ["drinks"] },
{ id: 20, question: "My sister __________ strawberry smoothie on the weekend.", answer: ["drinks"] },
{ id: 21, question: "I __________ up at 5:30 every morning.", answer: ["wake"] },
{ id: 22, question: "She __________ her teeth twice a day.", answer: ["brushes"] },
{ id: 23, question: "My father __________ to work by motorcycle.", answer: ["goes"] },
{ id: 24, question: "We __________ English lessons every Tuesday and Thursday.", answer: ["have"] },
{ id: 25, question: "He __________ his homework after Maghrib prayer.", answer: ["does"] },
{ id: 26, question: "My mother __________ the house every Saturday morning.", answer: ["cleans"] },
{ id: 27, question: "They __________ football in the field near the mosque.", answer: ["play"] },
{ id: 28, question: "She usually __________ to bed at 9 o'clock.", answer: ["goes"] },
{ id: 29, question: "Rian __________ his bicycle to school every day.", answer: ["rides"] },
{ id: 30, question: "We __________ dinner together as a family.", answer: ["have", "eat"] },
{ id: 31, question: "He often __________ video games after finishing his tasks.", answer: ["plays"] },
{ id: 32, question: "My sister __________ her uniform before she goes to school.", answer: ["wears"] },
{ id: 33, question: "The students __________ the national anthem every Monday.", answer: ["sing"] },
{ id: 34, question: "I sometimes __________ a book before sleeping.", answer: ["read"] },
{ id: 35, question: "In the restaurant, she usually __________ nasi uduk and es teh.", answer: ["orders"] },
{ id: 36, question: "He __________ a plate of sate ayam and rice.", answer: ["orders"] },
{ id: 37, question: "We __________ two glasses of es campur when we go to the warung.", answer: ["order"] },
{ id: 38, question: "My friend always __________ extra spicy sambal with his food.", answer: ["asks for"] },
{ id: 39, question: "The customer __________ mie goreng without vegetables.", answer: ["orders"] },
{ id: 40, question: "They often __________ take-away food when they are busy.", answer: ["order"] },
{ id: 41, question: "We __________ English and Math every morning.", answer: ["study", "have"] },
{ id: 42, question: "She __________ hard before every exam.", answer: ["studies"] },
{ id: 43, question: "The teacher __________ new vocabulary on the board.", answer: ["writes"] },
{ id: 44, question: "My classmates often __________ questions in class.", answer: ["ask"] },
{ id: 45, question: "He __________ to school by angkot.", answer: ["goes"] },
{ id: 46, question: "My family __________ in a small house in Tasikmalaya.", answer: ["lives"] },
{ id: 47, question: "She __________ her grandmother very much.", answer: ["loves"] },
{ id: 48, question: "We often __________ our cousins during holidays.", answer: ["visit"] },
{ id: 49, question: "He always __________ his mother with the housework.", answer: ["helps"] },
{ id: 50, question: "My best friend __________ funny stories every day.", answer: ["tells"] },
{ id: 51, question: "I often __________ football with my friends after school.", answer: ["play"] },
{ id: 52, question: "She __________ books about animals in her free time.", answer: ["reads"] },
{ id: 53, question: "He usually __________ movies on weekends.", answer: ["watches"] },
{ id: 54, question: "We __________ to music while doing homework.", answer: ["listen"] },
{ id: 55, question: "My sister __________ beautiful pictures.", answer: ["draws"] },
{ id: 56, question: "We __________ in a comfortable house with a small garden.", answer: ["live"] },
{ id: 57, question: "My mother __________ the kitchen every morning.", answer: ["cleans"] },
{ id: 58, question: "He usually __________ the dishes after dinner.", answer: ["washes"] },
{ id: 59, question: "She __________ dinner for the family.", answer: ["cooks"] },
{ id: 60, question: "I often __________ my room on Saturday.", answer: ["clean"] },
{ id: 61, question: "My mother often __________ vegetables at the traditional market.", answer: ["buys"] },
{ id: 62, question: "She usually __________ a hijab to school every day.", answer: ["wears"] },
{ id: 63, question: "He __________ new shoes when his old ones are broken.", answer: ["buys"] },
{ id: 64, question: "We __________ to the mall on Sunday afternoons.", answer: ["go"] },
{ id: 65, question: "Students __________ white and blue uniforms on Monday.", answer: ["wear"] },
{ id: 66, question: "It often __________ in the afternoon during the rainy season.", answer: ["rains"] },
{ id: 67, question: "The sun usually __________ brightly in the dry season.", answer: ["shines"] },
{ id: 68, question: "We __________ hot weather because we can swim.", answer: ["like"] },
{ id: 69, question: "She __________ cool weather in the morning.", answer: ["likes"] },
{ id: 70, question: "I usually __________ healthy when I sleep enough.", answer: ["feel"] },
{ id: 71, question: "She __________ a headache when she studies too long.", answer: ["has"] },
{ id: 72, question: "We __________ sports to keep our body strong.", answer: ["do", "play"] },
{ id: 73, question: "He __________ fresh fruits and vegetables every day.", answer: ["eats"] },
{ id: 74, question: "My mother __________ her hands before cooking.", answer: ["washes"] },
{ id: 75, question: "Many people __________ near the city center.", answer: ["live"] },
{ id: 76, question: "We often __________ to the mosque for Friday prayer.", answer: ["go"] },
{ id: 77, question: "She __________ her aunt who lives in the village.", answer: ["visits"] },
{ id: 78, question: "There __________ a big park in the middle of town.", answer: ["is"] },
{ id: 79, question: "Many students __________ smartphones for learning.", answer: ["use"] },
{ id: 80, question: "He often __________ games on his tablet.", answer: ["plays"] },
{ id: 81, question: "She __________ videos to learn English pronunciation.", answer: ["watches"] },
{ id: 82, question: "We __________ messages to our friends every day.", answer: ["send"] },
{ id: 83, question: "My father __________ his laptop for work.", answer: ["uses"] },
{ id: 84, question: "We __________ trees to make the air cleaner.", answer: ["plant"] },
{ id: 85, question: "She always __________ the environment by not littering.", answer: ["protects"] },
{ id: 86, question: "He __________ plastic bottles and paper.", answer: ["recycles"] },
{ id: 87, question: "Our school __________ a garden with many flowers.", answer: ["has"] },
{ id: 88, question: "We __________ nature because it gives us fresh air.", answer: ["love"] },
{ id: 89, question: "My grandmother __________ prayers five times a day.", answer: ["performs", "does", "prays"] },
{ id: 90, question: "The shop __________ school uniforms near my house.", answer: ["sells"] },
{ id: 91, question: "The wind sometimes __________ strongly from the south.", answer: ["blows"] },
{ id: 92, question: "The doctor __________ patients in the morning.", answer: ["sees"] },
{ id: 93, question: "The library __________ many interesting books.", answer: ["has"] },
{ id: 94, question: "People should __________ rivers and lakes clean.", answer: ["keep"] },
{ id: 95, question: "My brother __________ me with my English homework.", answer: ["helps"] },
{ id: 96, question: "The bell __________ at 07:00 every day.", answer: ["rings"] },
{ id: 97, question: "She __________ her notes after the lesson.", answer: ["writes", "copies"] },
{ id: 98, question: "We __________ group projects in Science class.", answer: ["do", "make"] },
{ id: 99, question: "The cat usually __________ on the sofa.", answer: ["sleeps", "sits"] },
{ id: 100, question: "My father __________ fishing with his friends on Sundays.", answer: ["goes"] }
];
let currentQuestion = 0;
let answers = new Array(questions.length).fill("");
let timerInterval;
let timeLeft = 60 * 60;
let studentData = { name: "", class: "", nectarClass: "" };
function showTab(tabIndex) {
document.getElementById("studentTab").style.display = tabIndex === 0 ? "block" : "none";
document.getElementById("testTab").style.display = tabIndex === 1 ? "block" : "none";
document.getElementById("tab0").classList.toggle("active", tabIndex === 0);
document.getElementById("tab1").classList.toggle("active", tabIndex === 1);
}
function startTest() {
const name = document.getElementById("studentName").value.trim();
const className = document.getElementById("studentClass").value.trim();
const nClass = document.getElementById("nectarClass").value.trim();
if (!name || !className || !nClass) {
alert("Please fill in all student information fields before starting.");
return;
}
studentData = { name: name, class: className, nectarClass: nClass };
showTab(1);
startTimer();
showQuestion();
}
function startTimer() {
timerInterval = setInterval(() => {
timeLeft--;
const min = Math.floor(timeLeft / 60);
const sec = timeLeft % 60;
document.getElementById("timer").textContent = `Time Left: ${min}:${sec < 10 ? '0' : ''}${sec}`;
if (timeLeft <= 0) submitTest();
}, 1000);
}
function showQuestion() {
const q = questions[currentQuestion];
document.getElementById("qNumber").textContent = q.id;
document.getElementById("questionText").innerHTML = q.question.replace("__________", "<strong>__________</strong>");
document.getElementById("answerInput").value = answers[currentQuestion] || "";
document.getElementById("prevBtn").style.display = currentQuestion === 0 ? "none" : "block";
document.getElementById("nextBtn").style.display = currentQuestion === questions.length - 1 ? "none" : "block";
document.getElementById("submitBtn").style.display = currentQuestion === questions.length - 1 ? "block" : "none";
const progress = ((currentQuestion + 1) / questions.length) * 100;
document.getElementById("progressBar").style.width = progress + "%";
document.getElementById("currentQ").textContent = currentQuestion + 1;
document.getElementById("totalQ").textContent = questions.length;
document.getElementById("answerInput").focus();
}
function saveAnswer() {
answers[currentQuestion] = document.getElementById("answerInput").value.trim();
}
function nextQuestion() {
saveAnswer();
if (currentQuestion < questions.length - 1) {
currentQuestion++;
showQuestion();
}
}
function prevQuestion() {
saveAnswer();
if (currentQuestion > 0) {
currentQuestion--;
showQuestion();
}
}
document.getElementById("answerInput").addEventListener("keypress", function(e) {
if (e.key === "Enter") {
if (currentQuestion === questions.length - 1) {
submitTest();
} else {
nextQuestion();
}
}
});
function normalize(str) {
return str.toLowerCase().trim();
}
function checkAnswer(userAnswer, correctAnswers) {
if (!userAnswer) return false;
return correctAnswers.some(correct => normalize(correct) === normalize(userAnswer));
}
function submitTest() {
saveAnswer();
clearInterval(timerInterval);
let score = 0;
const reviewHTML = [];
questions.forEach((q, index) => {
const userAns = answers[index] || "";
const isCorrect = checkAnswer(userAns, q.answer);
if (isCorrect) score++;
reviewHTML.push(`
<div class="review-item">
<strong>Q${q.id}:</strong> ${q.question}<br><br>
<span style="color: ${isCorrect ? 'var(--success)' : 'var(--danger)'}">
Your answer: <strong>${userAns || "(empty)"}</strong>
</span><br>
${!isCorrect ? `<span class="correct">Correct answer: <strong>${q.answer[0]}</strong></span>` : ''}
</div>
`);
});
const percentage = Math.round((score / questions.length) * 100);
document.getElementById("testTab").style.display = "none";
document.getElementById("resultsScreen").style.display = "block";
document.getElementById("studentInfoResult").innerHTML =
`<strong>Name:</strong> ${studentData.name} | <strong>Class:</strong> ${studentData.class} | <strong>Nectar:</strong> ${studentData.nectarClass}`;
document.getElementById("scoreDisplay").textContent = `${score}/${questions.length} (${percentage}%)`;
// let feedback = percentage >= 85 ? "Excellent! You are A1 level 🎉" :
// percentage >= 70 ? "Good job! You're doing well for A1" :
// percentage >= 50 ? "Keep practicing Pocket Book and Present Tense." :
// "You need more practice on Simple Present Tense.";
let feedback = percentage >= 70 ? "A1 Level 🎉": "Try again next year."
document.getElementById("feedbackText").textContent = feedback;
document.getElementById("reviewContainer").innerHTML = reviewHTML.join("");
}
// --- PDF GENERATION WITH LOGOS ---
function saveAsPDF() {
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
const pageWidth = doc.internal.pageSize.width;
// 1. Draw Navy Blue Header Banner
doc.setFillColor(0, 0, 128); // Navy Blue
doc.rect(0, 0, pageWidth, 35, 'F'); // Made banner taller for logos
// 2. Add Logos to the PDF Header
try {
const nectarImg = document.getElementById('nectarLogo');
const smpn3Img = document.getElementById('smpn3Logo');
// addImage(imageElement, format, x, y, width, height)
doc.addImage(nectarImg, 'PNG', 15, 4, 22, 27); // Nectar on Left
doc.addImage(smpn3Img, 'JPEG', pageWidth - 37, 4, 23, 25); // SMPN 3 on Right
} catch (err) {
console.warn("Could not load logos into PDF. Proceeding without them.");
}
// 3. Add Document Title
doc.setTextColor(255, 255, 255);
doc.setFont("helvetica", "bold");
doc.setFontSize(18);
doc.text("NECTAR CEFR A1 Test Result", pageWidth / 2, 18, { align: "center" });
doc.setFontSize(11);
doc.setFont("helvetica", "normal");
doc.text("SMP Negeri 3 Tasikmalaya", pageWidth / 2, 26, { align: "center" });
// 4. Student Information Section
doc.setTextColor(0, 0, 0);
doc.setFontSize(11);
const today = new Date().toLocaleDateString('id-ID', { year: 'numeric', month: 'long', day: 'numeric' });
doc.text(`Name: ${studentData.name}`, 14, 48);
doc.text(`School Class: ${studentData.class}`, 14, 55);
doc.text(`Nectar Class: ${studentData.nectarClass}`, 14, 62);
doc.text(`Date: ${today}`, pageWidth - 14, 48, { align: "right" });
// 5. Highlighted Score Box
doc.setFillColor(240, 245, 250); // Light blue-grey background
doc.rect(14, 70, pageWidth - 28, 28, 'F');
const scoreText = document.getElementById("scoreDisplay").textContent;
doc.setFontSize(18);
doc.setFont("helvetica", "bold");
doc.setTextColor(0, 0, 128); // Navy
doc.text(`Final Score: ${scoreText}`, pageWidth / 2, 82, { align: "center" });
const feedback = document.getElementById("feedbackText").textContent.replace(/[^\x00-\x7F]/g, "").trim();
doc.setFontSize(11);
doc.setFont("helvetica", "italic");
doc.setTextColor(80, 80, 80);
doc.text(feedback, pageWidth / 2, 90, { align: "center" });
// 6. Build AutoTable Data
const tableBody = [];
questions.forEach((q, i) => {
const userAns = answers[i] || "-";
const isCorrect = checkAnswer(userAns, q.answer);
tableBody.push([
q.id,
q.question,
userAns,
q.answer[0],
isCorrect ? "Correct" : "Wrong"
]);
});
// 7. Generate Professional Table
doc.autoTable({
startY: 105,
head: [['No.', 'Question', 'Your Answer', 'Correct Answer', 'Result']],
body: tableBody,
theme: 'striped',
headStyles: { fillColor: [0, 0, 128], textColor: 255 }, // Navy header
styles: { fontSize: 9, cellPadding: 3 },
columnStyles: {
0: { cellWidth: 12, halign: 'center' }, // Number
1: { cellWidth: 80 }, // Question
2: { cellWidth: 35 }, // User Answer
3: { cellWidth: 35 }, // Correct Answer
4: { cellWidth: 20, halign: 'center', fontStyle: 'bold' } // Result
},
didParseCell: function(data) {
if (data.section === 'body' && data.column.index === 4) {
if (data.cell.raw === 'Correct') {
data.cell.styles.textColor = [39, 174, 96]; // Green
} else {
data.cell.styles.textColor = [231, 76, 60]; // Red
}
}
}
});
// 8. Save Document
doc.save(`NECTAR_A1_${studentData.name.replace(/ /g, "_")}.pdf`);
}
function restartTest() {
location.reload();
}
document.addEventListener('contextmenu', e => e.preventDefault());
document.addEventListener("visibilitychange", () => {
if (document.hidden) alert("⚠️ Warning: Please stay on the test page.");
});
window.onload = () => {
document.getElementById("totalQ").textContent = questions.length;
showTab(0);
};
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment