document.addEventListener('DOMContentLoaded', function () { const form = document.getElementById('gradesForm'); if (!form) { console.warn("⚠️ Form with ID 'gradesForm' not found."); return; } const isScoreInRange = function (value) { const num = Number(value); return Number.isFinite(num) && num >= 0 && num <= 100; }; const toggleCommentCheckbox = function (wrapper) { if (!wrapper) return; const textarea = wrapper.querySelector('textarea'); const label = wrapper.querySelector('label.missing-check'); if (!textarea || !label) return; const empty = textarea.value.trim() === ''; label.classList.toggle('d-none', !empty); if (!empty) { const checkbox = label.querySelector('input[type="checkbox"]'); if (checkbox) checkbox.checked = false; } }; form.querySelectorAll('.comment-check').forEach(function (wrapper) { const textarea = wrapper.querySelector('textarea'); if (!textarea) return; textarea.addEventListener('input', function () { toggleCommentCheckbox(wrapper); }); toggleCommentCheckbox(wrapper); }); form.addEventListener('submit', function (event) { const submitter = event.submitter; if (!submitter || submitter.id !== 'submitScoresLockBtn') { return; } const missingEntries = []; const invalidEntries = []; form.querySelectorAll('#myTable tbody tr').forEach(function (row) { let studentName = row.getAttribute('data-student-name') || ''; if (!studentName) { const cells = row.querySelectorAll('td'); const first = cells[0] ? cells[0].textContent.trim() : ''; const last = cells[1] ? cells[1].textContent.trim() : ''; studentName = (first || last) ? (first + ' ' + last).trim() : 'Student'; } const rowMissingSet = new Set(); const rowInvalid = []; const rawMissingDetails = row.getAttribute('data-missing-details') || '[]'; let missingDetails = []; try { missingDetails = JSON.parse(rawMissingDetails) || []; } catch (_) { missingDetails = []; } const commentLabels = new Set(['PTAP Comment', 'Midterm Comment', 'Final Comment']); missingDetails.forEach(function (label) { if (!commentLabels.has(label)) { rowMissingSet.add(label); } }); row.querySelectorAll('[data-score-check="1"]').forEach(function (cell) { const label = cell.getAttribute('data-field-label') || 'Score'; const value = cell.getAttribute('data-field-value') || ''; if (value !== '' && value !== null && !isScoreInRange(value)) { rowInvalid.push(label); } }); row.querySelectorAll('.comment-check').forEach(function (wrapper) { const label = wrapper.getAttribute('data-field-label') || 'Comment'; const textarea = wrapper.querySelector('textarea'); const checkbox = wrapper.querySelector('input.missing-comment-checkbox'); const value = textarea ? textarea.value.trim() : ''; if (value === '' && (!checkbox || !checkbox.checked)) { rowMissingSet.add(label); } }); const rowMissing = Array.from(rowMissingSet); if (rowMissing.length) { missingEntries.push(studentName + ': ' + rowMissing.join(', ')); } if (rowInvalid.length) { invalidEntries.push(studentName + ': ' + rowInvalid.join(', ')); } }); if (invalidEntries.length || missingEntries.length) { event.preventDefault(); const lines = []; if (invalidEntries.length) { lines.push('Scores must be between 0 and 100 for:'); lines.push('- ' + invalidEntries.join('\n- ')); } if (missingEntries.length) { lines.push('Missing entries (fill or check "Missing ok"):'); lines.push('- ' + missingEntries.join('\n- ')); } const warningBox = document.getElementById('missingWarning'); const warningBody = warningBox ? warningBox.querySelector('.missing-warning-body') : null; if (warningBox && warningBody) { warningBody.textContent = lines.join('\n'); warningBox.classList.remove('d-none'); warningBox.scrollIntoView({ behavior: 'smooth', block: 'center' }); } else { alert(lines.join('\n')); } } }); });