Skip to content
Permalink
Browse files

"show cell answer state" option for MCQ; only show highlight when not…

… dirty

Question authors can choose not to show the correct/incorrect state on
individual choice inputs for MCQ parts. This is appropriate when the
marking is based on the entire choice matrix, as opposed to the default
where each choice adds or subtracts marks when ticked.

This also fixes #581, removing the feedback styling when a part is dirty
  • Loading branch information...
christianp committed Nov 5, 2018
1 parent 75a24d5 commit 8cf57893a06c77e895854ead41fe6a29224e2c6c
@@ -984,6 +984,7 @@ class MultipleChoicePart(Part):
warningType = 'none'
layoutType = 'all'
layoutExpression = ''
showCellAnswerState = True

def __init__(self,marks=0,prompt=''):
Part.__init__(self,marks,prompt)
@@ -1004,7 +1005,7 @@ def loadDATA(self, builder, data):
}

self.displayType = displayTypes[self.kind]
tryLoad(data,['minMarks','maxMarks','minAnswers','maxAnswers','shuffleChoices','shuffleAnswers','displayType','displayColumns','warningType'],self)
tryLoad(data,['minMarks','maxMarks','minAnswers','maxAnswers','shuffleChoices','shuffleAnswers','displayType','displayColumns','warningType','showCellAnswerState'],self)

if haskey(data,'minmarks'):
self.minMarksEnabled = True
@@ -1041,13 +1042,15 @@ def toxml(self):
part = super(MultipleChoicePart,self).toxml()
appendMany(part,['choices','answers','layout',['marking','matrix','maxmarks','minmarks','distractors','warning']])

part.attrib['showcellanswerstate'] = strcons_fix(self.showCellAnswerState)

choices = part.find('choices')
choices.attrib = {
'minimumexpected': strcons_fix(self.minAnswers),
'maximumexpected': strcons_fix(self.maxAnswers),
'displaycolumns': strcons_fix(self.displayColumns),
'shuffle': strcons_fix(self.shuffleChoices),
'displaytype': strcons(self.displayType)
'displaytype': strcons(self.displayType),
}

if isinstance(self.choices,str):
@@ -49,6 +49,7 @@ MultipleResponsePart.prototype = /** @lends Numbas.parts.MultipleResponsePart.pr
this.flipped = false;
}
//work out marks available
tryGetAttribute(settings,xml,'.','showCellAnswerState');
tryGetAttribute(settings,xml,'marking/maxmarks','enabled','maxMarksEnabled');
if(this.type=='1_n_2') {
settings.maxMarksEnabled = false;
@@ -288,41 +288,41 @@ input.jme {
border-bottom-color: #34444f;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.student-answer.answered input {
.part:not(.dirty) > .student-answer.answered input {
border: 1px solid;
border-color: hsl(204,72%,50%);
background: hsl(204,72%,95%);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}
.student-answer.answered[feedback-state='correct'] input {
.part:not(.dirty) > .student-answer.answered[feedback-state='correct'] input {
border-color: hsl(120, 50%, 50%);
background: hsl(120, 50%, 95%);
}
.student-answer.answered[feedback-state='wrong'] input {
.part:not(.dirty) > .student-answer.answered[feedback-state='wrong'] input {
border-color: hsl(0, 50%, 50%);
background: hsl(0, 50%, 95%);
}
.student-answer.answered[feedback-state='partial'] input {
.part:not(.dirty) > .student-answer.answered[feedback-state='partial'] input {
background: white;
}

.student-answer.answered .multiplechoice .checked label {
.part:not(.dirty) > .student-answer.answered .multiplechoice.show-cell-answer-state .checked label {
border-bottom: 1px solid hsl(204,72%,50%);
}
.student-answer.answered:not([feedback-state='none']) .multiplechoice .checked.correct label {
..part:not(.dirty) > student-answer.answered:not([feedback-state='none']) .multiplechoice.show-cell-answer-state .checked.correct label {
border-bottom-color: hsl(120,50%,50%);
}
.student-answer.answered:not([feedback-state='none']) .multiplechoice .checked:not(.correct) label {
..part:not(.dirty) > student-answer.answered:not([feedback-state='none']) .multiplechoice.show-cell-answer-state .checked:not(.correct) label {
border-bottom-color: hsl(0,50%,50%);
}

#everything .student-answer.answered .choices-grid td.checked {
#everything .part:not(.dirty) > .student-answer.answered .choices-grid.show-cell-answer-state td.checked {
background: hsl(204,72%,95%);
}
#everything .student-answer.answered:not([feedback-state='none']) .choices-grid td.checked.correct {
#everything .part:not(.dirty) > .student-answer.answered:not([feedback-state='none']) .choices-grid.show-cell-answer-state td.checked.correct {
background: hsl(120,50%,95%);
}
#everything .student-answer.answered:not([feedback-state='none']) .choices-grid td.checked:not(.correct) {
#everything .part:not(.dirty) > .student-answer.answered:not([feedback-state='none']) .choices-grid.show-cell-answer-state td.checked:not(.correct) {
background: hsl(0,50%,95%);
}

@@ -38,6 +38,7 @@ Numbas.queueScript('display/parts/multipleresponse',['display-base','part-displa
return obs;
}
this.layout = util.copyarray(p.layout);
this.showCellAnswerState = ko.observable(p.settings.showCellAnswerState);
switch(p.type) {
case '1_n_2':
/** Index of student's current answer choice (not necessarily submitted)
@@ -197,4 +198,4 @@ Numbas.queueScript('display/parts/multipleresponse',['display-base','part-displa
}
};
display.MultipleResponsePartDisplay = extend(display.PartDisplay,display.MultipleResponsePartDisplay,true);
});
});
@@ -4,17 +4,17 @@
<span localise-data-jme-context-description="part.mcq.choices">
<xsl:choose>
<xsl:when test="@displaytype='radiogroup'">
<ul class="multiplechoice clearfix" data-bind="reorder_list: {{order: part.shuffleAnswers}}">
<ul class="multiplechoice clearfix" data-bind="reorder_list: {{order: part.shuffleAnswers}}, css: {{'show-cell-answer-state': showCellAnswerState}}">
<xsl:apply-templates select="choice" mode="radiogroup"/>
</ul>
</xsl:when>
<xsl:when test="@displaytype='checkbox'">
<ul class="multiplechoice clearfix" data-bind="reorder_list: {{order: part.shuffleAnswers}}">
<ul class="multiplechoice clearfix" data-bind="reorder_list: {{order: part.shuffleAnswers}}, css: {{'show-cell-answer-state': showCellAnswerState}}">
<xsl:apply-templates select="choice" mode="checkbox"/>
</ul>
</xsl:when>
<xsl:when test="@displaytype='dropdownlist'">
<select class="multiplechoice" data-bind="value: studentAnswer, disable: revealed, reorder_list: {{order: part.shuffleAnswers, leaders: 1}}">
<select class="multiplechoice" data-bind="value: studentAnswer, disable: revealed, reorder_list: {{order: part.shuffleAnswers, leaders: 1}}, css: {{'show-cell-answer-state': showCellAnswerState}}">
<option value=""></option>
<xsl:apply-templates select="choice" mode="dropdownlist"/>
</select>
@@ -128,4 +128,4 @@
<xsl:template match="distractor">
<span><xsl:apply-templates /></span>
</xsl:template>
{% endraw %}
{% endraw %}
@@ -2,7 +2,7 @@
<xsl:template match="part[@type='m_n_x']" mode="typespecific">
<xsl:variable name="displaytype" select="choices/@displaytype"/>
<form autocomplete="nope">
<table class="choices-grid" data-bind="reorder_table: {{rows: part.shuffleChoices, columns: part.shuffleAnswers, leaders: 1}}">
<table class="choices-grid" data-bind="reorder_table: {{rows: part.shuffleChoices, columns: part.shuffleAnswers, leaders: 1}}, css: {{'show-cell-answer-state': showCellAnswerState}}">
<thead localise-data-jme-context-description="part.mcq.answers">
<td/>
<xsl:for-each select="answers/answer">
@@ -93,4 +93,4 @@
</xsl:for-each>
</tr>
</xsl:template>
{% endraw %}
{% endraw %}

0 comments on commit 8cf5789

Please sign in to comment.
You can’t perform that action at this time.