Commit 77d56dc6 by Tim Krones

Add option for limiting number of attempts in assessment mode to Studio editor.

parent 7fd8c2ed
...@@ -97,10 +97,10 @@ and Drop component to a lesson, then click the `EDIT` button. ...@@ -97,10 +97,10 @@ and Drop component to a lesson, then click the `EDIT` button.
![Edit view](/doc/img/edit-view.png) ![Edit view](/doc/img/edit-view.png)
In the first step, you can set some basic properties of the component, In the first step, you can set some basic properties of the component,
such as the title, the maximum score, the problem text to render such as the title, the mode, the maximum number of attempts, the maximum score,
above the background image, the introductory feedback (shown the problem text to render above the background image, the introductory feedback
initially), and the final feedback (shown after the learner (shown initially), and the final feedback (shown after the learner successfully
successfully completes the drag and drop problem). completes the drag and drop problem).
![Drop zone edit](/doc/img/edit-view-zones.png) ![Drop zone edit](/doc/img/edit-view-zones.png)
......
doc/img/edit-view.png

32.2 KB | W: | H:

doc/img/edit-view.png

29.4 KB | W: | H:

doc/img/edit-view.png
doc/img/edit-view.png
doc/img/edit-view.png
doc/img/edit-view.png
  • 2-up
  • Swipe
  • Onion skin
...@@ -10,7 +10,7 @@ import urllib ...@@ -10,7 +10,7 @@ import urllib
from xblock.core import XBlock from xblock.core import XBlock
from xblock.exceptions import JsonHandlerError from xblock.exceptions import JsonHandlerError
from xblock.fields import Scope, String, Dict, Float, Boolean from xblock.fields import Scope, String, Dict, Float, Boolean, Integer
from xblock.fragment import Fragment from xblock.fragment import Fragment
from xblockutils.resources import ResourceLoader from xblockutils.resources import ResourceLoader
from xblockutils.settings import XBlockWithSettingsMixin, ThemableXBlockMixin from xblockutils.settings import XBlockWithSettingsMixin, ThemableXBlockMixin
...@@ -58,6 +58,16 @@ class DragAndDropBlock(XBlock, XBlockWithSettingsMixin, ThemableXBlockMixin): ...@@ -58,6 +58,16 @@ class DragAndDropBlock(XBlock, XBlockWithSettingsMixin, ThemableXBlockMixin):
default=STANDARD_MODE default=STANDARD_MODE
) )
max_attempts = Integer(
display_name=_("Maximum attempts"),
help=_(
"Defines the number of times a student can try to answer this problem. "
"If the value is not set, infinite attempts are allowed."
),
scope=Scope.settings,
default=None,
)
show_title = Boolean( show_title = Boolean(
display_name=_("Show title"), display_name=_("Show title"),
help=_("Display the title to the learner?"), help=_("Display the title to the learner?"),
...@@ -245,6 +255,7 @@ class DragAndDropBlock(XBlock, XBlockWithSettingsMixin, ThemableXBlockMixin): ...@@ -245,6 +255,7 @@ class DragAndDropBlock(XBlock, XBlockWithSettingsMixin, ThemableXBlockMixin):
def studio_submit(self, submissions, suffix=''): def studio_submit(self, submissions, suffix=''):
self.display_name = submissions['display_name'] self.display_name = submissions['display_name']
self.mode = submissions['mode'] self.mode = submissions['mode']
self.max_attempts = submissions['max_attempts']
self.show_title = submissions['show_title'] self.show_title = submissions['show_title']
self.question_text = submissions['problem_text'] self.question_text = submissions['problem_text']
self.show_question_header = submissions['show_problem_header'] self.show_question_header = submissions['show_problem_header']
......
...@@ -64,6 +64,9 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -64,6 +64,9 @@ function DragAndDropEditBlock(runtime, element, params) {
_fn.build.$el.targetImage.show(); _fn.build.$el.targetImage.show();
_fn.build.clickHandlers(); _fn.build.clickHandlers();
// Hide settings that are specific to assessment mode
_fn.build.$el.feedback.form.find('#problem-mode').trigger('change');
}, },
validate: function() { validate: function() {
...@@ -171,6 +174,9 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -171,6 +174,9 @@ function DragAndDropEditBlock(runtime, element, params) {
}); });
}); });
$fbkTab
.on('change', '#problem-mode', _fn.build.form.problem.toggleAssessmentSettings);
$zoneTab $zoneTab
.on('click', '.add-zone', function(e) { .on('click', '.add-zone', function(e) {
e.preventDefault(); e.preventDefault();
...@@ -220,6 +226,19 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -220,6 +226,19 @@ function DragAndDropEditBlock(runtime, element, params) {
.on('input', '.item-image-url', _fn.build.form.item.imageURLChanged); .on('input', '.item-image-url', _fn.build.form.item.imageURLChanged);
}, },
form: { form: {
problem: {
toggleAssessmentSettings: function(e) {
e.preventDefault();
var $modeSetting = $(e.currentTarget);
var $problemForm = $modeSetting.parent('form');
var $assessmentSettings = $problemForm.find('.setting.assessment');
if ($modeSetting.val() === 'assessment') {
$assessmentSettings.show();
} else {
$assessmentSettings.hide();
}
}
},
zone: { zone: {
totalZonesCreated: 0, // This counter is used for HTML IDs. Never decremented. totalZonesCreated: 0, // This counter is used for HTML IDs. Never decremented.
zoneObjects: [], zoneObjects: [],
...@@ -492,6 +511,7 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -492,6 +511,7 @@ function DragAndDropEditBlock(runtime, element, params) {
var data = { var data = {
'display_name': $element.find('#display-name').val(), 'display_name': $element.find('#display-name').val(),
'mode': $element.find("#problem-mode").val(), 'mode': $element.find("#problem-mode").val(),
'max_attempts': $element.find("#max-attempts").val(),
'show_title': $element.find('.show-title').is(':checked'), 'show_title': $element.find('.show-title').is(':checked'),
'weight': $element.find('#weight').val(), 'weight': $element.find('#weight').val(),
'problem_text': $element.find('#problem-text').val(), 'problem_text': $element.find('#problem-text').val(),
......
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
</select> </select>
<span class="sr">{{ help_texts.mode }}</span> <span class="sr">{{ help_texts.mode }}</span>
<label class="h3 setting assessment" for="max-attempts" title="{{ help_texts.max_attempts }}">{% trans "Maximum attempts" %}</label>
<input class="setting assessment" id="max-attempts" type="number" min="1" step="1" {% if self.max_attempts %}value="{{ self.max_attempts }}"{% endif %} />
<label class="h3" for="weight">{% trans "Maximum score" %}</label> <label class="h3" for="weight">{% trans "Maximum score" %}</label>
<input id="weight" type="number" step="0.1" value="{{ self.weight|unlocalize }}" /> <input id="weight" type="number" step="0.1" value="{{ self.weight|unlocalize }}" />
......
...@@ -99,6 +99,7 @@ class BasicTests(TestCaseMixin, unittest.TestCase): ...@@ -99,6 +99,7 @@ class BasicTests(TestCaseMixin, unittest.TestCase):
body = { body = {
'display_name': "Test Drag & Drop", 'display_name': "Test Drag & Drop",
'mode': DragAndDropBlock.ASSESSMENT_MODE, 'mode': DragAndDropBlock.ASSESSMENT_MODE,
'max_attempts': 1,
'show_title': False, 'show_title': False,
'problem_text': "Problem Drag & Drop", 'problem_text': "Problem Drag & Drop",
'show_problem_header': False, 'show_problem_header': False,
...@@ -114,6 +115,7 @@ class BasicTests(TestCaseMixin, unittest.TestCase): ...@@ -114,6 +115,7 @@ class BasicTests(TestCaseMixin, unittest.TestCase):
self.assertEqual(self.block.show_title, False) self.assertEqual(self.block.show_title, False)
self.assertEqual(self.block.mode, DragAndDropBlock.ASSESSMENT_MODE) self.assertEqual(self.block.mode, DragAndDropBlock.ASSESSMENT_MODE)
self.assertEqual(self.block.max_attempts, 1)
self.assertEqual(self.block.display_name, "Test Drag & Drop") self.assertEqual(self.block.display_name, "Test Drag & Drop")
self.assertEqual(self.block.question_text, "Problem Drag & Drop") self.assertEqual(self.block.question_text, "Problem Drag & Drop")
self.assertEqual(self.block.show_question_header, False) self.assertEqual(self.block.show_question_header, False)
......
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