Commit 30781d01 by Xavier Antoviaque

Merge pull request #71 from dragonfi/description-and-frame

Add a shared header text and number assessment questions
parents 595f6a2f 31ec9efb
......@@ -82,6 +82,7 @@ elements:
* `<title>` - Renders the title of the block.
* `<html>` - May contain arbitrary HTML to be displayed in the block.
* `<shared-header>` - A specialized HTML block, displayed together with the title as a shared header for every step in assessment mode.
* `<answer>` - Represents a free-form answer, rendered as a textarea
element.
* `<mcq>` - Multiple choice question, rendered as radio buttons.
......
......@@ -9,3 +9,4 @@ from .message import MentoringMessageBlock
from .table import MentoringTableBlock, MentoringTableColumnBlock, MentoringTableColumnHeaderBlock
from .tip import TipBlock
from .title import TitleBlock
from .header import SharedHeaderBlock
# -*- coding: utf-8 -*-
#
# Copyright (C) 2014 Harvard
#
# Authors:
# Xavier Antoviaque <xavier@antoviaque.org>
# David Gabor Bodor <david.gabor.bodor@gmail.com>
#
# This software's license gives you freedom; you can copy, convey,
# propagate, redistribute and/or modify this program under the terms of
# the GNU Affero General Public License (AGPL) as published by the Free
# Software Foundation (FSF), either version 3 of the License, or (at your
# option) any later version of the AGPL published by the FSF.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
# General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program in a file in the toplevel directory called
# "AGPLv3". If not, see <http://www.gnu.org/licenses/>.
#
import logging
from lxml import etree
from xblock.fragment import Fragment
from .light_children import LightChild, Scope, String
log = logging.getLogger(__name__)
class SharedHeaderBlock(LightChild):
"""
A shared header block shown under the title.
"""
content = String(help="HTML content of the header", scope=Scope.content, default="")
@classmethod
def init_block_from_node(cls, block, node, attr):
block.light_children = []
node.tag = 'div'
block.content = unicode(etree.tostring(node))
node.tag = 'shared-header'
return block
def student_view(self, context=None):
return Fragment(u"<script type='text/template' id='{}'>\n{}\n</script>".format(
'light-child-template',
self.content
))
def mentoring_view(self, context=None):
return self.student_view(context)
def mentoring_table_view(self, context=None):
return self.student_view(context)
......@@ -35,6 +35,7 @@ from xblock.fragment import Fragment
from .light_children import XBlockWithLightChildren
from .title import TitleBlock
from .header import SharedHeaderBlock
from .html import HTMLBlock
from .message import MentoringMessageBlock
from .utils import get_scenarios_from_path, load_resource, render_template
......@@ -97,7 +98,7 @@ class MentoringBlock(XBlockWithLightChildren):
@property
def steps(self):
return [child for child in self.get_children_objects() if
not isinstance(child, (HTMLBlock, TitleBlock, MentoringMessageBlock))]
not isinstance(child, (HTMLBlock, TitleBlock, MentoringMessageBlock, SharedHeaderBlock))]
@property
def score(self):
......@@ -112,12 +113,28 @@ class MentoringBlock(XBlockWithLightChildren):
return (score, int(round(score*100)), correct, incorrect)
def _index_steps(self):
steps = self.steps
if len(steps) == 1:
steps[0].index = ""
return
index = 1
for child in steps:
child.index = index
index += 1
def student_view(self, context):
self._index_steps()
fragment, named_children = self.get_children_fragment(
context, view_name='mentoring_view',
not_instance_of=(MentoringMessageBlock, TitleBlock)
not_instance_of=(MentoringMessageBlock, TitleBlock, SharedHeaderBlock)
)
fragment.add_content(render_template('templates/html/mentoring.html', {
'self': self,
'named_children': named_children,
......@@ -150,7 +167,7 @@ class MentoringBlock(XBlockWithLightChildren):
except KeyError as e:
return {'result': 'error', 'message': 'Missing event_type in JSON data'}
self._publish_event(event_type, data)
return self._publish_event(event_type, data)
def _publish_event(self, event_type, data):
data['user_id'] = self.scope_ids.user_id
......@@ -170,6 +187,16 @@ class MentoringBlock(XBlockWithLightChildren):
return None
@property
def header(self):
"""
Return the header child.
"""
for child in self.get_children_objects():
if isinstance(child, SharedHeaderBlock):
return child
return None
@property
def has_missing_dependency(self):
"""
Returns True if the student needs to complete another step before being able to complete
......@@ -265,7 +292,7 @@ class MentoringBlock(XBlockWithLightChildren):
completed = False
current_child = None
children = [child for child in self.get_children_objects() \
if not isinstance(child, TitleBlock)]
if not isinstance(child, (TitleBlock, SharedHeaderBlock))]
for child in children:
if child.name and child.name in submissions:
......
......@@ -95,6 +95,11 @@
height:33.33px;
}
.mentoring .assessment-question-block {
border: 5px solid #e5ebee;
padding: 20px;
}
.mentoring .assessment-checkmark {
margin-right: 10px;
}
......
<fieldset class="choices questionnaire">
<legend class="question">
<h3>QUESTION</h3>
<h3 class="question-title">QUESTION {{ self.index }}</h3>
<p>{{ self.question }}</p>
</legend>
<div class="choices-list">
......@@ -8,7 +8,7 @@
<div class="choice">
<div class="choice-result icon-2x"></div>
<label class="choice-label">
<input class="choice-selector" type="radio" name="{{ self.name }}" value="{{ choice.value }}"{% if self.student_choice == choice.value %} checked{% endif %}> {{ choice.content }}
<input class="choice-selector" type="radio" name="{{ self.name }}" value="{{ choice.value }}"{% if self.student_choice == choice.value %} checked{% endif %} />{{ choice.content }}
</label>
<div class="choice-tips"></div>
</div>
......
<fieldset class="rating questionnaire">
<legend class="question">{{ self.question }}</legend>
<legend class="question">
<h3 class="question-title">QUESTION {{ self.index }}</h3>
<p>{{ self.question }}</p>
</legend>
<div class="choices-list">
<div class="choice">
<div class="choice-result icon-2x"></div>
<label><input class="choice-selector" type="radio" name="{{ self.name }}" value="1"{% if self.student_choice == '1' %} checked{% endif %}>1</label>
<label><input class="choice-selector" type="radio" name="{{ self.name }}" value="1"{% if self.student_choice == '1' %} checked{% endif %} />1</label>
<span class="low"> - {{ self.low }}</span>
<div class="choice-tips"></div>
</div>
<div class="choice">
<div class="choice-result icon-2x"></div>
<label><input class="choice-selector" type="radio" name="{{ self.name }}" value="2"{% if self.student_choice == '2' %} checked{% endif %}>2</label>
<label><input class="choice-selector" type="radio" name="{{ self.name }}" value="2"{% if self.student_choice == '2' %} checked{% endif %} />2</label>
<div class="choice-tips"></div>
</div>
<div class="choice">
<div class="choice-result icon-2x"></div>
<label><input class="choice-selector" type="radio" name="{{ self.name }}" value="3"{% if self.student_choice == '3' %} checked{% endif %}>3</label>
<label><input class="choice-selector" type="radio" name="{{ self.name }}" value="3"{% if self.student_choice == '3' %} checked{% endif %} />3</label>
<div class="choice-tips"></div>
</div>
<div class="choice">
<div class="choice-result icon-2x"></div>
<label><input class="choice-selector" type="radio" name="{{ self.name }}" value="4"{% if self.student_choice == '4' %} checked{% endif %}>4</label>
<label><input class="choice-selector" type="radio" name="{{ self.name }}" value="4"{% if self.student_choice == '4' %} checked{% endif %} />4</label>
<div class="choice-tips"></div>
</div>
<div class="choice">
<div class="choice-result icon-2x"></div>
<label><input class="choice-selector" type="radio" name="{{ self.name }}" value="5"{% if self.student_choice == '5' %} checked{% endif %}>5</label>
<label><input class="choice-selector" type="radio" name="{{ self.name }}" value="5"{% if self.student_choice == '5' %} checked{% endif %} />5</label>
<span class="low"> - {{ self.high }}</span>
<div class="choice-tips"></div>
</div>
{% for choice in custom_choices %}
<div class="choice">
<div class="choice-result icon-2x"></div>
<label><input type="radio" name="{{ self.name }}" value="{{ choice.value }}"{% if self.student_choice == '{{ choice.value }}' %} checked{% endif %}> {{ choice.content }}</label>
<label><input type="radio" name="{{ self.name }}" value="{{ choice.value }}"{% if self.student_choice == '{{ choice.value }}' %} checked{% endif %} />{{ choice.content }}</label>
<div class="choice-tips"></div>
</div>
{% endfor %}
......
......@@ -3,38 +3,44 @@
You need to complete <a href="{{ missing_dependency_url }}">the previous step</a> before
attempting this step.
</div>
{% if self.title %}
{% if self.title or self.header %}
<div class="title">
<h2 class="main">{{ self.title.content }}</h2>
{% if self.title %} <h2 class="main">{{ self.title.content }}</h2> {% endif %}
{% if self.header %} <div class="header">{{ self.header.content|safe }}</div> {% endif %}
</div>
{% endif %}
{% for name, c in named_children %}
{{c.body_html|safe}}
{% endfor %}
{% if self.display_submit %}
<div class="grade" data-score="{{ self.score.1 }}"
data-correct_answer="{{ self.score.2 }}"
data-incorrect_answer="{{ self.score.3 }}"
data-max_attempts="{{ self.max_attempts }}"
data-num_attempts="{{ self.num_attempts }}">
</div>
<div class="submit">
{% if self.mode == 'assessment' %}
<span class="assessment-checkmark icon-2x"></span>
{% endif %}
<div class="{{self.mode}}-question-block">
{% for name, c in named_children %}
{{c.body_html|safe}}
{% endfor %}
<input type="button" class="input-main" value="Submit" disabled="disabled"></input>
{% if self.display_submit %}
{% if self.mode == 'assessment' %}
<input type="button" class="input-next" value="Next Question" disabled="disabled"></input>
<input type="button" class="input-review" value="Review grade" disabled="disabled"></input>
<input type="button" class="input-try-again" value="Try again" disabled="disabled"></input>
{% endif %}
<div class="grade" data-score="{{ self.score.1 }}"
data-correct_answer="{{ self.score.2 }}"
data-incorrect_answer="{{ self.score.3 }}"
data-max_attempts="{{ self.max_attempts }}"
data-num_attempts="{{ self.num_attempts }}">
</div>
<div class="submit">
{% if self.mode == 'assessment' %}
<span class="assessment-checkmark icon-2x"></span>
{% endif %}
<div class="attempts" data-max_attempts="{{ self.max_attempts }}" data-num_attempts="{{ self.num_attempts }}"></div>
<input type="button" class="input-main" value="Submit" disabled="disabled" />
{% if self.mode == 'assessment' %}
<input type="button" class="input-next" value="Next Question" disabled="disabled" />
<input type="button" class="input-review" value="Review grade" disabled="disabled" />
<input type="button" class="input-try-again" value="Try again" disabled="disabled" />
{% endif %}
<div class="attempts" data-max_attempts="{{ self.max_attempts }}" data-num_attempts="{{ self.num_attempts }}"></div>
</div>
{% endif %}
<div class="messages"></div>
</div>
{% endif %}
<div class="messages"></div>
</div>
<fieldset class="choices questionnaire" data-hide_results="{{self.hide_results}}">
<legend class="question">
<h3>QUESTION</h3>
<h3 class="question-title">QUESTION {{ self.index }}</h3>
<p>{{ self.question }}</p>
</legend>
<div class="choices-list">
......@@ -11,9 +10,8 @@
<label class="choice-label">
<input class="choice-selector" type="checkbox" name="{{ self.name }}"
value="{{ choice.value }}"
{% if choice.value in self.student_choices %} checked{% endif %}>
{% if choice.value in self.student_choices %} checked{% endif %} />
{{ choice.content }}
</input>
</label>
<div class="choice-tips"></div>
</div>
......
<mentoring url_name="{{ url_name }}" display_name="Nav tooltip title" weight="1" mode="assessment">
<title>Default Title</title>
<shared-header>
<p>This paragraph is shared between <strong>all</strong> questions.</p>
</shared-header>
<html>
<p>What is your goal?</p>
</html>
......
......@@ -59,7 +59,8 @@ BLOCKS_CHILDREN = [
'tip = mentoring:TipBlock',
'choice = mentoring:ChoiceBlock',
'html = mentoring:HTMLBlock',
'title = mentoring:TitleBlock'
'title = mentoring:TitleBlock',
'shared-header = mentoring:SharedHeaderBlock',
]
setup(
......
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