Commit 7b054467 by Braden MacDonald

Merge pull request #37 from open-craft/show-question-header

Show/hide question header
parents 0c8911a4 564fd15e
...@@ -44,8 +44,10 @@ coverage.xml ...@@ -44,8 +44,10 @@ coverage.xml
*.mo *.mo
*.pot *.pot
# Django stuff: # Integration test output:
*.log /*.log
/tests.*.png
var/*
# Sphinx documentation # Sphinx documentation
docs/_build/ docs/_build/
...@@ -53,8 +55,6 @@ docs/_build/ ...@@ -53,8 +55,6 @@ docs/_build/
# PyBuilder # PyBuilder
target/ target/
workbench.db
# IDEs # IDEs
.idea .idea
.idea/* .idea/*
...@@ -9,7 +9,9 @@ install: ...@@ -9,7 +9,9 @@ install:
- "pip uninstall -y xblock-drag-and-drop-v2" - "pip uninstall -y xblock-drag-and-drop-v2"
- "python setup.py sdist" - "python setup.py sdist"
- "pip install dist/xblock-drag-and-drop-v2-0.1.tar.gz" - "pip install dist/xblock-drag-and-drop-v2-0.1.tar.gz"
script: pep8 drag_and_drop_v2 --max-line-length=120 && python run_tests.py script:
- pep8 drag_and_drop_v2 --max-line-length=120
- python run_tests.py
notifications: notifications:
email: false email: false
addons: addons:
......
...@@ -38,11 +38,18 @@ class DragAndDropBlock(XBlock): ...@@ -38,11 +38,18 @@ class DragAndDropBlock(XBlock):
question_text = String( question_text = String(
display_name=_("Question text"), display_name=_("Question text"),
help=_("The question text that is displayed to the user"), help=_("The question text (and/or instructions) shown to the user"),
scope=Scope.settings, scope=Scope.settings,
default="", default="",
) )
show_question_header = Boolean(
display_name=_("Show \"Question\" heading"),
help=_("Display the \"Question\" heading above the question/instructions?"),
scope=Scope.settings,
default=True,
)
weight = Float( weight = Float(
display_name=_("Weight"), display_name=_("Weight"),
help=_("This is the maximum score that the user receives when he/she successfully completes the problem"), help=_("This is the maximum score that the user receives when he/she successfully completes the problem"),
...@@ -129,8 +136,8 @@ class DragAndDropBlock(XBlock): ...@@ -129,8 +136,8 @@ class DragAndDropBlock(XBlock):
js_templates = load_resource('/templates/html/js_templates.html') js_templates = load_resource('/templates/html/js_templates.html')
help_texts = { help_texts = {
'item_background_color': self._(self.fields['item_background_color'].help), field_name: self._(field.help)
'item_text_color': self._(self.fields['item_text_color'].help) for field_name, field in self.fields.viewitems() if hasattr(field, "help")
} }
context = { context = {
'js_templates': js_templates, 'js_templates': js_templates,
...@@ -166,6 +173,7 @@ class DragAndDropBlock(XBlock): ...@@ -166,6 +173,7 @@ class DragAndDropBlock(XBlock):
self.display_name = submissions['display_name'] self.display_name = submissions['display_name']
self.show_title = submissions['show_title'] self.show_title = submissions['show_title']
self.question_text = submissions['question_text'] self.question_text = submissions['question_text']
self.show_question_header = submissions['show_question_header']
self.weight = float(submissions['weight']) self.weight = float(submissions['weight'])
self.item_background_color = submissions['item_background_color'] self.item_background_color = submissions['item_background_color']
self.item_text_color = submissions['item_text_color'] self.item_text_color = submissions['item_text_color']
...@@ -178,7 +186,7 @@ class DragAndDropBlock(XBlock): ...@@ -178,7 +186,7 @@ class DragAndDropBlock(XBlock):
@XBlock.handler @XBlock.handler
def get_data(self, request, suffix=''): def get_data(self, request, suffix=''):
data = self._get_data() data = self._get_data()
return webob.response.Response(body=json.dumps(data)) return webob.Response(body=json.dumps(data), content_type='application/json')
@XBlock.json_handler @XBlock.json_handler
def do_attempt(self, attempt, suffix=''): def do_attempt(self, attempt, suffix=''):
...@@ -285,6 +293,7 @@ class DragAndDropBlock(XBlock): ...@@ -285,6 +293,7 @@ class DragAndDropBlock(XBlock):
data['title'] = self.display_name data['title'] = self.display_name
data['show_title'] = self.show_title data['show_title'] = self.show_title
data['question_text'] = self.question_text data['question_text'] = self.question_text
data['show_question_header'] = self.show_question_header
if self.item_background_color: if self.item_background_color:
data['item_background_color'] = self.item_background_color data['item_background_color'] = self.item_background_color
......
...@@ -118,7 +118,7 @@ ...@@ -118,7 +118,7 @@
} }
.xblock--drag-and-drop .drag-builder .tab h3 { .xblock--drag-and-drop .drag-builder .tab h3 {
margin: 10px 0; margin: 20px 0 8px 0;
} }
.xblock--drag-and-drop .drag-builder .tab-header, .xblock--drag-and-drop .drag-builder .tab-header,
...@@ -180,7 +180,6 @@ ...@@ -180,7 +180,6 @@
.xblock--drag-and-drop .feedback-form textarea { .xblock--drag-and-drop .feedback-form textarea {
width: 99%; width: 99%;
height: 128px; height: 128px;
margin-bottom: 30px;
} }
.xblock--drag-and-drop .item-styles-form .item-styles-form-help { .xblock--drag-and-drop .item-styles-form .item-styles-form-help {
......
...@@ -259,6 +259,7 @@ function DragAndDropBlock(runtime, element) { ...@@ -259,6 +259,7 @@ function DragAndDropBlock(runtime, element) {
header_html: state.title, header_html: state.title,
show_title: state.show_title, show_title: state.show_title,
question_html: state.question_text, question_html: state.question_text,
show_question_header: state.show_question_header,
popup_html: state.state.feedback || '', popup_html: state.state.feedback || '',
feedback_html: $.trim(state.state.finished ? state.feedback.finish : state.feedback.start), feedback_html: $.trim(state.state.finished ? state.feedback.finish : state.feedback.start),
target_img_src: state.targetImg, target_img_src: state.targetImg,
......
...@@ -8,6 +8,8 @@ function DragAndDropEditBlock(runtime, element) { ...@@ -8,6 +8,8 @@ function DragAndDropEditBlock(runtime, element) {
// Make gettext available in Handlebars templates // Make gettext available in Handlebars templates
Handlebars.registerHelper('i18n', function(str) { return gettext(str); }); Handlebars.registerHelper('i18n', function(str) { return gettext(str); });
var $element = $(element);
var dragAndDrop = (function($) { var dragAndDrop = (function($) {
var _fn = { var _fn = {
...@@ -57,7 +59,7 @@ function DragAndDropEditBlock(runtime, element) { ...@@ -57,7 +59,7 @@ function DragAndDropEditBlock(runtime, element) {
$zoneTab = _fn.build.$el.zones.tab, $zoneTab = _fn.build.$el.zones.tab,
$itemTab = _fn.build.$el.items.tab; $itemTab = _fn.build.$el.items.tab;
$(element).one('click', '.continue-button', function(e) { $element.one('click', '.continue-button', function(e) {
// $fbkTab -> $zoneTab // $fbkTab -> $zoneTab
e.preventDefault(); e.preventDefault();
...@@ -418,12 +420,13 @@ function DragAndDropEditBlock(runtime, element) { ...@@ -418,12 +420,13 @@ function DragAndDropEditBlock(runtime, element) {
_fn.data.zones = _fn.build.form.zone.cleanObject(_fn.build.form.zone.obj); _fn.data.zones = _fn.build.form.zone.cleanObject(_fn.build.form.zone.obj);
var data = { var data = {
'display_name': $(element).find('.display-name').val(), 'display_name': $element.find('.display-name').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(),
'question_text': $(element).find('.question-text').val(), 'question_text': $element.find('.question-text').val(),
'item_background_color': $(element).find('.item-background-color').val(), 'show_question_header': $element.find('.show-question-header').is(':checked'),
'item_text_color': $(element).find('.item-text-color').val(), 'item_background_color': $element.find('.item-background-color').val(),
'item_text_color': $element.find('.item-text-color').val(),
'data': _fn.data, 'data': _fn.data,
}; };
...@@ -451,7 +454,7 @@ function DragAndDropEditBlock(runtime, element) { ...@@ -451,7 +454,7 @@ function DragAndDropEditBlock(runtime, element) {
}; };
})(jQuery); })(jQuery);
$(element).find('.cancel-button').bind('click', function() { $element.find('.cancel-button').bind('click', function() {
runtime.notify('cancel', {}); runtime.notify('cancel', {});
}); });
......
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
return ( return (
h('section.feedback', [ h('section.feedback', [
h('div.reset-button', {style: {display: reset_button_display}}, gettext('Reset exercise')), h('div.reset-button', {style: {display: reset_button_display}}, gettext('Reset exercise')),
h('div.title1', {style: {display: feedback_display}}, gettext('Feedback')), h('h3.title1', {style: {display: feedback_display}}, gettext('Feedback')),
h('p.message', {style: {display: feedback_display}, h('p.message', {style: {display: feedback_display},
innerHTML: ctx.feedback_html}) innerHTML: ctx.feedback_html})
]) ])
...@@ -86,15 +86,13 @@ ...@@ -86,15 +86,13 @@
}; };
var mainTemplate = function(ctx) { var mainTemplate = function(ctx) {
var problemHeader = ''; var problemHeader = ctx.show_title ? h('h2.problem-header', {innerHTML: ctx.header_html}) : null;
if (ctx.show_title) { var questionHeader = ctx.show_question_header ? h('h3.title1', gettext('Question')) : null;
problemHeader = h('h2.problem-header', {innerHTML: ctx.header_html});
}
return ( return (
h('section.xblock--drag-and-drop', [ h('section.xblock--drag-and-drop', [
problemHeader, problemHeader,
h('section.problem', {role: 'application'}, [ h('section.problem', {role: 'application'}, [
h('div.title1', gettext('Question')), questionHeader,
h('p', {innerHTML: ctx.question_html}) h('p', {innerHTML: ctx.question_html})
]), ]),
h('section.drag-container', [ h('section.drag-container', [
......
...@@ -17,14 +17,22 @@ ...@@ -17,14 +17,22 @@
<form class="feedback-form"> <form class="feedback-form">
<h3>{% trans "Question title" %}</h3> <h3>{% trans "Question title" %}</h3>
<input class="display-name" value="{{ self.display_name }}" /> <input class="display-name" value="{{ self.display_name }}" />
<input class="show-title" type="checkbox" value="{{ self.show_title }}" <label title="{{ help_texts.show_title }}">
{% if self.show_title %}checked="checked"{% endif %}> {% trans "Show title" %} <input class="show-title" type="checkbox"
{% if self.show_title %}checked="checked"{% endif %}>
{% trans "Show title" %}
</label>
<h3>{% trans "Maximum score" %}</h3> <h3>{% trans "Maximum score" %}</h3>
<input class="weight" value="1" value="{{ self.weight }}"/> <input class="weight" value="1" value="{{ self.weight }}"/>
<h3>{% trans "Question text" %}</h3> <h3>{% trans "Question text" %}</h3>
<textarea class="question-text">{{ self.question_text }}</textarea> <textarea class="question-text">{{ self.question_text }}</textarea>
<label title="{{ help_texts.show_question_header }}">
<input class="show-question-header" type="checkbox"
{% if self.show_question_header %}checked="checked"{% endif %}>
{% trans "Show \"Question\" heading" %}
</label>
<h3>{% trans "Introduction Feedback" %}</h3> <h3>{% trans "Introduction Feedback" %}</h3>
<textarea class="intro-feedback">{{ self.data.feedback.start }}</textarea> <textarea class="intro-feedback">{{ self.data.feedback.start }}</textarea>
......
# Installs xblock-sdk and dependencies needed to run the tests suite. # Installs xblock-sdk and dependencies needed to run the tests suite.
# Run this script inside a fresh virtual environment. # Run this script inside a fresh virtual environment.
pip install -e git://github.com/edx/xblock-sdk.git#egg=xblock-sdk pip install -e git://github.com/edx/xblock-sdk.git@4e8e713e7dd886b8d2eb66b5001216b66b9af81a#egg=xblock-sdk
cd $VIRTUAL_ENV/src/xblock-sdk/ && pip install -r requirements/base.txt \ cd $VIRTUAL_ENV/src/xblock-sdk/ && pip install -r requirements/base.txt \
&& pip install -r requirements/test.txt && cd - && pip install -r requirements/test.txt && cd -
python setup.py develop python setup.py develop
...@@ -89,7 +89,5 @@ ...@@ -89,7 +89,5 @@
"start": "Intro Feed", "start": "Intro Feed",
"finish": "Final Feed" "finish": "Final Feed"
}, },
"targetImg": "http://i0.kym-cdn.com/photos/images/newsfeed/000/030/404/1260585284155.png", "targetImg": "http://i0.kym-cdn.com/photos/images/newsfeed/000/030/404/1260585284155.png"
"title": "Drag and Drop",
"question_text": ""
} }
...@@ -71,5 +71,6 @@ ...@@ -71,5 +71,6 @@
"targetImg": "http://i0.kym-cdn.com/photos/images/newsfeed/000/030/404/1260585284155.png", "targetImg": "http://i0.kym-cdn.com/photos/images/newsfeed/000/030/404/1260585284155.png",
"title": "Drag and Drop", "title": "Drag and Drop",
"show_title": true, "show_title": true,
"question_text": "" "question_text": "",
"show_question_header": true
} }
...@@ -71,5 +71,6 @@ ...@@ -71,5 +71,6 @@
"targetImg": "http://i0.kym-cdn.com/photos/images/newsfeed/000/030/404/1260585284155.png", "targetImg": "http://i0.kym-cdn.com/photos/images/newsfeed/000/030/404/1260585284155.png",
"title": "Drag and Drop", "title": "Drag and Drop",
"show_title": true, "show_title": true,
"question_text": "" "question_text": "",
"show_question_header": true
} }
...@@ -89,7 +89,5 @@ ...@@ -89,7 +89,5 @@
"start": "Intro Feed", "start": "Intro Feed",
"finish": "Final <b>Feed</b>" "finish": "Final <b>Feed</b>"
}, },
"targetImg": "http://i0.kym-cdn.com/photos/images/newsfeed/000/030/404/1260585284155.png", "targetImg": "http://i0.kym-cdn.com/photos/images/newsfeed/000/030/404/1260585284155.png"
"title": "Drag and Drop",
"question_text": ""
} }
...@@ -19,15 +19,24 @@ class BaseIntegrationTest(SeleniumBaseTest): ...@@ -19,15 +19,24 @@ class BaseIntegrationTest(SeleniumBaseTest):
"'": "&apos;" "'": "&apos;"
} }
def _make_scenario_xml(self, display_name, show_title, question_text, completed): def _make_scenario_xml(self, display_name, show_title, question_text, completed=False, show_question_header=True):
return """ return """
<vertical_demo> <vertical_demo>
<drag-and-drop-v2 display_name='{display_name}' show_title='{show_title}' question_text='{question_text}' <drag-and-drop-v2
weight='1' completed='{completed}'/> display_name='{display_name}'
show_title='{show_title}'
question_text='{question_text}'
show_question_header='{show_question_header}'
weight='1'
completed='{completed}'
/>
</vertical_demo> </vertical_demo>
""".format( """.format(
display_name=escape(display_name), show_title=show_title, question_text=escape(question_text), display_name=escape(display_name),
completed=completed show_title=show_title,
question_text=escape(question_text),
show_question_header=show_question_header,
completed=completed,
) )
def _get_custom_scenario_xml(self, filename): def _get_custom_scenario_xml(self, filename):
......
...@@ -8,23 +8,26 @@ from workbench import scenarios ...@@ -8,23 +8,26 @@ from workbench import scenarios
class TestDragAndDropTitleAndQuestion(BaseIntegrationTest): class TestDragAndDropTitleAndQuestion(BaseIntegrationTest):
@unpack @unpack
@data( @data(
('plain1', 'title1', 'question1'), ('Plain text question 1, header visible.', True),
('plain2', 'title2', 'question2'), ('Plain text question 2, header hidden.', False),
('html1', 'title with <i>HTML</i>', 'Question with <i>HTML</i>'), ('Question/instructions with <i>HTML</i> and header.', True),
('html2', '<span style="color:red">Title: HTML?</span>', '<span style="color:red">Span question</span>'), ('<span style="color: red;">Span question, no header</span>', False),
) )
def test_title_and_question_parameters(self, _, display_name, question_text): def test_question_parameters(self, question_text, show_question_header):
const_page_name = 'Test title and question parameters' const_page_name = 'Test title and question parameters'
const_page_id = 'test_block_title_and_question' const_page_id = 'test_block_title_and_question'
scenario_xml = self._make_scenario_xml( scenario_xml = self._make_scenario_xml(
display_name=display_name, show_title=True, question_text=question_text, completed=False display_name="Title",
show_title=True,
question_text=question_text,
show_question_header=show_question_header,
) )
scenarios.add_xml_scenario(const_page_id, const_page_name, scenario_xml) scenarios.add_xml_scenario(const_page_id, const_page_name, scenario_xml)
self.addCleanup(scenarios.remove_scenario, const_page_id) self.addCleanup(scenarios.remove_scenario, const_page_id)
page = self.go_to_page(const_page_name) page = self.go_to_page(const_page_name)
problem_header = page.find_element_by_css_selector('h2.problem-header') is_question_header_visible = len(page.find_elements_by_css_selector('section.problem > h3')) > 0
self.assertEqual(self.get_element_html(problem_header), display_name) self.assertEqual(is_question_header_visible, show_question_header)
question = page.find_element_by_css_selector('section.problem > p') question = page.find_element_by_css_selector('section.problem > p')
self.assertEqual(self.get_element_html(question), question_text) self.assertEqual(self.get_element_html(question), question_text)
...@@ -36,11 +39,13 @@ class TestDragAndDropTitleAndQuestion(BaseIntegrationTest): ...@@ -36,11 +39,13 @@ class TestDragAndDropTitleAndQuestion(BaseIntegrationTest):
('html shown', 'title with <i>HTML</i>', True), ('html shown', 'title with <i>HTML</i>', True),
('html hidden', '<span style="color:red">Title: HTML?</span>', False) ('html hidden', '<span style="color:red">Title: HTML?</span>', False)
) )
def test_show_title_parameter(self, _, display_name, show_title): def test_title_parameters(self, _, display_name, show_title):
const_page_name = 'Test show title parameter' const_page_name = 'Test show title parameter'
const_page_id = 'test_block_show_title' const_page_id = 'test_block_show_title'
scenario_xml = self._make_scenario_xml( scenario_xml = self._make_scenario_xml(
display_name=display_name, show_title=show_title, question_text='Generic question', completed=False display_name=display_name,
show_title=show_title,
question_text='Generic question',
) )
scenarios.add_xml_scenario(const_page_id, const_page_name, scenario_xml) scenarios.add_xml_scenario(const_page_id, const_page_name, scenario_xml)
self.addCleanup(scenarios.remove_scenario, const_page_id) self.addCleanup(scenarios.remove_scenario, const_page_id)
......
...@@ -59,8 +59,9 @@ def test_studio_submit(): ...@@ -59,8 +59,9 @@ def test_studio_submit():
body = json.dumps({ body = json.dumps({
'display_name': "Test Drag & Drop", 'display_name': "Test Drag & Drop",
'show_title': True, 'show_title': False,
'question_text': "Question Drag & Drop", 'question_text': "Question Drag & Drop",
'show_question_header': False,
'item_background_color': 'cornflowerblue', 'item_background_color': 'cornflowerblue',
'item_text_color': 'coral', 'item_text_color': 'coral',
'weight': '5', 'weight': '5',
...@@ -72,8 +73,10 @@ def test_studio_submit(): ...@@ -72,8 +73,10 @@ def test_studio_submit():
assert_equals(json.loads(res.body), {'result': 'success'}) assert_equals(json.loads(res.body), {'result': 'success'})
assert_equals(block.show_title, False)
assert_equals(block.display_name, "Test Drag & Drop") assert_equals(block.display_name, "Test Drag & Drop")
assert_equals(block.question_text, "Question Drag & Drop") assert_equals(block.question_text, "Question Drag & Drop")
assert_equals(block.show_question_header, False)
assert_equals(block.item_background_color, "cornflowerblue") assert_equals(block.item_background_color, "cornflowerblue")
assert_equals(block.item_text_color, "coral") assert_equals(block.item_text_color, "coral")
assert_equals(block.weight, 5) assert_equals(block.weight, 5)
......
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