Commit 67a9c25f by Tim Krones

Add functionality for reviewing steps.

parent 9e864583
...@@ -898,13 +898,22 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes ...@@ -898,13 +898,22 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
self._steps_cache = [self.runtime.get_block(child_id) for child_id in self.steps] self._steps_cache = [self.runtime.get_block(child_id) for child_id in self.steps]
return self._steps_cache return self._steps_cache
def get_question_number(self, question_name):
question_names = [q.name for q in self.get_questions()]
return question_names.index(question_name) + 1
def answer_mapper(self, answer_status): def answer_mapper(self, answer_status):
steps = self.get_steps() steps = self.get_steps()
answer_map = [] answer_map = []
for step in steps: for step in steps:
for answer in step.student_results: for answer in step.student_results:
if answer[1]['status'] == answer_status: if answer[1]['status'] == answer_status:
answer_map.append({'id': answer[0], 'details': answer[1]}) answer_map.append({
'id': answer[0],
'details': answer[1],
'step': step.step_number,
'number': self.get_question_number(answer[0]),
})
return answer_map return answer_map
@property @property
...@@ -977,6 +986,22 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes ...@@ -977,6 +986,22 @@ class MentoringWithExplicitStepsBlock(BaseMentoringBlock, StudioContainerWithNes
'review_tips': self.review_tips 'review_tips': self.review_tips
} }
def show_extended_feedback(self):
return self.extended_feedback and self.max_attempts_reached
def feedback_dispatch(self, target_data):
if self.show_extended_feedback():
return json.dumps(target_data)
def correct_json(self):
return self.feedback_dispatch(self.score.correct)
def incorrect_json(self):
return self.feedback_dispatch(self.score.incorrect)
def partial_json(self):
return self.feedback_dispatch(self.score.partially_correct)
def get_message_content(self, message_type, or_default=False): def get_message_content(self, message_type, or_default=False):
for child_id in self.children: for child_id in self.children:
if child_isinstance(self, child_id, MentoringMessageBlock): if child_isinstance(self, child_id, MentoringMessageBlock):
......
...@@ -5,10 +5,11 @@ function MentoringWithStepsBlock(runtime, element) { ...@@ -5,10 +5,11 @@ function MentoringWithStepsBlock(runtime, element) {
); );
var activeStep = $('.mentoring', element).data('active-step'); var activeStep = $('.mentoring', element).data('active-step');
var gradeTemplate = _.template($('#xblock-review-template').html()); var gradeTemplate = _.template($('#xblock-review-template').html());
var reviewStepsTemplate = _.template($('#xblock-review-steps-template').html());
var reviewTipsTemplate = _.template($('#xblock-review-tips-template').html()); // Tips about specific questions the user got wrong var reviewTipsTemplate = _.template($('#xblock-review-tips-template').html()); // Tips about specific questions the user got wrong
var attemptsTemplate = _.template($('#xblock-attempts-template').html()); var attemptsTemplate = _.template($('#xblock-attempts-template').html());
var reviewStep, checkmark, submitDOM, nextDOM, reviewDOM, tryAgainDOM, var reviewStep, checkmark, submitDOM, nextDOM, reviewDOM, tryAgainDOM,
assessmentMessageDOM, gradeDOM, attemptsDOM, reviewTipsDOM, submitXHR; assessmentMessageDOM, gradeDOM, attemptsDOM, reviewTipsDOM, reviewLinkDOM, submitXHR;
function isLastStep() { function isLastStep() {
return (activeStep === steps.length-1); return (activeStep === steps.length-1);
...@@ -151,8 +152,24 @@ function MentoringWithStepsBlock(runtime, element) { ...@@ -151,8 +152,24 @@ function MentoringWithStepsBlock(runtime, element) {
function showReviewStep() { function showReviewStep() {
reviewStep.show(); reviewStep.show();
var data = gradeDOM.data(); var data = gradeDOM.data();
// Links for reviewing individual questions (WIP)
var enableExtendedFeedback = (!someAttemptsLeft() && data.extended_feedback);
_.extend(data, {
'runDetails': function(correctness) {
if (!enableExtendedFeedback) {
return '';
}
var self = this;
return reviewStepsTemplate({'questions': self[correctness], 'correctness': correctness});
}
});
gradeDOM.html(gradeTemplate(data)); gradeDOM.html(gradeTemplate(data));
$('a.step-link', element).on('click', getStepToReview);
// Review tips // Review tips
if (someAttemptsLeft()) { if (someAttemptsLeft()) {
if (data.assessment_review_tips.length > 0) { if (data.assessment_review_tips.length > 0) {
...@@ -171,6 +188,36 @@ function MentoringWithStepsBlock(runtime, element) { ...@@ -171,6 +188,36 @@ function MentoringWithStepsBlock(runtime, element) {
tryAgainDOM.show(); tryAgainDOM.show();
} }
function getStepToReview(event) {
event.preventDefault();
var stepIndex = parseInt($(event.target).data('step')) - 1;
jumpToReview(stepIndex);
}
function jumpToReview(stepIndex) {
activeStep = stepIndex;
cleanAll();
reviewStep.hide();
showActiveStep();
if (isLastStep()) {
reviewDOM.show();
reviewDOM.removeAttr('disabled');
nextDOM.hide();
nextDOM.attr('disabled', 'disabled');
} else {
nextDOM.show();
nextDOM.removeAttr('disabled');
}
// ...
tryAgainDOM.hide();
submitDOM.show();
submitDOM.attr('disabled', 'disabled');
reviewLinkDOM.show();
// ...
}
function showAttempts() { function showAttempts() {
var data = attemptsDOM.data(); var data = attemptsDOM.data();
if (data.max_attempts > 0) { if (data.max_attempts > 0) {
...@@ -224,6 +271,13 @@ function MentoringWithStepsBlock(runtime, element) { ...@@ -224,6 +271,13 @@ function MentoringWithStepsBlock(runtime, element) {
if (!someAttemptsLeft()) { if (!someAttemptsLeft()) {
tryAgainDOM.attr("disabled", "disabled"); tryAgainDOM.attr("disabled", "disabled");
} }
nextDOM.off();
nextDOM.on('click', reviewNextStep);
reviewLinkDOM.hide();
}
function reviewNextStep() {
jumpToReview(activeStep+1);
} }
function handleTryAgain(result) { function handleTryAgain(result) {
...@@ -233,6 +287,8 @@ function MentoringWithStepsBlock(runtime, element) { ...@@ -233,6 +287,8 @@ function MentoringWithStepsBlock(runtime, element) {
tryAgainDOM.hide(); tryAgainDOM.hide();
submitDOM.show(); submitDOM.show();
if (! isLastStep()) { if (! isLastStep()) {
nextDOM.off();
nextDOM.on('click', updateDisplay);
nextDOM.show(); nextDOM.show();
reviewDOM.hide(); reviewDOM.hide();
} }
...@@ -257,7 +313,11 @@ function MentoringWithStepsBlock(runtime, element) { ...@@ -257,7 +313,11 @@ function MentoringWithStepsBlock(runtime, element) {
submitDOM.show(); submitDOM.show();
nextDOM = $(element).find('.submit .input-next'); nextDOM = $(element).find('.submit .input-next');
if (atReviewStep()) {
nextDOM.on('click', reviewNextStep);
} else {
nextDOM.on('click', updateDisplay); nextDOM.on('click', updateDisplay);
}
nextDOM.show(); nextDOM.show();
reviewDOM = $(element).find('.submit .input-review'); reviewDOM = $(element).find('.submit .input-review');
...@@ -271,6 +331,9 @@ function MentoringWithStepsBlock(runtime, element) { ...@@ -271,6 +331,9 @@ function MentoringWithStepsBlock(runtime, element) {
attemptsDOM = $('.attempts', element); attemptsDOM = $('.attempts', element);
reviewTipsDOM = $('.assessment-review-tips', element); reviewTipsDOM = $('.assessment-review-tips', element);
reviewLinkDOM = $(element).find('.review-link');
reviewLinkDOM.on('click', showGrade);
var options = { var options = {
onChange: onChange onChange: onChange
}; };
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
), {number_correct: correct_answer}, {interpolate: /\{(.+?)\}/g}) ), {number_correct: correct_answer}, {interpolate: /\{(.+?)\}/g})
%> %>
</p> </p>
<%= runDetails('correct') %>
</div> </div>
<div class="clear"></div> <div class="clear"></div>
<span class="assessment-checkmark icon-2x checkmark-partially-correct icon-ok fa fa-check"></span> <span class="assessment-checkmark icon-2x checkmark-partially-correct icon-ok fa fa-check"></span>
...@@ -29,6 +30,7 @@ ...@@ -29,6 +30,7 @@
), {number_partially_correct: partially_correct_answer}, {interpolate: /\{(.+?)\}/g}) ), {number_partially_correct: partially_correct_answer}, {interpolate: /\{(.+?)\}/g})
%> %>
</p> </p>
<%= runDetails('partial') %>
</div> </div>
<div class="clear"></div> <div class="clear"></div>
<span class="assessment-checkmark icon-2x checkmark-incorrect icon-exclamation fa fa-exclamation"></span> <span class="assessment-checkmark icon-2x checkmark-incorrect icon-exclamation fa fa-exclamation"></span>
...@@ -42,6 +44,7 @@ ...@@ -42,6 +44,7 @@
), {number_incorrect: incorrect_answer}, {interpolate: /\{(.+?)\}/g}) ), {number_incorrect: incorrect_answer}, {interpolate: /\{(.+?)\}/g})
%> %>
</p> </p>
<%= runDetails('incorrect') %>
</div> </div>
<div class="clear"></div> <div class="clear"></div>
<hr/> <hr/>
...@@ -49,11 +52,11 @@ ...@@ -49,11 +52,11 @@
</script> </script>
<!-- Template for extended feedback: Show extended feedback details when all attempts are used up. --> <!-- Template for extended feedback: Show extended feedback details when all attempts are used up. -->
<script type="text/template" id="xblock-review-questions-template"> <script type="text/template" id="xblock-review-steps-template">
<% var q, last_question; %> <% var q, last_question; %>
<ul class="review-list <%= label %>-list"> <ul class="review-list <%= correctness %>-list">
<% for (var question in questions) {{ q = questions[question]; last_question = question == questions.length - 1; %> <% for (var question in questions) {{ q = questions[question]; last_question = question == questions.length - 1; %>
<li><a href="#" class="question-link" data-step="<%= q.number %>"><%= _.template(gettext("Question {number}"), {number: q.number}, {interpolate: /\{(.+?)\}/g}) %></a></li> <li><a href="#" class="step-link" data-step="<%= q.step %>"><%= _.template(gettext("Question {number}"), {number: q.number}, {interpolate: /\{(.+?)\}/g}) %></a></li>
<% }} %> <% }} %>
</ul> </ul>
</script> </script>
......
...@@ -21,7 +21,11 @@ ...@@ -21,7 +21,11 @@
data-correct_answer="{{ self.score.correct|length }}" data-correct_answer="{{ self.score.correct|length }}"
data-incorrect_answer="{{ self.score.incorrect|length }}" data-incorrect_answer="{{ self.score.incorrect|length }}"
data-partially_correct_answer="{{ self.score.partially_correct|length }}" data-partially_correct_answer="{{ self.score.partially_correct|length }}"
data-assessment_review_tips="{{ self.review_tips_json }}"> data-assessment_review_tips="{{ self.review_tips_json }}"
data-extended_feedback="{{ self.extended_feedback }}"
data-correct="{{ self.correct_json }}"
data-incorrect="{{ self.incorrect_json }}"
data-partial="{{ self.partial_json }}">
</div> </div>
<div class="submit"> <div class="submit">
...@@ -41,4 +45,6 @@ ...@@ -41,4 +45,6 @@
</div> </div>
<div class="review-link"><a href="#">Review final grade</a></div>
</div> </div>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment