I am currently developing a cutting-edge Angular application that serves as a training platform to offer online courses to users.
Each course is essentially a set of "slides," which are HTML partials through which the user can navigate in order. These slides may contain interactive widgets such as quizzes, exercises, and more.
The main objective is for these courses to be created using only HTML/CSS without requiring any JavaScript or Angular knowledge. However, complications arise when integrating interactive elements into the courses.
For instance, a typical course slide could include:
<p>This content introduces the quiz.</p>
<div class="quiz">
<ol class="questions" data-passing-score="50">
<li>
<p>What was Abraham Lincoln's last name?</p>
<ul class="answers">
<li>Smith</li>
<li>Johnson</li>
<li class="correct">Lincoln</li>
<li>Liebowitz</li>
</ul>
</li>
<li>
<p>What were George Washington's false teeth made of?</p>
<ul class="answers">
<li>Particle board</li>
<li class="correct">Wood</li>
<li>The bones of his enemies</li>
<li>Advanced space-age polymers</li>
</ul>
</li>
</ol>
</div>
<p>This content follows the quiz.</p>
Upon loading this HTML file via $http.get()
, the application should identify the presence of a div
with the class quiz
and initiate necessary interactivity, like modifying the markup structure, managing visibility, evaluating quiz responses, and more.
Although commonly done in jQuery, we aim to implement this functionality in an Angular environment instead.
In order to achieve this, I need to tackle two key challenges:
Challenge 1: Extracting quiz data from raw HTML and converting it into a JavaScript object, like so:
var quiz = {
passing_score: 50,
questions: [
{
ask: "What was Abraham Lincoln's last name?",
answers: [
{ text: "Smith", correct: false },
{ text: "Johnson", correct: false },
{ text: "Lincoln", correct: true },
{ text: "Liebowitz", correct: false }
]
},
...
]
};
I envision parsing the loaded HTML into a DOM tree (in memory only) and utilizing jQuery or jqLite to locate and extract the required data.
Is this approach sensible, or would you recommend exploring alternative methods?
Challenge 2: Replacing div.quiz
within the loaded HTML with a quiz template, similar to the following:
<form ng-controller="QuizController as quizCtrl" ng-submit="quizCtrl.submit()">
<ol>
<li ng-repeat="question in quizCtrl.questions">
<p ng-bind-html="question.ask"></p>
<ul>
<li ng-repeat="answer in question.answers">
<label>
<input type="radio" ng-attr-name="{{ 'q' + $parent.$index }}" ng-model="question.selected_answer" ng-value="answer">
<span ng-bind-html="answer.text"></span>
</label>
</li>
</ul>
</li>
</ol>
<button type="submit">Score Quiz</button>
</form>
This div needs to be bound to QuizController.
How can I dynamically connect a specific DOM node to a particular controller, and how do I pass the quiz object (constructed in the previous step) to the controller's scope?
Is there a standardized solution within the realm of Angular, or does this methodology seem unconventional?
Any insights provided on this matter would be greatly appreciated!