Prior Learning Assessment & Recognition (PLAR) Portfolio Guide

PLAR Portfolio Guide

1. Personal Information
2. Target Course for PLAR
3. My Prior Experience

Add relevant jobs, volunteer work, or workshops.

4. Learning Narratives

Explain how your experience meets each learning objective.

Add a Course to Challenge

My Configured Courses

Course Code Course Name # Objectives Action

Add experiences in Section 3 to link them here.

' : ''}
`; narrativesSection.appendChild(fieldset); // Populate the checklist for this new fieldset const checklist = fieldset.querySelector(`#${narrativeId}-checklist`); experiences.forEach(exp => { const item = document.createElement('div'); item.className = 'plar-checkbox-item'; item.innerHTML = ` `; checklist.appendChild(item); }); }); } // Updates all checklists when experiences are added/removed function updateNarrativeChecklists() { const checklists = document.querySelectorAll('.plar-checkbox-list'); checklists.forEach(checklist => { checklist.innerHTML = ''; if (experiences.length === 0) { checklist.innerHTML = '

Add experiences in Section 3 to link them here.

'; return; } const narrativeId = checklist.id.replace('-checklist', ''); experiences.forEach(exp => { const item = document.createElement('div'); item.className = 'plar-checkbox-item'; item.innerHTML = ` `; checklist.appendChild(item); }); }); } // --- Review & PDF Functions --- function getFullPortfolioData() { const data = {}; // 1. Personal Info data.principal = { name: document.getElementById('plar-name').value, email: document.getElementById('plar-email').value, phone: document.getElementById('plar-phone').value, }; // 2. Target Course const course = courses.find(c => c.id === targetCourseSelect.value); data.course = course || { name: 'N/A', code: 'N/A' }; // 3. Experiences data.experiences = [...experiences]; // 4. Narratives (Read from dynamic form) data.narratives = []; const narrativeFieldsets = narrativesSection.querySelectorAll('fieldset'); narrativeFieldsets.forEach(fieldset => { const id = fieldset.id; const objective = narrativesData[id].objective; const narrativeText = fieldset.querySelector(`#${id}-text`).value; const documents = fieldset.querySelector(`#${id}-docs`).value; const linkedExp = []; fieldset.querySelectorAll(`#${id}-checklist input[type="checkbox"]:checked`).forEach(checkbox => { const exp = experiences.find(e => e.id === checkbox.dataset.expId); if (exp) linkedExp.push(exp.title); }); data.narratives.push({ objective, narrativeText, documents, linkedExp }); }); return data; } function renderReviewSheet() { const data = getFullPortfolioData(); let experiencesHTML = '

No experiences added.

'; if (data.experiences.length > 0) { experiencesHTML = data.experiences.map(exp => `
${exp.title} (${exp.org}, ${exp.dates})

${exp.desc}

`).join(''); } let narrativesHTML = '

No objectives found for this course.

'; if (data.narratives.length > 0) { narrativesHTML = data.narratives.map(n => `

Objective: ${n.objective}

${n.narrativeText || 'No narrative written.'}

Supported By: ${n.linkedExp.join(', ') || 'None linked'}

Documents: ${n.documents || 'None listed'}

`).join(''); } reviewSheet.innerHTML = `

PLAR Portfolio Prep Sheet

Student Information

Name: ${data.principal.name}
Email: ${data.principal.email}
Phone: ${data.principal.phone}

Target Course

Course: ${data.course.name} (${data.course.code})

Summary of Experience

${experiencesHTML}

Learning Narratives & Evidence

${narrativesHTML}

This is a preparation sheet, NOT a formal portfolio.

`; } function downloadPDF() { const { jsPDF } = window.jspdf; const doc = new jsPDF(); const data = getFullPortfolioData(); const pageHeight = doc.internal.pageSize.height; const pageWidth = doc.internal.pageSize.width; const margin = 20; const maxWidth = pageWidth - (margin * 2); let currentY = margin; const checkPageBreak = (spaceNeeded) => { if (currentY + spaceNeeded > pageHeight - margin) { doc.addPage(); currentY = margin; } }; const addSection = (title) => { checkPageBreak(20); doc.setFontSize(16); doc.setFont(undefined, 'bold'); doc.text(title, margin, currentY); currentY += 7; doc.setLineWidth(0.5); doc.line(margin, currentY, maxWidth + margin, currentY); currentY += 10; }; const addText = (text, size = 11, style = 'normal', indent = 0) => { checkPageBreak(10); doc.setFontSize(size); doc.setFont(undefined, style); const lines = doc.splitTextToSize(text, maxWidth - indent); doc.text(lines, margin + indent, currentY); currentY += (lines.length * (size * 0.4)) + 5; }; // --- PDF Content --- doc.setFontSize(20); doc.setFont(undefined, 'bold'); doc.text("PLAR Portfolio Prep Sheet", pageWidth / 2, currentY, { align: 'center' }); currentY += 15; // Student Info addSection("Student Information"); addText(`Name: ${data.principal.name}`); addText(`Email: ${data.principal.email}`); addText(`Phone: ${data.principal.phone}`); // Target Course addSection("Target Course"); addText(`${data.course.name} (${data.course.code})`); // Experience addSection("Summary of Experience"); if (data.experiences.length > 0) { data.experiences.forEach(exp => { checkPageBreak(20); addText(`${exp.title}`, 12, 'bold'); addText(`${exp.org} (${exp.dates})`, 11, 'italic', 5); addText(exp.desc, 11, 'normal', 5); currentY += 5; }); } else { addText("No experiences added.", 11, 'italic'); } // Narratives addSection("Learning Narratives & Evidence"); if (data.narratives.length > 0) { data.narratives.forEach(n => { checkPageBreak(40); addText(`Objective: ${n.objective}`, 12, 'bold'); addText(n.narrativeText || 'No narrative written.', 11, 'italic', 5); addText(`Linked Experience: ${n.linkedExp.join(', ') || 'None'}`, 10, 'normal', 5); addText(`Supporting Documents: ${n.documents || 'None'}`, 10, 'normal', 5); currentY += 10; }); } else { addText("No objectives or narratives found.", 11, 'italic'); } // Footer checkPageBreak(20); currentY = pageHeight - margin - 10; doc.setFontSize(10); doc.setFont(undefined, 'bold'); doc.text("This is a preparation sheet, NOT a formal portfolio.", pageWidth / 2, currentY, { align: 'center' }); doc.save('plar-prep-sheet.pdf'); } // --- Tab Navigation --- function switchTab(tabIndex) { tabs.forEach((tab, index) => { tab.classList.toggle('active', index === tabIndex); contents[index].classList.toggle('active', index === tabIndex); }); currentTab = tabIndex; updateNavButtons(); } function updateNavButtons() { prevBtn.disabled = currentTab === 0; nextBtn.disabled = currentTab === tabs.length - 1; // Re-order tabs to match spec (Dashboard first, Config last) const dashboardTab = tabs[0]; const reviewTab = tabs[1]; const configTab = tabs[2]; const tabContainer = document.querySelector('.plar-tabs'); tabContainer.innerHTML = ''; tabContainer.appendChild(dashboardTab); tabContainer.appendChild(reviewTab); tabContainer.appendChild(configTab); } tabs.forEach((tab, index) => { tab.addEventListener('click', () => { // Find the *actual* index from the DOM order, not the initial 'index' const tabNode = tab.closest('.plar-tab-button'); const newIndex = Array.from(tabNode.parentNode.children).indexOf(tabNode); switchTab(newIndex); }); }); nextBtn.addEventListener('click', () => { if (currentTab < tabs.length - 1) switchTab(currentTab + 1); }); prevBtn.addEventListener('click', () => { if (currentTab > 0) switchTab(currentTab - 1); }); // --- Event Listeners --- configForm.addEventListener('submit', handleAddCourse); addExpBtn.addEventListener('click', handleAddExperience); targetCourseSelect.addEventListener('change', handleCourseSelectChange); generateBtn.addEventListener('click', () => { renderReviewSheet(); switchTab(1); // Switch to review tab }); pdfDownloadBtn.addEventListener('click', downloadPDF); // --- Initial Setup --- courses.push(sampleCourse); renderConfigTable(); populateTargetCourseDropdown(); updateNavButtons(); // This also re-orders the tabs });
Scroll to Top