Commit cd689891 by Braden MacDonald Committed by GitHub

Merge pull request #81 from edx-solutions/tim/max-attempts

Add option for limiting number of attempts in assessment mode to Studio editor
parents 3849de48 40037b19
......@@ -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?"),
......@@ -262,6 +272,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']
......
......@@ -79,6 +79,11 @@
font-size: 100%;
}
.xblock--drag-and-drop--editor .tab .nested-input {
display: block;
margin-top: 8px;
}
.xblock--drag-and-drop--editor .tab-header,
.xblock--drag-and-drop--editor .tab-content,
.xblock--drag-and-drop--editor .tab-footer {
......
......@@ -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),
$problemForm = $modeSetting.parent('form'),
$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: [],
......@@ -488,6 +507,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,15 @@
</select>
<span class="sr">{{ help_texts.mode }}</span>
<label class="h3 setting assessment" title="{{ help_texts.max_attempts }}">
{% trans "Maximum attempts" %}
<input class="nested-input max-attempts"
type="number"
min="1"
step="1"
{% if self.max_attempts %}value="{{ self.max_attempts }}"{% endif %} />
</label>
<label class="h3" for="weight">{% trans "Maximum score" %}</label>
<input id="weight" type="number" step="0.1" value="{{ self.weight|unlocalize }}" />
......
......@@ -103,6 +103,35 @@ msgid "Drag and Drop"
msgstr ""
#: drag_and_drop_v2.py
msgid "Mode"
msgstr ""
#: drag_and_drop_v2.py
msgid ""
"Standard mode: the problem provides immediate feedback each time a learner drops an item on a target zone. "
"Assessment mode: the problem provides feedback only after a learner drops all available items on target zones."
msgstr ""
#: drag_and_drop_v2.py
msgid "Standard"
msgstr ""
#: drag_and_drop_v2.py
msgid "Assessment"
msgstr ""
#: drag_and_drop_v2.py
#: templates/html/drag_and_drop_edit.html
msgid "Maximum attempts"
msgstr ""
#: drag_and_drop_v2.py
msgid ""
"Defines the number of times a student can try to answer this problem. "
"If the value is not set, infinite attempts are allowed."
msgstr ""
#: drag_and_drop_v2.py
#: templates/html/drag_and_drop_edit.html
msgid "Show title"
msgstr ""
......@@ -279,6 +308,10 @@ msgid "Problem title"
msgstr ""
#: templates/html/drag_and_drop_edit.html
msgid "Problem mode"
msgstr ""
#: templates/html/drag_and_drop_edit.html
msgid "Maximum score"
msgstr ""
......
......@@ -128,6 +128,42 @@ msgid "Drag and Drop"
msgstr "Dräg änd Dröp Ⱡ'σяєм ιρѕυм ∂σłσя ѕι#"
#: drag_and_drop_v2.py
msgid "Mode"
msgstr "Mödé Ⱡ'σяєм ι#"
#: drag_and_drop_v2.py
msgid ""
"Standard mode: the problem provides immediate feedback each time a learner drops an item on a target zone. "
"Assessment mode: the problem provides feedback only after a learner drops all available items on target zones."
msgstr ""
"Ständärd mödé: thé prößlém prövïdés ïmmédïäté féédßäçk éäçh tïmé ä léärnér dröps än ïtém ön ä tärgét zöné. "
"Àsséssmént mödé: thé prößlém prövïdés féédßäçk önlý äftér ä léärnér dröps äll äväïläßlé ïtéms ön tärgét zönés. "
"Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕмσ∂ тємρσя ιη¢ι∂ι∂υηт υт łαвσяє єт ∂σłσяє "
"мαgηα αłιqυα. υт єηιм α∂ мιηιм νєηιαм, qυιѕ ησѕтяυ∂ єχєя¢ιтαтιση υłłαм¢σ łαвσяιѕ ηιѕι υт αłιqυιρ єχ єα ¢σммσ∂σ "
"¢σηѕєqυαт. ∂υιѕ αυтє ιяυяє ∂σłσя ιη яєρяєнєη∂єяιт ιη νσłυρтαтє νєłιт єѕѕє ¢ιłłυм ∂σłσяє єυ ƒυgιαт ηυłłα ραяιαт#"
#: drag_and_drop_v2.py
msgid "Standard"
msgstr "Ständärd Ⱡ'σяєм ιρѕυм ∂#"
#: drag_and_drop_v2.py
msgid "Assessment"
msgstr "Àsséssmént Ⱡ'σяєм ιρѕυм ∂σłσ#"
#: drag_and_drop_v2.py
#: templates/html/drag_and_drop_edit.html
msgid "Maximum attempts"
msgstr "Mäxïmüm ättémpts Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
#: drag_and_drop_v2.py
msgid ""
"Defines the number of times a student can try to answer this problem. "
"If the value is not set, infinite attempts are allowed."
msgstr ""
"Défïnés thé nümßér öf tïmés ä stüdént çän trý tö änswér thïs prößlém. "
"Ìf thé välüé ïs nöt sét, ïnfïnïté ättémpts äré ällöwéd. Ⱡ'σяєм #"
#: drag_and_drop_v2.py
msgid "Show title"
msgstr "Shöw tïtlé Ⱡ'σяєм ιρѕυм ∂σłσ#"
......@@ -339,6 +375,10 @@ msgid "Problem title"
msgstr "Prößlém tïtlé Ⱡ'σяєм ιρѕυм ∂σłσя ѕι#"
#: templates/html/drag_and_drop_edit.html
msgid "Problem mode"
msgstr "Prößlém mödé Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
#: templates/html/drag_and_drop_edit.html
msgid "Show title"
msgstr "Shöw tïtlé Ⱡ'σяєм ιρѕυм ∂σłσ#"
......
......@@ -109,6 +109,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,
......@@ -124,6 +125,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