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.
![Edit view](/doc/img/edit-view.png)
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
above the background image, the introductory feedback (shown
initially), and the final feedback (shown after the learner
successfully completes the drag and drop problem).
such as the title, the mode, the maximum number of attempts, the maximum score,
the problem text to render above the background image, the introductory feedback
(shown initially), and the final feedback (shown after the learner successfully
completes the drag and drop problem).
![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
from xblock.core import XBlock
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 xblockutils.resources import ResourceLoader
from xblockutils.settings import XBlockWithSettingsMixin, ThemableXBlockMixin
......@@ -58,6 +58,16 @@ class DragAndDropBlock(XBlock, XBlockWithSettingsMixin, ThemableXBlockMixin):
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(
display_name=_("Show title"),
help=_("Display the title to the learner?"),
......@@ -245,6 +255,7 @@ class DragAndDropBlock(XBlock, XBlockWithSettingsMixin, ThemableXBlockMixin):
def studio_submit(self, submissions, suffix=''):
self.display_name = submissions['display_name']
self.mode = submissions['mode']
self.max_attempts = submissions['max_attempts']
self.show_title = submissions['show_title']
self.question_text = submissions['problem_text']
self.show_question_header = submissions['show_problem_header']
......
......@@ -64,6 +64,9 @@ function DragAndDropEditBlock(runtime, element, params) {
_fn.build.$el.targetImage.show();
_fn.build.clickHandlers();
// Hide settings that are specific to assessment mode
_fn.build.$el.feedback.form.find('#problem-mode').trigger('change');
},
validate: function() {
......@@ -171,6 +174,9 @@ function DragAndDropEditBlock(runtime, element, params) {
});
});
$fbkTab
.on('change', '#problem-mode', _fn.build.form.problem.toggleAssessmentSettings);
$zoneTab
.on('click', '.add-zone', function(e) {
e.preventDefault();
......@@ -220,6 +226,19 @@ function DragAndDropEditBlock(runtime, element, params) {
.on('input', '.item-image-url', _fn.build.form.item.imageURLChanged);
},
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: {
totalZonesCreated: 0, // This counter is used for HTML IDs. Never decremented.
zoneObjects: [],
......@@ -492,6 +511,7 @@ function DragAndDropEditBlock(runtime, element, params) {
var data = {
'display_name': $element.find('#display-name').val(),
'mode': $element.find("#problem-mode").val(),
'max_attempts': $element.find("#max-attempts").val(),
'show_title': $element.find('.show-title').is(':checked'),
'weight': $element.find('#weight').val(),
'problem_text': $element.find('#problem-text').val(),
......
......@@ -31,6 +31,9 @@
</select>
<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>
<input id="weight" type="number" step="0.1" value="{{ self.weight|unlocalize }}" />
......
......@@ -99,6 +99,7 @@ class BasicTests(TestCaseMixin, unittest.TestCase):
body = {
'display_name': "Test Drag & Drop",
'mode': DragAndDropBlock.ASSESSMENT_MODE,
'max_attempts': 1,
'show_title': False,
'problem_text': "Problem Drag & Drop",
'show_problem_header': False,
......@@ -114,6 +115,7 @@ class BasicTests(TestCaseMixin, unittest.TestCase):
self.assertEqual(self.block.show_title, False)
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.question_text, "Problem Drag & Drop")
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