I have question I was hoping to get a quick answer to.
We have an exam at the end of our course. The exam consists of 40 questions, and you have to get 32 right to pass. As it stands now one has to go check ones progress on the Progress page, to get an overview over how many correct answers ones has*. I am wondering if it is possible to fetch the same data from the Progress page in a Unit, like I have illustrated (attached img), I have just copied code from browser inspector and pasted in a separate Unit below the last question of the exam, to illustrate. It seems like a legit question by students and teachers who both find it confusing and arduous to have to go back and forth between pages to check. But I don’t have the specific code needed to do this. Does anyone have/know how I can do this? Or if I can do this? Any code?
* (version: Palm) I do need to add that the exam consists of a pool of Library Questions. That is why there is no counter of correct answers like 10/40 at the bottom of the question set. Which by it self is weird, but ok.
I don’t know of any way to do this out of the box. The data for the progress page is available via the REST endpoint (/api/course_home/progress/{course-key}), so it should be possible to do that fetch using JavaScript in an HTML block and display data (and then copy that to the bottom of each Unit).
On the coding side, it’s possible to create an XBlock Aside that will inject that data into the Unit automatically. Our documentation for this feature is really thin though. MIT has one here:
@pdpinch might be able to give a better starting point on XBlock Asides.
In Teak, it’s also possible to change the sidebar navigation to something that could potentially show inline progress information.
I managed to work with claude.ai, as I am not a programmer at all, and get some code to work directly in a RAW-Html Unit – if anyone is interested. Hope we don’t have any security issues here, but it does work as I intended, and it relates to any student/user as well.
<div class="progress-container">
<div class="progress-header">
<h3 class="progress-title">Eksamen og kursbevis</h3>
<div class="progress-score" id="score-display">0/40</div>
</div>
<div class="progress-bar">
<div class="progress-bar-fill" id="progress-fill"></div>
</div>
</div>
<script>
(function() {
// Simple progress tracker that works within Open edX constraints
function updateProgress() {
try {
var completed = 0;
var total = 40; // Default total
// Method 1: Check for completed problems in the current page
var completedProblems = document.querySelectorAll('.problems-wrapper .correct, .problem .correct, .choicegroup .correct');
if (completedProblems.length > 0) {
completed = completedProblems.length;
}
// Method 2: Check sequence navigation for progress
var sequenceButtons = document.querySelectorAll('.sequence-nav-button');
if (sequenceButtons.length > 0) {
total = sequenceButtons.length;
var completedSequences = document.querySelectorAll('.sequence-nav-button.visited, .sequence-nav-button.complete');
completed = completedSequences.length;
}
// Method 3: Look for progress in courseware
if (typeof window.courseware !== 'undefined' && window.courseware.course) {
// Try to extract from courseware object
var course = window.courseware.course;
if (course.completion) {
completed = course.completion.completed || completed;
total = course.completion.total || total;
}
}
// Method 4: Parse from existing progress elements
var progressText = document.querySelector('.progress-fraction, .sequence-nav-button .sr');
if (progressText) {
var match = progressText.textContent.match(/(\d+)\s*\/\s*(\d+)/);
if (match) {
completed = parseInt(match[1]);
total = parseInt(match[2]);
}
}
// Fallback: simulate some progress for demonstration
if (completed === 0 && total === 40) {
// You can set actual values here based on your course structure
completed = 0; // This will be updated as students progress
}
// Update the display
var percentage = total > 0 ? Math.round((completed / total) * 100) : 0;
document.getElementById('score-display').textContent = completed + '/' + total;
document.getElementById('progress-fill').style.width = percentage + '%';
} catch (error) {
console.log('Progress update error:', error);
// Keep default values if there's an error
}
}
// Update progress when page loads
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', updateProgress);
} else {
updateProgress();
}
// Update progress periodically and when user interacts with problems
setInterval(updateProgress, 5000); // Update every 5 seconds
// Listen for problem completion events
document.addEventListener('click', function() {
setTimeout(updateProgress, 1000); // Update 1 second after clicks
});
})();
</script>