Online Automated Exam Paper Generator

Online Automated Exam Paper Generator

Exam Details

Type: ${q.type.toUpperCase()} | Topic: ${q.topic} | Marks: ${q.marks}

`; list.appendChild(item); }); } function renderPaperPreview(paper) { const previewContainer = document.getElementById('paperPreview'); const pdfContainer = document.getElementById('pdf-exam-paper'); if (!paper) { previewContainer.innerHTML = '

Click "Generate Exam Paper" to create a preview.

'; pdfContainer.innerHTML = ''; return; } const { details, sections } = paper; let totalMarks = 0; let html = `

${details.title}

${details.courseName}

Duration: ${details.duration} minutes

Instructions:

${details.instructions}

`; sections.forEach(section => { if (section.questions.length > 0) { html += `

${section.title}

`; section.questions.forEach((q, index) => { totalMarks += q.marks; html += `
${index + 1}.
${q.text}
[${q.marks}]
`; if (q.type === 'mcq' && q.options) { html += `
    `; q.options.forEach(opt => { html += `
  1. ${opt}
  2. `; }); html += `
`; } }); html += `
`; } }); previewContainer.innerHTML = html; pdfContainer.innerHTML = html; // Also render to the hidden PDF div // Update total marks in both previews const marksText = `Total Marks: ${totalMarks}`; document.getElementById('totalMarksPreview').innerHTML = marksText; const pdfMarksElem = pdfContainer.querySelector('#totalMarksPreview'); if(pdfMarksElem) pdfMarksElem.innerHTML = marksText; } // --- LOGIC & EVENT HANDLERS --- function updateTabs() { tabs.forEach(tab => tab.classList.toggle('active', parseInt(tab.dataset.tab) === currentTab)); tabPanes.forEach(pane => pane.classList.toggle('hidden', parseInt(pane.id.split('-')[1]) !== currentTab)); prevBtn.disabled = currentTab === 1; nextBtn.disabled = currentTab === totalTabs; } function goToTab(tabNumber) { if (tabNumber >= 1 && tabNumber <= totalTabs) { currentTab = tabNumber; updateTabs(); } } function addQuestion() { const text = document.getElementById('questionText').value.trim(); const type = document.getElementById('questionType').value; const topic = document.getElementById('questionTopic').value.trim(); const marks = parseInt(document.getElementById('questionMarks').value); const mcqOptionsRaw = document.getElementById('mcqOptions').value.trim(); if (!text || !topic || isNaN(marks)) { alert('Please fill all fields: Question, Topic, and Marks.'); return; } if (type === 'mcq' && !mcqOptionsRaw) { alert('Please provide comma-separated options for MCQ questions.'); return; } const newId = appData.questionBank.length > 0 ? Math.max(...appData.questionBank.map(q => q.id)) + 1 : 1; const newQuestion = { id: newId, text, type, topic, marks }; if (type === 'mcq') { newQuestion.options = mcqOptionsRaw.split(',').map(opt => opt.trim()); } appData.questionBank.push(newQuestion); renderQuestionBankList(); // Clear inputs document.getElementById('questionText').value = ''; document.getElementById('questionTopic').value = ''; document.getElementById('questionMarks').value = ''; document.getElementById('mcqOptions').value = ''; } function deleteQuestion(questionId) { appData.questionBank = appData.questionBank.filter(q => q.id !== questionId); renderQuestionBankList(); } function generatePaper() { // 1. Update details from inputs appData.examDetails.title = document.getElementById('examTitle').value; appData.examDetails.courseName = document.getElementById('courseName').value; appData.examDetails.duration = document.getElementById('examDuration').value; appData.examDetails.instructions = document.getElementById('examInstructions').value; // 2. Get requested number of questions const numMcq = parseInt(document.getElementById('generateNumMcq').value) || 0; const numShort = parseInt(document.getElementById('generateNumShort').value) || 0; const numLong = parseInt(document.getElementById('generateNumLong').value) || 0; // 3. Filter and select questions randomly const selectRandomQuestions = (type, count) => { const filtered = appData.questionBank.filter(q => q.type === type); return filtered.sort(() => 0.5 - Math.random()).slice(0, count); }; const mcqSection = { title: 'Section A: Multiple Choice Questions', questions: selectRandomQuestions('mcq', numMcq) }; const shortSection = { title: 'Section B: Short Answer Questions', questions: selectRandomQuestions('short', numShort) }; const longSection = { title: 'Section C: Essay Questions', questions: selectRandomQuestions('long', numLong) }; appData.generatedPaper = { details: appData.examDetails, sections: [mcqSection, shortSection, longSection] }; renderPaperPreview(appData.generatedPaper); document.getElementById('downloadPdfBtn').disabled = false; } function downloadPdf() { if (!appData.generatedPaper) { alert('Please generate the paper first.'); return; } const elementToCapture = document.getElementById('pdf-exam-paper'); html2canvas(elementToCapture, { scale: 2, windowWidth: elementToCapture.scrollWidth, windowHeight: elementToCapture.scrollHeight }).then(canvas => { const imgData = canvas.toDataURL('image/png'); const { jsPDF } = window.jspdf; const pdf = new jsPDF({ orientation: 'portrait', unit: 'in', format: 'letter' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const imgWidth = canvas.width / 200; // Approximate conversion from pixels to inches const imgHeight = canvas.height / 200; const ratio = imgWidth / imgHeight; let finalImgHeight = pdfHeight; let finalImgWidth = finalImgHeight * ratio; if (finalImgWidth > pdfWidth) { finalImgWidth = pdfWidth; finalImgHeight = finalImgWidth / ratio; } let heightLeft = imgHeight; let position = 0; pdf.addImage(imgData, 'PNG', 0, position, pdfWidth, imgHeight); heightLeft -= pdfHeight; while (heightLeft > 0) { position = heightLeft - imgHeight; pdf.addPage(); pdf.addImage(imgData, 'PNG', 0, position, pdfWidth, imgHeight); heightLeft -= pdfHeight; } pdf.save(`${appData.examDetails.title.replace(/\s+/g, '-')}.pdf`); }); } // --- EVENT LISTENERS --- tabs.forEach(tab => tab.addEventListener('click', (e) => goToTab(parseInt(e.currentTarget.dataset.tab)))); prevBtn.addEventListener('click', () => goToTab(currentTab - 1)); nextBtn.addEventListener('click', () => goToTab(currentTab + 1)); document.getElementById('addQuestionBtn').addEventListener('click', addQuestion); document.getElementById('generatePaperBtn').addEventListener('click', generatePaper); document.getElementById('downloadPdfBtn').addEventListener('click', downloadPdf); document.getElementById('questionBankList').addEventListener('click', (e) => { if (e.target.classList.contains('delete-question-btn')) { deleteQuestion(parseInt(e.target.dataset.questionId)); } }); document.getElementById('questionType').addEventListener('change', (e) => { document.getElementById('mcqOptionsContainer').style.display = e.target.value === 'mcq' ? 'block' : 'none'; }); // --- INITIALIZATION --- renderAll(); updateTabs(); document.getElementById('mcqOptionsContainer').style.display = 'block'; // Default view });
Scroll to Top