Commit e87453b7 by Braden MacDonald

Merge pull request #52 from open-craft/hgse-fixes-iii

Fix two bugs (OC-839)
parents 21fc19e0 0bf1ae61
......@@ -85,6 +85,23 @@ class AnswerMixin(object):
)
return answer_data
@property
def student_input(self):
if self.name:
return self.get_model_object().student_input
return ''
@XBlock.json_handler
def answer_value(self, data, suffix=''):
""" Current value of the answer, for refresh by client """
return {'value': self.student_input}
@XBlock.json_handler
def refresh_html(self, data, suffix=''):
""" Complete HTML view of the XBlock, for refresh by client """
frag = self.mentoring_view({})
return {'html': frag.content}
def validate_field_data(self, validation, data):
"""
Validate this block's field data.
......@@ -277,12 +294,6 @@ class AnswerRecapBlock(AnswerMixin, StudioEditableXBlockMixin, XBlock):
css_path = 'public/css/answer.css'
@property
def student_input(self):
if self.name:
return self.get_model_object().student_input
return ''
def mentoring_view(self, context=None):
""" Render this XBlock within a mentoring block. """
context = context.copy() if context else {}
......@@ -308,6 +319,8 @@ class AnswerRecapBlock(AnswerMixin, StudioEditableXBlockMixin, XBlock):
fragment = Fragment(html)
fragment.add_css_url(self.runtime.local_resource_url(self, self.css_path))
fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/answer_recap.js'))
fragment.initialize_js('AnswerRecapBlock')
return fragment
def student_view(self, context=None):
......
......@@ -759,10 +759,16 @@ class MentoringBlock(XBlock, StepParentMixin, StudioEditableXBlockMixin, StudioC
"""
By default, each Sequential block in a course ("Subsection" in Studio parlance) will
display the display_name of each descendant in a tooltip above the content. We don't
want that - we only want to display the mentoring block as a whole as one item.
want that - we only want to display one title for this mentoring block as a whole.
Otherwise things like "Choice (yes) (Correct)" will appear in the tooltip.
If this block has no title set, don't display any title. Then, if this is the only block
in the unit, the unit's title will be used. (Why isn't it always just used?)
"""
return [self.display_name]
has_explicitly_set_title = self.fields['display_name'].is_set_on(self)
if has_explicitly_set_title:
return [self.display_name]
return []
@staticmethod
def workbench_scenarios():
......
......@@ -11,6 +11,11 @@ function AnswerBlock(runtime, element) {
if (completed === 'True' && this.mode === 'standard') {
checkmark.addClass('checkmark-correct icon-ok fa-check');
}
// In the LMS, the HTML of multiple units can be loaded at once,
// and the user can flip among them. If that happens, the answer in
// our HTML may be out of date.
this.refreshAnswer();
},
submit: function() {
......@@ -69,6 +74,25 @@ function AnswerBlock(runtime, element) {
}
}
return true;
},
refreshAnswer: function() {
$.ajax({
type: 'POST',
url: runtime.handlerUrl(element, 'answer_value'),
data: '{}',
dataType: 'json',
success: function(data) {
// Update the answer to the latest, unless the user has made an edit
var newAnswer = data.value;
var $textarea = $(':input', element);
var currentAnswer = $textarea.val();
var origAnswer = $('.orig-student-answer', element).text();
if (currentAnswer == origAnswer && currentAnswer != newAnswer) {
$textarea.val(newAnswer);
}
},
});
}
};
}
function AnswerRecapBlock(runtime, element) {
return {
init: function(options) {
// In the LMS, the HTML of multiple units can be loaded at once,
// and the user can flip among them. If that happens, the answer in
// our HTML may be out of date.
this.refreshAnswer();
},
refreshAnswer: function() {
$.ajax({
type: 'POST',
url: runtime.handlerUrl(element, 'refresh_html'),
data: '{}',
dataType: 'json',
success: function(data) {
$(element).html(data.html);
}
});
}
};
}
......@@ -5,5 +5,6 @@
class="answer editable" cols="50" rows="10" name="input"
data-min_characters="{{ self.min_characters }}"
>{{ self.student_input }}</textarea>
<div style="display: none;" class="orig-student-answer">{{ self.student_input }}</div> <!-- To detect edits -->
<span class="answer-checkmark fa icon-2x"></span>
</div>
{% load i18n %}
<div class="xblock-answer" data-completed="{{ student_input|yesno:"true,false" }}">
<div class="xblock-answer">
{% if not hide_header %}<h3 class="question-title">{{ title }}</h3>{% endif %}
{% if description %}<p>{{ description|safe }}</p>{% endif %}
<blockquote class="answer read_only">
......
......@@ -6,6 +6,7 @@ from problem_builder import MentoringBlock
from problem_builder.mentoring import _default_theme_config
@ddt.ddt
class TestMentoringBlock(unittest.TestCase):
def test_sends_progress_event_when_rendered_student_view_with_display_submit_false(self):
block = MentoringBlock(MagicMock(), DictFieldData({
......@@ -31,6 +32,21 @@ class TestMentoringBlock(unittest.TestCase):
self.assertFalse(patched_runtime.publish.called)
@ddt.data(True, False)
def test_get_content_titles(self, has_title_set):
"""
Test that we don't send a title to the LMS for the sequential's tooltips when no title
is set
"""
if has_title_set:
data = {'display_name': 'Custom Title'}
expected = ['Custom Title']
else:
data = {}
expected = []
block = MentoringBlock(MagicMock(), DictFieldData(data), Mock())
self.assertEqual(block.get_content_titles(), expected)
@ddt.ddt
class TestMentoringBlockTheming(unittest.TestCase):
......
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