Commit 4788bc70 by Braden MacDonald

Fix major bugs with the JavaScript that only occurred in Studio

1. MRQBlock initialization function had an unused parameter that Studio's runtime crashed on
2. The result of an assessment's JS runtime.children() call was different if the first child was an HTMLModule compared to an html_demo XBlock. This broke assessments. We now properly filter the result of .children() to only use actual question "steps"
parent 297d77d5
......@@ -152,7 +152,7 @@ class AnswerBlock(AnswerMixin, StepMixin, StudioEditableXBlockMixin, XBlock):
return student_input
def mentoring_view(self, context=None):
def fallback_view(self, view_name, context=None):
context = context or {}
context['self'] = self
html = loader.render_template('templates/html/answer_editable.html', context)
......
......@@ -141,7 +141,7 @@ function RatingBlock(runtime, element) {
return MCQBlock(runtime, element);
}
function MRQBlock(runtime, element, mentoring) {
function MRQBlock(runtime, element) {
return {
mode: null,
mentoring: null,
......
......@@ -135,6 +135,15 @@ class QuestionnaireAbstractBlock(StudioEditableXBlockMixin, StudioContainerXBloc
def mentoring_view(self, context=None):
return self.student_view(context)
def assessment_step_view(self, context=None):
"""
assessment_step_view is the same as mentoring_view, except its DIV will have a different
class (.xblock-v1-assessment_step_view) that we use for assessments to hide all the
steps with CSS and to detect which children of mentoring are "Steps" and which are just
decorative elements/instructions.
"""
return self.mentoring_view(context)
@property
def custom_choices(self):
custom_choices = []
......
......@@ -188,20 +188,20 @@ class MentoringBlock(XBlock, StepParentMixin, StudioEditableXBlockMixin, StudioC
for child_id in self.children:
child = self.runtime.get_block(child_id)
if isinstance(child, MentoringMessageBlock):
pass # TODO
pass
else:
try:
if self.is_assessment and isinstance(child, StepMixin):
child_fragment = child.render('assessment_step_view', context)
else:
child_fragment = child.render('mentoring_view', context)
except NoSuchViewError:
if child.scope_ids.block_type == 'html':
if getattr(self.runtime, 'is_author_mode', False):
if child.scope_ids.block_type == 'html' and getattr(self.runtime, 'is_author_mode', False):
# html block doesn't support mentoring_view, and if we use student_view Studio will wrap
# it in HTML that we don't want in the preview. So just render its HTML directly:
child_fragment = Fragment(child.data)
else:
child_fragment = child.render('student_view', context)
else:
raise # This type of child is not supported.
fragment.add_frag_resources(child_fragment)
child_content += child_fragment.content
......
......@@ -105,6 +105,11 @@
padding: 20px;
}
.mentoring .assessment-question-block > .xblock-v1-assessment_step_view,
.mentoring .assessment-question-block > .xblock-assessment_step_view {
display: none; /* Each "step" (question) is hidden at first, and shown one at a time by JavaScript */
}
.mentoring .assessment-checkmark {
margin-right: 10px;
}
......
......@@ -2,6 +2,7 @@ function MentoringBlock(runtime, element) {
var attemptsTemplate = _.template($('#xblock-attempts-template').html());
var data = $('.mentoring', element).data();
var children = runtime.children(element);
var steps = runtime.children(element).filter(function(c) { return c.element.className.indexOf('assessment_step_view') > -1; });
var step = data.step;
var mentoring = {
......@@ -12,8 +13,9 @@ function MentoringBlock(runtime, element) {
children: children,
initChildren: initChildren,
getChildByName: getChildByName,
hideAllChildren: hideAllChildren,
hideAllSteps: hideAllSteps,
step: step,
steps: steps,
publish_event: publish_event
};
......@@ -88,9 +90,9 @@ function MentoringBlock(runtime, element) {
}
}
function hideAllChildren() {
for (var i=0; i < children.length; i++) {
$(children[i].element).hide();
function hideAllSteps() {
for (var i=0; i < steps.length; i++) {
$(steps[i].element).hide();
}
}
......
......@@ -16,8 +16,8 @@ function MentoringAssessmentView(runtime, element, mentoring) {
// Clear all selections
$('input[type=radio], input[type=checkbox]', element).prop('checked', false);
// hide all children
mentoring.hideAllChildren();
// hide all questions
mentoring.hideAllSteps();
$('.grade').html('');
$('.attempts').html('');
......@@ -96,11 +96,11 @@ function MentoringAssessmentView(runtime, element, mentoring) {
}
function isLastChild() {
return (active_child == mentoring.children.length-1);
return (active_child == mentoring.steps.length-1);
}
function isDone() {
return (active_child == mentoring.children.length);
return (active_child == mentoring.steps.length);
}
function displayNextChild() {
......@@ -108,7 +108,7 @@ function MentoringAssessmentView(runtime, element, mentoring) {
// find the next real child block to display. HTMLBlock are always displayed
active_child++;
var child = mentoring.children[active_child];
var child = mentoring.steps[active_child];
$(child.element).show();
mentoring.publish_event({
event_type: 'xblock.mentoring.assessment.shown',
......@@ -164,7 +164,7 @@ function MentoringAssessmentView(runtime, element, mentoring) {
function submit() {
var success = true;
var data = {};
var child = mentoring.children[active_child];
var child = mentoring.steps[active_child];
if (child && child.name !== undefined) {
data[child.name] = callIfExists(child, 'submit');
}
......@@ -178,12 +178,12 @@ function MentoringAssessmentView(runtime, element, mentoring) {
function validateXBlock() {
var is_valid = true;
var data = $('.attempts', element).data();
var children = mentoring.children;
var steps = mentoring.steps;
// if ((data.max_attempts > 0) && (data.num_attempts >= data.max_attempts)) {
// is_valid = false;
// }
var child = mentoring.children[active_child];
var child = mentoring.steps[active_child];
if (child && child.name !== undefined) {
var child_validation = callIfExists(child, 'validate');
if (_.isBoolean(child_validation)) {
......
......@@ -5,6 +5,13 @@
<p>Please answer the questions below.</p>
</html_demo>
<html_demo>
We need an XBlock with JavaScript here to test that it doesn't interfere
with the assessment, since it will show up in runtime(element).children,
but it is not a "step" element:
</html_demo>
<acid/>
<answer name="goal" question="What is your goal?" />
<mcq name="mcq_1_1" question="Do you like this MCQ?" correct_choices="yes">
......
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