UBC GPA Calculator š Results š Course Breakdown Course Credits Grade Points No courses added yet
š¤ Export & Share
š PDF
š CSV
š Copy
š¬ WhatsApp
Disclaimer: This calculator is for guidance only. Verify GPA results with UBC’s official academic policies. Grade point values used: A+ (4.33), A (4.00), A- (3.67), B+ (3.33), B (3.00), B- (2.67), C+ (2.33), C (2.00), C- (1.67), D (1.00), F (0.00).
`);
printWindow.document.close();
printWindow.print();
}function exportToCSV() {
const courses = [];
document.querySelectorAll('.course-entry').forEach(courseEntry => {
const name = courseEntry.querySelector('input[id$="-name"]').value;
const credits = courseEntry.querySelector('input[id$="-credits"]').value;
const grade = courseEntry.querySelector('select[id$="-grade"]').value;
if (name && credits && grade) {
const points = (parseFloat(credits) * gradePoints[grade]).toFixed(2);
courses.push([name, credits, grade, gradePoints[grade], points]);
}
});if (courses.length === 0) {
alert('No courses to export. Please add some courses first.');
return;
}let csvContent = 'Course Name,Credits,Grade,Grade Points,Total Points\n';
courses.forEach(course => {
csvContent += course.map(field => `"${field}"`).join(',') + '\n';
});// Add summary
const termGPA = document.getElementById('currentGPA').textContent;
const cumulativeGPA = document.getElementById('cumulativeGPA').textContent;
const totalCredits = document.getElementById('totalCredits').textContent;
csvContent += '\nSummary\n';
csvContent += `Term GPA,${termGPA}\n`;
csvContent += `Cumulative GPA,${cumulativeGPA}\n`;
csvContent += `Total Credits,${totalCredits}\n`;const blob = new Blob([csvContent], { type: 'text/csv' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `UBC_GPA_Results_${new Date().toISOString().split('T')[0]}.csv`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}function copyResults() {
const results = generateResultsText(true);
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(results).then(() => {
showNotification('Results copied to clipboard!', 'success');
}).catch(() => {
fallbackCopyTextToClipboard(results);
});
} else {
fallbackCopyTextToClipboard(results);
}
}function fallbackCopyTextToClipboard(text) {
const textArea = document.createElement("textarea");
textArea.value = text;
textArea.style.position = "fixed";
textArea.style.left = "-999999px";
textArea.style.top = "-999999px";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
document.execCommand('copy');
showNotification('Results copied to clipboard!', 'success');
} catch (err) {
showNotification('Failed to copy results. Please try again.', 'error');
}
document.body.removeChild(textArea);
}function shareWhatsApp() {
const results = generateResultsText(true);
const encodedResults = encodeURIComponent(results);
const whatsappURL = `https://wa.me/?text=${encodedResults}`;
window.open(whatsappURL, '_blank');
}function generateResultsText(plainText = false) {
const termGPA = document.getElementById('currentGPA').textContent;
const cumulativeGPA = document.getElementById('cumulativeGPA').textContent;
const totalCredits = document.getElementById('totalCredits').textContent;
let text = plainText ?
`š UBC GPA Calculator Results\n` +
`Generated: ${new Date().toLocaleDateString()}\n\n` +
`š SUMMARY\n` +
`Term GPA: ${termGPA}\n` +
`Cumulative GPA: ${cumulativeGPA}\n` +
`Total Credits: ${totalCredits}\n\n` +
`š COURSE BREAKDOWN\n`
:
`
š GPA Summary Term GPA: ${termGPA}
Cumulative GPA: ${cumulativeGPA}
Total Credits: ${totalCredits}
š Course Breakdown Course Credits Grade Points `;// Add courses
const courseRows = document.querySelectorAll('#breakdownBody tr');
courseRows.forEach(row => {
const cells = row.querySelectorAll('td');
if (cells.length === 4 && cells[0].textContent !== 'No courses added yet') {
if (plainText) {
text += `${cells[0].textContent} | ${cells[1].textContent} credits | ${cells[2].textContent} | ${cells[3].textContent} points\n`;
} else {
text += `${cells[0].textContent} ${cells[1].textContent} ${cells[2].textContent} ${cells[3].textContent} `;
}
}
});if (plainText) {
text += `\nā ļø Disclaimer: Results are for guidance only. Verify with UBC's official policies.`;
} else {
text += `
Disclaimer: This calculator is for guidance only. Verify GPA results with UBC's official academic policies.
`;
}return text;
}function showNotification(message, type = 'info') {
const notification = document.createElement('div');
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
padding: 12px 20px;
border-radius: 6px;
color: white;
font-weight: 500;
z-index: 9999;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
transition: all 0.3s ease;
background-color: ${type === 'success' ? 'var(--success-color)' :
type === 'error' ? 'var(--danger-color)' :
'var(--primary-color)'};
`;
notification.textContent = message;
document.body.appendChild(notification);setTimeout(() => {
notification.style.opacity = '0';
notification.style.transform = 'translateX(100%)';
setTimeout(() => document.body.removeChild(notification), 300);
}, 3000);
}// Add ARIA live region for screen readers
const liveRegion = document.createElement('div');
liveRegion.setAttribute('aria-live', 'polite');
liveRegion.setAttribute('aria-atomic', 'true');
liveRegion.style.position = 'absolute';
liveRegion.style.left = '-10000px';
liveRegion.style.width = '1px';
liveRegion.style.height = '1px';
liveRegion.style.overflow = 'hidden';
document.body.appendChild(liveRegion);// Update live region when GPA changes
function updateLiveRegion(gpa) {
liveRegion.textContent = `GPA updated to ${gpa}`;
}// Enhanced accessibility: Update live region on calculation
const originalCalculateGPA = calculateGPA;
calculateGPA = function() {
originalCalculateGPA();
const currentGPA = document.getElementById('currentGPA').textContent;
if (currentGPA !== '0.00') {
updateLiveRegion(currentGPA);
}
};