Commit b9708906 by Tim Krones

Merge pull request #45 from open-craft/oc-1161-2

Add a checkbox to the zone tab to control visibility of zone borders.…
parents 8be8937b 32f00642
...@@ -71,8 +71,9 @@ In the next step, you set the background image URL and define the ...@@ -71,8 +71,9 @@ In the next step, you set the background image URL and define the
properties of the drop zones. The properties include the title/text properties of the drop zones. The properties include the title/text
rendered in the drop zone, the zone's dimensions and position rendered in the drop zone, the zone's dimensions and position
coordinates. In this step you can also specify whether you would like coordinates. In this step you can also specify whether you would like
zone labels to be shown to students or not. It is possible to define zone labels to be shown to students or not, as well as whether or not
an arbitrary number of drop zones as long as their titles are unique. to display borders outlining the zones. It is possible to define an
arbitrary number of drop zones as long as their titles are unique.
![Drag item edit](https://raw.githubusercontent.com/edx-solutions/xblock-drag-and-drop-v2/5ff71f56ba454c66d8f2749bc1d55d5f1df3b792/doc/img/edit-view-items.png) ![Drag item edit](https://raw.githubusercontent.com/edx-solutions/xblock-drag-and-drop-v2/5ff71f56ba454c66d8f2749bc1d55d5f1df3b792/doc/img/edit-view-items.png)
......
...@@ -147,6 +147,7 @@ class DragAndDropBlock(XBlock): ...@@ -147,6 +147,7 @@ class DragAndDropBlock(XBlock):
return { return {
"zones": self.data.get('zones', []), "zones": self.data.get('zones', []),
"display_zone_labels": self.data.get('displayLabels', False), "display_zone_labels": self.data.get('displayLabels', False),
"display_zone_borders": self.data.get('displayBorders', False),
"items": items_without_answers(), "items": items_without_answers(),
"title": self.display_name, "title": self.display_name,
"show_title": self.show_title, "show_title": self.show_title,
......
...@@ -233,6 +233,10 @@ ...@@ -233,6 +233,10 @@
box-align:center; box-align:center;
} }
.xblock--drag-and-drop .zone-with-borders {
border: 1px dotted #565656;
}
/* Focused zone */ /* Focused zone */
.xblock--drag-and-drop .zone:focus { .xblock--drag-and-drop .zone:focus {
border: 2px solid #a5a5a5; border: 2px solid #a5a5a5;
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
box-pack:center; box-pack:center;
box-align:center; box-align:center;
border: 1px dotted #666; border: 1px dotted #565656;
box-sizing: border-box; box-sizing: border-box;
} }
......
...@@ -552,6 +552,7 @@ function DragAndDropBlock(runtime, element, configuration) { ...@@ -552,6 +552,7 @@ function DragAndDropBlock(runtime, element, configuration) {
target_img_src: configuration.target_img_expanded_url, target_img_src: configuration.target_img_expanded_url,
target_img_description: configuration.target_img_description, target_img_description: configuration.target_img_description,
display_zone_labels: configuration.display_zone_labels, display_zone_labels: configuration.display_zone_labels,
display_zone_borders: configuration.display_zone_borders,
zones: configuration.zones, zones: configuration.zones,
items: items, items: items,
// state - parts that can change: // state - parts that can change:
......
...@@ -80,6 +80,10 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -80,6 +80,10 @@ function DragAndDropEditBlock(runtime, element, params) {
$('.display-labels-form input', element).prop('checked', true); $('.display-labels-form input', element).prop('checked', true);
} }
if (_fn.data.displayBorders) {
$('.display-borders-form input', element).prop('checked', true);
}
$fbkTab.addClass('hidden'); $fbkTab.addClass('hidden');
$zoneTab.removeClass('hidden'); $zoneTab.removeClass('hidden');
...@@ -149,6 +153,9 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -149,6 +153,9 @@ function DragAndDropEditBlock(runtime, element, params) {
}) })
.on('click', '.display-labels-form input', function(e) { .on('click', '.display-labels-form input', function(e) {
_fn.data.displayLabels = $('.display-labels-form input', element).is(':checked'); _fn.data.displayLabels = $('.display-labels-form input', element).is(':checked');
})
.on('click', '.display-borders-form input', function(e) {
_fn.data.displayBorders = $('.display-borders-form input', element).is(':checked');
}); });
$itemTab $itemTab
......
...@@ -119,9 +119,10 @@ ...@@ -119,9 +119,10 @@
var zoneTemplate = function(zone, ctx) { var zoneTemplate = function(zone, ctx) {
var className = ctx.display_zone_labels ? 'zone-name' : 'zone-name sr'; var className = ctx.display_zone_labels ? 'zone-name' : 'zone-name sr';
var selector = ctx.display_zone_borders ? 'div.zone.zone-with-borders' : 'div.zone';
return ( return (
h( h(
'div.zone', selector,
{ {
id: zone.id, id: zone.id,
attributes: { attributes: {
......
...@@ -74,6 +74,11 @@ ...@@ -74,6 +74,11 @@
<label for="display-labels">{% trans "Display label names on the image" %}:</label> <label for="display-labels">{% trans "Display label names on the image" %}:</label>
<input name="display-labels" id="display-labels" type="checkbox" /> <input name="display-labels" id="display-labels" type="checkbox" />
</form> </form>
<form class="display-borders-form">
<h3>{% trans "Zone borders" %}</h3>
<label for="display-borders">{% trans "Display zone borders on the image" %}:</label>
<input name="display-borders" id="display-borders" type="checkbox" />
</form>
</section> </section>
<section class="tab-content"> <section class="tab-content">
<div class="zone-editor"> <div class="zone-editor">
......
...@@ -28,7 +28,7 @@ if __name__ == "__main__": ...@@ -28,7 +28,7 @@ if __name__ == "__main__":
try: try:
os.mkdir('var') os.mkdir('var')
except OSError: except OSError:
# May already exist. # The var dir may already exist.
pass pass
from django.core.management import execute_from_command_line from django.core.management import execute_from_command_line
......
...@@ -59,5 +59,7 @@ ...@@ -59,5 +59,7 @@
"start": "Drag the items onto the image above.", "start": "Drag the items onto the image above.",
"finish": "Good work! You have completed this drag and drop exercise." "finish": "Good work! You have completed this drag and drop exercise."
}, },
"targetImgDescription": "This describes the target image" "targetImgDescription": "This describes the target image",
"displayLabels": {display_labels_value},
"displayBorders": {display_borders_value},
} }
...@@ -11,6 +11,7 @@ class Colors(object): ...@@ -11,6 +11,7 @@ class Colors(object):
BLUE = 'rgb(29, 82, 128)' BLUE = 'rgb(29, 82, 128)'
GREY = 'rgb(237, 237, 237)' GREY = 'rgb(237, 237, 237)'
CORAL = '#ff7f50' CORAL = '#ff7f50'
DARK_GREY = 'rgb(86, 86, 86)' # == #565656 in CSS-land
CORNFLOWERBLUE = 'cornflowerblue' CORNFLOWERBLUE = 'cornflowerblue'
@classmethod @classmethod
...@@ -32,18 +33,22 @@ class TestDragAndDropRender(BaseIntegrationTest): ...@@ -32,18 +33,22 @@ class TestDragAndDropRender(BaseIntegrationTest):
PAGE_TITLE = 'Drag and Drop v2' PAGE_TITLE = 'Drag and Drop v2'
PAGE_ID = 'drag_and_drop_v2' PAGE_ID = 'drag_and_drop_v2'
ITEM_PROPERTIES = [{'text': '1'}, {'text': '2'}, {'text': 'X'}, ] ITEM_PROPERTIES = [{'text': '1'}, {'text': '2'}, {'text': 'X'}, ]
SIDES = ['Top', 'Bottom', 'Left', 'Right']
def load_scenario(self, item_background_color="", item_text_color=""): def load_scenario(self, item_background_color="", item_text_color="", zone_labels=False, zone_borders=False):
exercise_data = load_resource("integration/data/test_data_a11y.json")
exercise_data = exercise_data.replace('{display_labels_value}', 'true' if zone_labels else 'false')
exercise_data = exercise_data.replace('{display_borders_value}', 'true' if zone_borders else 'false')
scenario_xml = """ scenario_xml = """
<vertical_demo> <vertical_demo>
<drag-and-drop-v2 item_background_color='{item_background_color}' <drag-and-drop-v2 item_background_color='{item_background_color}'
item_text_color='{item_text_color}' item_text_color='{item_text_color}'
data='{data}' /> data='{exercise_data}' />
</vertical_demo> </vertical_demo>
""".format( """.format(
item_background_color=item_background_color, item_background_color=item_background_color,
item_text_color=item_text_color, item_text_color=item_text_color,
data=load_resource("integration/data/test_data_a11y.json") exercise_data=exercise_data
) )
self._add_scenario(self.PAGE_ID, self.PAGE_TITLE, scenario_xml) self._add_scenario(self.PAGE_ID, self.PAGE_TITLE, scenario_xml)
...@@ -218,3 +223,36 @@ class TestDragAndDropRender(BaseIntegrationTest): ...@@ -218,3 +223,36 @@ class TestDragAndDropRender(BaseIntegrationTest):
image_path = '/resource/drag-and-drop-v2/public/img/triangle.png' image_path = '/resource/drag-and-drop-v2/public/img/triangle.png'
self.assertTrue(bg_image.get_attribute("src").endswith(image_path)) self.assertTrue(bg_image.get_attribute("src").endswith(image_path))
self.assertEqual(bg_image.get_attribute("alt"), 'This describes the target image') self.assertEqual(bg_image.get_attribute("alt"), 'This describes the target image')
def test_zone_borders_hidden(self):
self.load_scenario()
zones = self._get_zones()
for index, dummy in enumerate(zones, start=1):
zone = '#zone-{}'.format(index)
for side in self.SIDES:
self.assertEqual(self._get_style(zone, 'border{}Width'.format(side), True), '0px')
self.assertEqual(self._get_style(zone, 'border{}Style'.format(side), True), 'none')
def test_zone_borders_shown(self):
self.load_scenario(zone_borders=True)
zones = self._get_zones()
for index, dummy in enumerate(zones, start=1):
zone = '#zone-{}'.format(index)
for side in self.SIDES:
self.assertEqual(self._get_style(zone, 'border{}Width'.format(side), True), '1px')
self.assertEqual(self._get_style(zone, 'border{}Style'.format(side), True), 'dotted')
self.assertEqual(self._get_style(zone, 'border{}Color'.format(side), True), Colors.DARK_GREY)
def test_zone_labels_hidden(self):
self.load_scenario()
zones = self._get_zones()
for zone in zones:
zone_name = zone.find_element_by_css_selector('p.zone-name')
self.assertIn('sr', zone_name.get_attribute('class'))
def test_zone_labels_shown(self):
self.load_scenario(zone_labels=True)
zones = self._get_zones()
for zone in zones:
zone_name = zone.find_element_by_css_selector('p.zone-name')
self.assertNotIn('sr', zone_name.get_attribute('class'))
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
"item_background_color": "white", "item_background_color": "white",
"item_text_color": "#000080", "item_text_color": "#000080",
"initial_feedback": "HTML <strong>Intro</strong> Feed", "initial_feedback": "HTML <strong>Intro</strong> Feed",
"display_zone_borders": false,
"display_zone_labels": false, "display_zone_labels": false,
"zones": [ "zones": [
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
"item_background_color": null, "item_background_color": null,
"item_text_color": null, "item_text_color": null,
"initial_feedback": "Intro Feed", "initial_feedback": "Intro Feed",
"display_zone_borders": false,
"display_zone_labels": false, "display_zone_labels": false,
"zones": [ "zones": [
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
"item_background_color": null, "item_background_color": null,
"item_text_color": null, "item_text_color": null,
"initial_feedback": "This is the initial feedback.", "initial_feedback": "This is the initial feedback.",
"display_zone_borders": false,
"display_zone_labels": false, "display_zone_labels": false,
"zones": [ "zones": [
......
...@@ -29,6 +29,7 @@ class BasicTests(TestCaseMixin, unittest.TestCase): ...@@ -29,6 +29,7 @@ class BasicTests(TestCaseMixin, unittest.TestCase):
zones = config.pop("zones") zones = config.pop("zones")
items = config.pop("items") items = config.pop("items")
self.assertEqual(config, { self.assertEqual(config, {
"display_zone_borders": False,
"display_zone_labels": False, "display_zone_labels": False,
"title": "Drag and Drop", "title": "Drag and Drop",
"show_title": True, "show_title": True,
......
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