A custom Open edX XBlock for creating interactive HTML/CSS/JS content with learner interaction tracking and auto-grading.
This XBlock allows course authors to define custom HTML, CSS, and JavaScript content and automatically captures learner interactions in JSON format for grading, analytics, or state restoration.
- Custom HTML/CSS/JS Content: Authors define their own HTML, CSS, and JavaScript content in the Studio editor
- Learner Interaction Tracking: Captures learner interactions via the
submitInteraction(data)API - Auto-Grading: Optional automatic grading — either via author JavaScript or server-side answer matching
- Completion Tracking: Emits completion events when learners submit an interaction
- Feedback Display: Configurable correct/incorrect feedback with custom messages
- Previous Response: Optionally shows learners their previous response on return
- Test Grading: Studio includes a "Test Grading" panel to verify grading config before publishing
- Debug Mode: Staff-only debug panel showing block state
- Masquerade Support: Staff can view individual student state via Open edX's "View as Specific Learner"
- Python 3.11+
- Django 4.2 or 5.2
- Open edX (Redwood or later)
Add to your OPENEDX_EXTRA_PIP_REQUIREMENTS:
git+https://github.com/blend-ed/interactive-html-xblock.git@main
Add interactive_js_block to your course's Advanced Module List:
Settings → Advanced Settings → Advanced Module List
Add the InteractiveJSBlock component to your course
Click "Edit" to open the Studio editor
Configure the following:
- HTML Content: The structure of your interactive element
- CSS Styles: Styling for your content
- JavaScript Code: Interactivity logic using
submitInteraction(data) - Grading Configuration: Answer matching mode, correct answer(s), and feedback messages
Use the
submitInteraction(data)function in your JavaScript to capture learner interactions:function submitAnswer(answer) { submitInteraction({ answer: answer, correct: answer === "Paris", timeSpent: Math.round((Date.now() - startTime) / 1000) }); }
Use the Test Grading panel in Studio to verify your grading config works before publishing.
Learners see the rendered HTML content with the author's CSS and JavaScript applied. The XBlock automatically provides the submitInteraction() function for capturing interactions.
- Display Name: The title shown to learners
- Weight: Points value for grading
- Enable Debug Mode: Show debug panel (staff only)
- Auto Grade Enabled: Enable automatic grading
- Show Feedback to Learners: Show correct/incorrect feedback after submission
- Show Previous Response: Show learners their previous response on return
- Grading Configuration: Answer matching mode (None / Single Answer / Multiple Fields), correct answer value(s), and feedback messages
There are two ways to grade interactions:
1. Author JavaScript provides correctness directly (recommended for most cases):
Include a correct boolean in the data passed to submitInteraction():
submitInteraction({
answer: "Paris",
correct: true,
timeSpent: 45
});The XBlock uses this directly — no server-side config needed. If you've set feedback messages in Grading Configuration, they'll be shown automatically.
2. Server-side answer matching:
Set "Auto Grade Enabled" to True and configure the Grading Configuration in Studio:
- Single Answer: Set the correct answer value. The server compares case-insensitively.
- Multiple Fields: Add field name / expected value pairs. Partial credit is awarded proportionally.
Configure feedback messages (Correct Feedback / Incorrect Feedback) to show custom responses.
Staff can view individual student state using the platform's built-in masquerade feature ("View as Specific Learner"). This works because the XBlock sets show_in_read_only_mode = True. Bulk data exports are available through the Open edX instructor dashboard.
pip install -e . # development install
make requirements # full dev environmenttox -e py312-django52 # Django 5.2
tox -e py312-django42 # Django 4.2
pytest tests/test_interactive_js_block.py # specific file
pytest tests/test_interactive_js_block.py::TestInteractiveJSBlock::test_method_name # single testtox -e quality # pylint, pycodestyle, pydocstyle, isortInstall in development mode:
cd interactive-html-xblock pip install -e .
Add to Tutor mounts:
tutor mounts add /path/to/interactive-html-xblock
Create a Tutor plugin (
touch $(tutor plugins printroot)/mount_interactive_html_xblock.py):from tutor import hooks hooks.Filters.MOUNTED_DIRECTORIES.add_item(("openedx", "interactive_html_xblock"))
Enable and build:
tutor plugins enable mount_interactive_html_xblock tutor images build openedx-dev tutor dev start -d
This is the default content when you add a new block:
<div class="quiz">
<h3>Sample Quiz</h3>
<p>What is the capital of France?</p>
<div class="options">
<button onclick="submitAnswer('Paris')">Paris</button>
<button onclick="submitAnswer('London')">London</button>
<button onclick="submitAnswer('Berlin')">Berlin</button>
</div>
</div>var startTime = Date.now();
function submitAnswer(answer) {
submitInteraction({
answer: answer,
correct: answer === "Paris",
timeSpent: Math.round((Date.now() - startTime) / 1000)
});
}Copyright © 2026 Blend-ed.
Interactive XBlock is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. See the LICENSE file in this repository for the full license text.
Maintainer: zameel7.