Commit 48b9846b by Tim Krones

Address review comments.

parent e8b10924
......@@ -29,7 +29,7 @@ DEFAULT_DATA = {
"correct": _("Yes, it's a 1")
},
"zone": "Zone 1",
"backgroundImage": "",
"imageURL": "",
"id": 0,
},
{
......@@ -39,7 +39,7 @@ DEFAULT_DATA = {
"correct": _("Yes, it's a 2")
},
"zone": "Zone 2",
"backgroundImage": "",
"imageURL": "",
"id": 1,
},
{
......@@ -49,7 +49,7 @@ DEFAULT_DATA = {
"correct": ""
},
"zone": "none",
"backgroundImage": "",
"imageURL": "",
"id": 2,
},
],
......
......@@ -198,7 +198,6 @@ class DragAndDropBlock(XBlock):
fragment.initialize_js('DragAndDropEditBlock', {
'data': self.data,
'target_img_expanded_url': self.target_img_expanded_url,
'target_img_description': self.target_img_description,
'default_background_image_url': self.default_background_image_url,
})
......
......@@ -115,7 +115,8 @@
/* Focused option */
.xblock--drag-and-drop .drag-container .item-bank .option:focus,
.xblock--drag-and-drop .drag-container .item-bank .option:hover {
transform: scale(1.1);
outline: 2px solid #fff;
outline-offset: -4px;
}
.xblock--drag-and-drop .drag-container .ui-draggable-dragging {
......
......@@ -103,7 +103,8 @@
margin: 10px 0 0 0;
}
.xblock--drag-and-drop--editor .target-image-form input {
.xblock--drag-and-drop--editor .target-image-form input,
.xblock--drag-and-drop--editor .target-image-form textarea {
width: 50%;
}
......@@ -141,8 +142,7 @@
width: 18%;
}
.xblock--drag-and-drop--editor .zones-form .zone-row .title,
.xblock--drag-and-drop--editor .zones-form .zone-row .description {
.xblock--drag-and-drop--editor .zones-form .zone-row > input {
width: 60%;
margin: 0 0 5px;
line-height: 2.664rem; /* .title gets line-height from a Studio rule that does not apply to .description;
......@@ -191,6 +191,11 @@
width: 35%;
}
.xblock--drag-and-drop--editor .items-form .item-image-url {
width: 81%;
margin-right: 1%;
}
.xblock--drag-and-drop--editor .items-form .item-width,
.xblock--drag-and-drop--editor .items-form .item-height {
width: 40px;
......
......@@ -167,11 +167,16 @@ function DragAndDropBlock(runtime, element, configuration) {
revert: 'invalid',
revertDuration: 150,
start: function(evt, ui) {
var item_id = $(this).data('value');
var $item = $(this);
$item.attr('aria-grabbed', true);
var item_id = $item.data('value');
publishEvent({
event_type: 'xblock.drag-and-drop-v2.item.picked-up',
item_id: item_id
});
},
stop: function(evt, ui) {
$(this).attr('aria-grabbed', false);
}
});
} catch (e) {
......@@ -311,18 +316,17 @@ function DragAndDropBlock(runtime, element, configuration) {
input.class_name = item_user_state.correct_input ? 'correct' : 'incorrect';
}
}
var content_html = item.displayName;
if (item.backgroundImage) {
content_html = '<img src="' + item.backgroundImage + '" alt="' + item.backgroundDescription + '" />';
}
var imageURL = item.imageURL || item.backgroundImage; // Fall back on "backgroundImage" to be backward-compatible
var itemProperties = {
value: item.id,
drag_disabled: Boolean(item_user_state || state.finished),
class_name: item_user_state && ('input' in item_user_state || item_user_state.correct_input) ? 'fade': undefined,
xhr_active: (item_user_state && item_user_state.submitting_location),
input: input,
content_html: content_html,
has_image: !!item.backgroundImage
displayName: item.displayName,
imageURL: imageURL,
imageDescription: item.imageDescription,
has_image: !!imageURL,
};
if (item_user_state) {
itemProperties.is_placed = true;
......
......@@ -70,11 +70,11 @@ function DragAndDropEditBlock(runtime, element, params) {
}
// Set the target image and bind its event handler:
$('.target-image-form input.url-input', element).val(_fn.data.targetImg);
$('.target-image-form input.description-input', element).val(_fn.data.targetImgDescription);
$('.target-image-form .url-input', element).val(_fn.data.targetImg);
$('.target-image-form .description-input', element).val(_fn.data.targetImgDescription);
_fn.build.$el.targetImage.load(_fn.build.form.zone.imageLoaded);
_fn.build.$el.targetImage.attr('src', params.target_img_expanded_url);
_fn.build.$el.targetImage.attr('alt', params.target_img_description);
_fn.build.$el.targetImage.attr('alt', _fn.data.targetImgDescription);
if (_fn.data.displayLabels) {
$('.display-labels-form input', element).prop('checked', true);
......@@ -124,7 +124,7 @@ function DragAndDropEditBlock(runtime, element, params) {
.on('click', '.target-image-form button', function(e) {
e.preventDefault();
var new_img_url = $.trim($('.target-image-form input.url-input', element).val());
var new_img_url = $.trim($('.target-image-form .url-input', element).val());
if (new_img_url) {
// We may need to 'expand' the URL before it will be valid.
// e.g. '/static/blah.png' becomes '/asset-v1:course+id/blah.png'
......@@ -139,7 +139,7 @@ function DragAndDropEditBlock(runtime, element, params) {
_fn.data.targetImg = new_img_url;
var new_description = $.trim(
$('.target-image-form input.description-input', element).val()
$('.target-image-form .description-input', element).val()
);
_fn.build.$el.targetImage.attr('alt', new_description);
_fn.data.targetImgDescription = new_description;
......@@ -388,10 +388,10 @@ function DragAndDropEditBlock(runtime, element, params) {
$form.each(function(i, el) {
var $el = $(el),
name = $el.find('.item-text').val(),
backgroundImage = $el.find('.background-image-url').val(),
backgroundDescription = $el.find('.background-image-description').val();
imageURL = $el.find('.item-image-url').val(),
imageDescription = $el.find('.item-image-description').val();
if (name.length > 0 || backgroundImage.length > 0) {
if (name.length > 0 || imageURL.length > 0) {
// Item width/height are ignored, but preserve the data:
var width = $el.find('.item-width').val(),
height = $el.find('.item-height').val();
......@@ -414,8 +414,8 @@ function DragAndDropEditBlock(runtime, element, params) {
width: width,
height: height
},
backgroundImage: backgroundImage,
backgroundDescription: backgroundDescription
imageURL: imageURL,
imageDescription: imageDescription,
};
var numValue = parseFloat($el.find('.item-numerical-value').val());
......
......@@ -71,6 +71,10 @@
if (item.has_image) {
className += " " + "option-with-image";
}
var content_html = item.displayName;
if (item.imageURL) {
content_html = '<img src="' + item.imageURL + '" alt="' + item.imageDescription + '" />';
}
return (
h('div.option',
{
......@@ -86,7 +90,7 @@
style: style
}, [
itemSpinnerTemplate(item.xhr_active),
h('div', {innerHTML: item.content_html, className: "item-content"}),
h('div', {innerHTML: content_html, className: "item-content"}),
itemInputTemplate(item.input)
]
)
......
......@@ -52,15 +52,14 @@
<h3 id="background-description-label">
{% trans "Background description" %}
</h3>
<input type="text"
class="description-input"
aria-labelledby="background-description-label"
aria-describedby="background-description-description">
<textarea class="description-input"
aria-labelledby="background-description-label"
aria-describedby="background-description-description"></textarea>
<div id="background-description-description" class="target-image-form-help">
{% blocktrans %}
Please provide a description of the image for non-visual users.
The description should provide sufficient information that would allow anyone
to solve the problem if the image did not load.
to solve the problem even without seeing the image.
{% endblocktrans %}
</div>
<button class="btn">{% trans "Change background" %}</button>
......
......@@ -11,26 +11,42 @@
<script id="zone-input-tpl" type="text/html">
<div class="zone-row {{ id }}" data-index="{{index}}">
<label>{{i18n "Text"}}</label>
<input type="text" class="title" value="{{ title }}" />
<label for="zone-{{index}}-title">{{i18n "Text"}}</label>
<input type="text"
id="zone-{{index}}-title"
class="title"
value="{{ title }}" />
<a href="#" class="remove-zone hidden">
<div class="icon remove"></div>
</a>
<label>{{i18n "Description"}}</label>
<label for="zone-{{index}}-description">{{i18n "Description"}}</label>
<input type="text"
id="zone-{{index}}-description"
class="description"
value="{{ description }}"
placeholder="{{i18n 'Describe this zone to non-visual users'}}" />
<div class="layout">
<label>{{i18n "width"}}</label>
<input type="text" class="size width" value="{{ width }}" />
<label>{{i18n "height"}}</label>
<input type="text" class="size height" value="{{ height }}" />
<label for="zone-{{index}}-width">{{i18n "width"}}</label>
<input type="text"
id="zone-{{index}}-width"
class="size width"
value="{{ width }}" />
<label for="zone-{{index}}-height">{{i18n "height"}}</label>
<input type="text"
id="zone-{{index}}-height"
class="size height"
value="{{ height }}" />
<br />
<label>x</label>
<input type="text" class="coord x" value="{{ x }}" />
<label>y</label>
<input type="text" class="coord y" value="{{ y }}" />
<label for="zone-{{index}}-x">x</label>
<input type="text"
id="zone-{{index}}-x"
class="coord x"
value="{{ x }}" />
<label for="zone-{{index}}-y">y</label>
<input type="text"
id="zone-{{index}}-y"
class="coord y"
value="{{ y }}" />
</div>
</div>
</script>
......@@ -42,29 +58,39 @@
<script id="item-input-tpl" type="text/html">
<div class="item">
<div class="row">
<label>{{i18n "Text"}}</label>
<input type="text" class="item-text" value="{{ displayName }}"/>
<label>{{i18n "Zone"}}</label>
<select class="zone-select">{{ dropdown }}</select>
<label for="item-{{id}}-text">{{i18n "Text"}}</label>
<input type="text"
id="item-{{id}}-text"
class="item-text"
value="{{ displayName }}" />
<label for="item-{{id}}-zone">{{i18n "Zone"}}</label>
<select id="item-{{id}}-zone"
class="zone-select">{{ dropdown }}</select>
<a href="#" class="remove-item hidden">
<div class="icon remove"></div>
</a>
</div>
<div class="row">
<label>{{i18n "Background image URL (alternative to the text)"}}</label>
<textarea class="background-image-url">{{ backgroundImage }}</textarea>
<label for="item-{{id}}-image-url">{{i18n "Image URL (alternative to the text)"}}</label>
<input type="text"
id="item-{{id}}-image-url"
class="item-image-url"
value="{{ imageURL }}" />
</div>
<div class="row">
<label>{{i18n "Background image description (should provide sufficient information to place the item even if the image did not load)"}}</label>
<textarea class="background-image-description">{{ backgroundDescription }}</textarea>
<label for="item-{{id}}-image-description">{{i18n "Image description (should provide sufficient information to place the item even if the image did not load)"}}</label>
<textarea id="item-{{id}}-image-description"
class="item-image-description">{{ imageDescription }}</textarea>
</div>
<div class="row">
<label>{{i18n "Success Feedback"}}</label>
<textarea class="success-feedback">{{ feedback.correct }}</textarea>
<label for="item-{{id}}-success-feedback">{{i18n "Success Feedback"}}</label>
<textarea id="item-{{id}}-success-feedback"
class="success-feedback">{{ feedback.correct }}</textarea>
</div>
<div class="row">
<label>{{i18n "Error Feedback"}}</label>
<textarea class="error-feedback">{{ feedback.incorrect }}</textarea>
<label for="item-{{id}}-error-feedback">{{i18n "Error Feedback"}}</label>
<textarea id="item-{{id}}-error-feedback"
class="error-feedback">{{ feedback.incorrect }}</textarea>
</div>
<div class="row" style="display: none;">
<!--
......@@ -75,16 +101,26 @@
If we do add them back in, we should only allow setting "width". Height will be
detected automatically based on font/image size requirements.
-->
<label>{{i18n "Width in pixels (0 for auto)"}}</label>
<input type="text" class="item-width" value="{{ width }}"></input>
<label>{{i18n "Height in pixels (0 for auto)"}}</label>
<input type="text" class="item-height" value="{{ height }}"></input>
<label for="item-{{id}}-width">{{i18n "Width in pixels (0 for auto)"}}</label>
<input type="text"
id="item-{{id}}-width"
class="item-width"
value="{{ width }}" />
<label for="item-{{id}}-height">{{i18n "Height in pixels (0 for auto)"}}</label>
<input type="text"
id="item-{{id}}-height"
class="item-height"
value="{{ height }}" />
</div>
<div class="row">
<label>{{i18n "Optional numerical value"}}</label>
<input type="text" class="item-numerical-value" value="{{ numericalValue }}"></input>
<label>{{i18n "Margin ±"}}</label>
<input type="text" class="item-numerical-margin" value="{{ numericalMargin }}"></input>
<label for="item-{{id}}-numerical-value">{{i18n "Optional numerical value"}}</label>
<input type="text"
id="item-{{id}}-numerical-value"
class="item-numerical-value" value="{{ numericalValue }}" />
<label for="item-{{id}}-numerical-margin">{{i18n "Margin ±"}}</label>
<input type="text"
id="item-{{id}}-numerical-margin"
class="item-numerical-margin" value="{{ numericalMargin }}" />
</div>
</div>
</script>
......@@ -27,7 +27,7 @@
"correct": "Yes 1"
},
"zone": "Zone 1",
"backgroundImage": "",
"imageURL": "",
"id": 0
},
{
......@@ -37,7 +37,7 @@
"correct": "Yes 2"
},
"zone": "Zone 2",
"backgroundImage": "",
"imageURL": "",
"id": 1,
"inputOptions": {
"value": 100,
......@@ -51,7 +51,7 @@
"correct": ""
},
"zone": "none",
"backgroundImage": "",
"imageURL": "",
"id": 2
}
],
......
{
"zones": [
{
"index": 1,
"title": "Zone 1",
"description": "This describes zone 1",
"height": 178,
"width": 196,
"y": "30",
"x": "160",
"id": "zone-1"
},
{
"index": 2,
"title": "Zone 2",
"description": "This describes zone 2",
"height": 140,
"width": 340,
"y": "210",
"x": "86",
"id": "zone-2"
}
],
"items": [
{
"displayName": "1",
"backgroundImage": "https://placehold.it/100x100",
"backgroundDescription": "This describes the background image of item 1",
"feedback": {
"incorrect": "No, 1 does not belong here",
"correct": "Yes, 1 goes here"
},
"zone": "Zone 1",
"id": 0
},
{
"displayName": "2",
"backgroundImage": "https://placehold.it/100x100",
"backgroundDescription": "This describes the background image of item 2",
"feedback": {
"incorrect": "No, 2 does not belong here",
"correct": "Yes, 2 goes here"
},
"zone": "Zone 2",
"id": 1
},
{
"displayName": "X",
"backgroundImage": "",
"feedback": {
"incorrect": "You silly, there are no zones for X",
"correct": ""
},
"zone": "none",
"id": 2
}
],
"feedback": {
"start": "Drag the items onto the image above.",
"finish": "Good work! You have completed this drag and drop exercise."
"zones": [
{
"index": 1,
"title": "Zone 1",
"description": "This describes zone 1",
"height": 178,
"width": 196,
"y": "30",
"x": "160",
"id": "zone-1"
},
"targetImgDescription": "This describes the target image"
{
"index": 2,
"title": "Zone 2",
"description": "This describes zone 2",
"height": 140,
"width": 340,
"y": "210",
"x": "86",
"id": "zone-2"
}
],
"items": [
{
"displayName": "1",
"imageURL": "https://placehold.it/100x100",
"imageDescription": "This describes the background image of item 1",
"feedback": {
"incorrect": "No, 1 does not belong here",
"correct": "Yes, 1 goes here"
},
"zone": "Zone 1",
"id": 0
},
{
"displayName": "2",
"imageURL": "https://placehold.it/100x100",
"imageDescription": "This describes the background image of item 2",
"feedback": {
"incorrect": "No, 2 does not belong here",
"correct": "Yes, 2 goes here"
},
"zone": "Zone 2",
"id": 1
},
{
"displayName": "X",
"imageURL": "",
"feedback": {
"incorrect": "You silly, there are no zones for X",
"correct": ""
},
"zone": "none",
"id": 2
}
],
"feedback": {
"start": "Drag the items onto the image above.",
"finish": "Good work! You have completed this drag and drop exercise."
},
"targetImgDescription": "This describes the target image"
}
......@@ -27,7 +27,7 @@
"correct": "Correct 1"
},
"zone": "Zone 51",
"backgroundImage": "",
"imageURL": "",
"id": 10
},
{
......@@ -37,7 +37,7 @@
"correct": "Correct 2"
},
"zone": "Zone 52",
"backgroundImage": "",
"imageURL": "",
"id": 20,
"inputOptions": {
"value": 100,
......@@ -51,7 +51,7 @@
"correct": ""
},
"zone": "none",
"backgroundImage": "",
"imageURL": "",
"id": 30
}
],
......
......@@ -27,7 +27,7 @@
"correct": "Yes <b>1</b>"
},
"zone": "Zone <i>1</i>",
"backgroundImage": "",
"imageURL": "",
"id": 0
},
{
......@@ -37,7 +37,7 @@
"correct": "Yes <i>2</i>"
},
"zone": "Zone <b>2</b>",
"backgroundImage": "",
"imageURL": "",
"id": 1,
"inputOptions": {
"value": 100,
......@@ -51,7 +51,7 @@
"correct": ""
},
"zone": "none",
"backgroundImage": "",
"imageURL": "",
"id": 2
}
],
......
......@@ -112,7 +112,9 @@ class TestDragAndDropRender(BaseIntegrationTest):
self._test_items(color_settings=color_settings)
def _test_items(self, color_settings={}): # pylint: disable=dangerous-default-value
def _test_items(self, color_settings=None):
color_settings = color_settings or {}
items = self._get_items()
self.assertEqual(len(items), 3)
......@@ -155,12 +157,8 @@ class TestDragAndDropRender(BaseIntegrationTest):
self.assertEqual(zone.get_attribute('data-zone'), 'Zone {}'.format(zone_number))
self.assertIn('ui-droppable', self.get_element_classes(zone))
zone_box_percentages = box_percentages[index]
self._assert_box_percentages(
'#zone-{}'.format(zone_number),
left=zone_box_percentages['left'],
top=zone_box_percentages['top'],
width=zone_box_percentages['width'],
height=zone_box_percentages['height']
self._assert_box_percentages( # pylint: disable=star-args
'#zone-{}'.format(zone_number), **zone_box_percentages
)
zone_name = zone.find_element_by_css_selector('p.zone-name')
self.assertEqual(zone_name.text, 'ZONE {}'.format(zone_number))
......
......@@ -34,25 +34,25 @@
"items": [
{
"displayName": "<b>1</b>",
"backgroundImage": "",
"imageURL": "",
"id": 0,
"inputOptions": false
},
{
"displayName": "<i>2</i>",
"backgroundImage": "",
"imageURL": "",
"id": 1,
"inputOptions": true
},
{
"displayName": "X",
"backgroundImage": "",
"imageURL": "",
"id": 2,
"inputOptions": false
},
{
"displayName": "",
"backgroundImage": "http://placehold.it/100x300",
"imageURL": "http://placehold.it/100x300",
"id": 3,
"inputOptions": false
}
......
......@@ -28,7 +28,7 @@
"correct": "Yes <b>1</b>"
},
"zone": "Zone <i>1</i>",
"backgroundImage": "",
"imageURL": "",
"id": 0
},
{
......@@ -38,7 +38,7 @@
"correct": "Yes <i>2</i>"
},
"zone": "Zone <b>2</b>",
"backgroundImage": "",
"imageURL": "",
"id": 1,
"inputOptions": {
"value": 100,
......@@ -52,7 +52,7 @@
"correct": ""
},
"zone": "none",
"backgroundImage": "",
"imageURL": "",
"id": 2
},
{
......@@ -62,7 +62,7 @@
"correct": ""
},
"zone": "none",
"backgroundImage": "http://placehold.it/100x300",
"imageURL": "http://placehold.it/100x300",
"id": 3
}
],
......
......@@ -34,28 +34,28 @@
"items": [
{
"displayName": "1",
"backgroundImage": "",
"imageURL": "",
"id": 0,
"inputOptions": false,
"size": {"height": "auto", "width": "190px"}
},
{
"displayName": "2",
"backgroundImage": "",
"imageURL": "",
"id": 1,
"inputOptions": true,
"size": {"height": "auto", "width": "190px"}
},
{
"displayName": "X",
"backgroundImage": "",
"imageURL": "",
"id": 2,
"inputOptions": false,
"size": {"height": "100px", "width": "100px"}
},
{
"displayName": "",
"backgroundImage": "http://i1.kym-cdn.com/entries/icons/square/000/006/151/tumblr_lltzgnHi5F1qzib3wo1_400.jpg",
"imageURL": "http://i1.kym-cdn.com/entries/icons/square/000/006/151/tumblr_lltzgnHi5F1qzib3wo1_400.jpg",
"id": 3,
"inputOptions": false,
"size": {"height": "auto", "width": "190px"}
......
......@@ -27,7 +27,7 @@
"correct": "Yes 1"
},
"zone": "Zone 1",
"backgroundImage": "",
"imageURL": "",
"id": 0,
"size": {
"width": "190px",
......@@ -41,7 +41,7 @@
"correct": "Yes 2"
},
"zone": "Zone 2",
"backgroundImage": "",
"imageURL": "",
"id": 1,
"size": {
"width": "190px",
......@@ -59,7 +59,7 @@
"correct": ""
},
"zone": "none",
"backgroundImage": "",
"imageURL": "",
"id": 2,
"size": {
"width": "100px",
......@@ -73,7 +73,7 @@
"correct": ""
},
"zone": "none",
"backgroundImage": "http://i1.kym-cdn.com/entries/icons/square/000/006/151/tumblr_lltzgnHi5F1qzib3wo1_400.jpg",
"imageURL": "http://i1.kym-cdn.com/entries/icons/square/000/006/151/tumblr_lltzgnHi5F1qzib3wo1_400.jpg",
"id": 3,
"size": {
"width": "190px",
......
......@@ -34,25 +34,25 @@
"items": [
{
"displayName": "1",
"backgroundImage": "",
"imageURL": "",
"id": 0,
"inputOptions": false
},
{
"displayName": "2",
"backgroundImage": "",
"imageURL": "",
"id": 1,
"inputOptions": true
},
{
"displayName": "X",
"backgroundImage": "",
"imageURL": "",
"id": 2,
"inputOptions": false
},
{
"displayName": "",
"backgroundImage": "http://placehold.it/200x100",
"imageURL": "http://placehold.it/200x100",
"id": 3,
"inputOptions": false
}
......
......@@ -29,7 +29,7 @@
"correct": "Yes 1"
},
"zone": "Zone 1",
"backgroundImage": "",
"imageURL": "",
"id": 0
},
{
......@@ -39,7 +39,7 @@
"correct": "Yes 2"
},
"zone": "Zone 2",
"backgroundImage": "",
"imageURL": "",
"id": 1,
"inputOptions": {
"value": 100,
......@@ -53,7 +53,7 @@
"correct": ""
},
"zone": "none",
"backgroundImage": "",
"imageURL": "",
"id": 2
},
{
......@@ -63,7 +63,7 @@
"correct": ""
},
"zone": "none",
"backgroundImage": "http://placehold.it/200x100",
"imageURL": "http://placehold.it/200x100",
"id": 3
}
],
......
......@@ -63,9 +63,9 @@ class BasicTests(TestCaseMixin, unittest.TestCase):
])
# Items should contain no answer data:
self.assertEqual(items, [
{"id": 0, "displayName": "1", "backgroundImage": "", "inputOptions": False},
{"id": 1, "displayName": "2", "backgroundImage": "", "inputOptions": False},
{"id": 2, "displayName": "X", "backgroundImage": "", "inputOptions": False},
{"id": 0, "displayName": "1", "imageURL": "", "inputOptions": False},
{"id": 1, "displayName": "2", "imageURL": "", "inputOptions": False},
{"id": 2, "displayName": "X", "imageURL": "", "inputOptions": False},
])
def test_ajax_solve_and_reset(self):
......
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