Commit 3d0e750f by Sven Marnach

Allow adding alt texts to images from the edit interface.

parent 6c86972e
...@@ -116,7 +116,7 @@ class PollBase(XBlock, ResourceMixin, PublishEventMixin): ...@@ -116,7 +116,7 @@ class PollBase(XBlock, ResourceMixin, PublishEventMixin):
""" """
Convert all items' labels into markdown. Convert all items' labels into markdown.
""" """
return [[key, {'label': markdown(value['label']), 'img': value['img']}] return [(key, {'label': markdown(value['label']), 'img': value['img'], 'img_alt': value.get('img_alt')})
for key, value in items] for key, value in items]
@staticmethod @staticmethod
...@@ -146,6 +146,7 @@ class PollBase(XBlock, ResourceMixin, PublishEventMixin): ...@@ -146,6 +146,7 @@ class PollBase(XBlock, ResourceMixin, PublishEventMixin):
result['errors'].append( result['errors'].append(
"{0} {1} contains no key.".format(noun, item)) "{0} {1} contains no key.".format(noun, item))
image_link = item.get('img', '').strip() image_link = item.get('img', '').strip()
image_alt = item.get('img_alt', '').strip()
label = item.get('label', '').strip() label = item.get('label', '').strip()
if not label: if not label:
if image and not image_link: if image and not image_link:
...@@ -163,8 +164,7 @@ class PollBase(XBlock, ResourceMixin, PublishEventMixin): ...@@ -163,8 +164,7 @@ class PollBase(XBlock, ResourceMixin, PublishEventMixin):
"Check the form and explicitly delete {1}s " "Check the form and explicitly delete {1}s "
"if not needed.".format(noun, noun.lower())) "if not needed.".format(noun, noun.lower()))
if image: if image:
# Labels might have prefixed space for markdown, though it's unlikely. items.append((key, {'label': label, 'img': image_link, 'img_alt': image_alt}))
items.append((key, {'label': label, 'img': image_link.strip()}))
else: else:
items.append([key, label]) items.append([key, label])
...@@ -236,8 +236,12 @@ class PollBlock(PollBase): ...@@ -236,8 +236,12 @@ class PollBlock(PollBase):
# This will be converted into an OrderedDict. # This will be converted into an OrderedDict.
# Key, (Label, Image path) # Key, (Label, Image path)
answers = List( answers = List(
default=(('R', {'label': 'Red', 'img': None}), ('B', {'label': 'Blue', 'img': None}), default=[
('G', {'label': 'Green', 'img': None}), ('O', {'label': 'Other', 'img': None})), ('R', {'label': 'Red', 'img': None, 'img_alt': None}),
('B', {'label': 'Blue', 'img': None, 'img_alt': None}),
('G', {'label': 'Green', 'img': None, 'img_alt': None}),
('O', {'label': 'Other', 'img': None, 'img_alt': None}),
],
scope=Scope.settings, help="The answer options on this poll." scope=Scope.settings, help="The answer options on this poll."
) )
tally = Dict(default={'R': 0, 'B': 0, 'G': 0, 'O': 0}, tally = Dict(default={'R': 0, 'B': 0, 'G': 0, 'O': 0},
...@@ -280,6 +284,7 @@ class PollBlock(PollBase): ...@@ -280,6 +284,7 @@ class PollBlock(PollBase):
'count': count, 'count': count,
'answer': value['label'], 'answer': value['label'],
'img': value['img'], 'img': value['img'],
'img_alt': value.get('img_alt'),
'key': key, 'key': key,
'first': False, 'first': False,
'choice': False, 'choice': False,
...@@ -311,7 +316,7 @@ class PollBlock(PollBase): ...@@ -311,7 +316,7 @@ class PollBlock(PollBase):
the student answered the poll. We don't want to take away the student answered the poll. We don't want to take away
the user's progress, but they should be able to vote again. the user's progress, but they should be able to vote again.
""" """
if self.choice and self.choice in OrderedDict(self.answers): if self.choice and self.choice in dict(self.answers):
return self.choice return self.choice
else: else:
return None return None
...@@ -376,9 +381,9 @@ class PollBlock(PollBase): ...@@ -376,9 +381,9 @@ class PollBlock(PollBase):
return { return {
'items': [ 'items': [
{ {
'key': key, 'text': value['label'], 'img': value['img'], 'key': key, 'text': value['label'], 'img': value['img'], 'img_alt': value.get('img_alt'),
'noun': 'answer', 'image': True, 'noun': 'answer', 'image': True,
} }
for key, value in self.answers for key, value in self.answers
], ],
} }
...@@ -487,10 +492,10 @@ class PollBlock(PollBase): ...@@ -487,10 +492,10 @@ class PollBlock(PollBase):
""" """
<poll tally="{'long': 20, 'short': 29, 'not_saying': 15, 'longer' : 35}" <poll tally="{'long': 20, 'short': 29, 'not_saying': 15, 'longer' : 35}"
question="## How long have you been studying with us?" question="## How long have you been studying with us?"
answers='[["longt", {"label": "A very long time", "img": null}], answers='[["longt", {"label": "A very long time", "img": null, "img_alt": null}],
["short", {"label": "Not very long", "img": null}], ["short", {"label": "Not very long", "img": null, "img_alt": null}],
["not_saying", {"label": "I shall not say", "img": null}], ["not_saying", {"label": "I shall not say", "img": null, "img_alt": null}],
["longer", {"label": "Longer than you", "img": null}]]' ["longer", {"label": "Longer than you", "img": null, "img_alt": null}]]'
feedback="### Thank you&#10;&#10;for being a valued student."/> feedback="### Thank you&#10;&#10;for being a valued student."/>
"""), """),
] ]
...@@ -510,11 +515,11 @@ class SurveyBlock(PollBase): ...@@ -510,11 +515,11 @@ class SurveyBlock(PollBase):
scope=Scope.settings, help="Answer choices for this Survey" scope=Scope.settings, help="Answer choices for this Survey"
) )
questions = List( questions = List(
default=( default=[
('enjoy', {'label': 'Are you enjoying the course?', 'img': None}), ('enjoy', {'label': 'Are you enjoying the course?', 'img': None, 'img_alt': None}),
('recommend', {'label': 'Would you recommend this course to your friends?', 'img': None}), ('recommend', {'label': 'Would you recommend this course to your friends?', 'img': None, 'img_alt': None}),
('learn', {'label': 'Do you think you will learn a lot?', 'img': None}) ('learn', {'label': 'Do you think you will learn a lot?', 'img': None, 'img_alt': None}),
), ],
scope=Scope.settings, help="Questions for this Survey" scope=Scope.settings, help="Questions for this Survey"
) )
tally = Dict( tally = Dict(
...@@ -616,6 +621,7 @@ class SurveyBlock(PollBase): ...@@ -616,6 +621,7 @@ class SurveyBlock(PollBase):
tally.append({ tally.append({
'label': value['label'], 'label': value['label'],
'img': value['img'], 'img': value['img'],
'img_alt': value.get('img_alt'),
'answers': [ 'answers': [
{ {
'count': count, 'choice': False, 'count': count, 'choice': False,
...@@ -740,7 +746,7 @@ class SurveyBlock(PollBase): ...@@ -740,7 +746,7 @@ class SurveyBlock(PollBase):
return { return {
'items': [ 'items': [
{ {
'key': key, 'text': value['label'], 'img': value['img'], 'key': key, 'text': value['label'], 'img': value['img'], 'img_alt': value.get('img_alt'),
'noun': 'question', 'image': True, 'noun': 'question', 'image': True,
} }
for key, value in self.questions for key, value in self.questions
...@@ -845,10 +851,11 @@ class SurveyBlock(PollBase): ...@@ -845,10 +851,11 @@ class SurveyBlock(PollBase):
"q2": {"sa": 3, "a": 2, "n": 3, "d": 10, "sd": 2}, "q2": {"sa": 3, "a": 2, "n": 3, "d": 10, "sd": 2},
"q3": {"sa": 2, "a": 7, "n": 1, "d": 4, "sd": 6}, "q3": {"sa": 2, "a": 7, "n": 1, "d": 4, "sd": 6},
"q4": {"sa": 1, "a": 2, "n": 8, "d": 4, "sd": 5}}' "q4": {"sa": 1, "a": 2, "n": 8, "d": 4, "sd": 5}}'
questions='[["q1", {"label": "I feel like this test will pass.", "img": null}], questions='[["q1", {"label": "I feel like this test will pass.", "img": null, "img_alt": null}],
["q2", {"label": "I like testing software", "img": null}], ["q2", {"label": "I like testing software", "img": null, "img_alt": null}],
["q3", {"label": "Testing is not necessary", "img": null}], ["q3", {"label": "Testing is not necessary", "img": null, "img_alt": null}],
["q4", {"label": "I would fake a test result to get software deployed.", "img": null}]]' ["q4", {"label": "I would fake a test result to get software deployed.", "img": null,
"img_alt": null}]]'
answers='[["sa", "Strongly Agree"], ["a", "Agree"], ["n", "Neutral"], answers='[["sa", "Strongly Agree"], ["a", "Agree"], ["n", "Neutral"],
["d", "Disagree"], ["sd", "Strongly Disagree"]]' ["d", "Disagree"], ["sd", "Strongly Disagree"]]'
feedback="### Thank you&#10;&#10;for running the tests."/> feedback="### Thank you&#10;&#10;for running the tests."/>
......
/* CSS for PollBlock Studio Menu View */ /* CSS for PollBlock Studio Menu View */
.poll-delete-answer { .poll-delete-answer {
clear: right;
float: right; float: right;
margin-top: 1em; margin-top: 1em;
} }
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<div class="poll-image result-image"> <div class="poll-image result-image">
<label for="answer-{{key}}" class="poll-image-label"> <label for="answer-{{key}}" class="poll-image-label">
{{#if img}} {{#if img}}
<img src="{{img}}" /> <img src="{{img}}" alt="{{img_alt}}"/>
{{/if}} {{/if}}
</label> </label>
</div> </div>
......
...@@ -2,21 +2,26 @@ ...@@ -2,21 +2,26 @@
{{#each items}} {{#each items}}
<li class="field comp-setting-entry is-set poll-{{noun}}-studio-item"> <li class="field comp-setting-entry is-set poll-{{noun}}-studio-item">
<div class="wrapper-comp-setting"> <div class="wrapper-comp-setting">
<div class="poll-move">
<div class="poll-move-up">&#9650;</div>
<div class="poll-move-down">&#9660;</div>
</div>
<a href="#" class="button action-button poll-delete-answer" onclick="return false;">Delete</a>
<label class="label setting-label poll-setting-label" for="{{noun}}-label-{{key}}">{{noun}}</label> <label class="label setting-label poll-setting-label" for="{{noun}}-label-{{key}}">{{noun}}</label>
<input class="input setting-input" name="{{noun}}-label-{{key}}" id="{{noun}}-label-{{key}}" value="{{text}}" type="text" /><br /> <input class="input setting-input" name="{{noun}}-label-{{key}}" id="{{noun}}-label-{{key}}" value="{{text}}" type="text" /><br />
{{#if image}} {{#if image}}
<label class="label setting-label" for="{{noun}}-img-{{key}}">Image URL</label> <label class="label setting-label" for="{{noun}}-img-{{key}}">Image URL</label>
<input class="input setting-input" name="{{noun}}-img-{{key}}" id="{{noun}}-img-{{key}}" value="{{img}}" type="text" /> <input class="input setting-input" name="{{noun}}-img-{{key}}" id="{{noun}}-img-{{key}}" value="{{img}}" type="text" /><br />
<label class="label setting-label" for="{{noun}}-img_alt-{{key}}">Image alternate text</label>
<input class="input setting-input" name="{{noun}}-img_alt-{{key}}" id="{{noun}}-img_alt-{{key}}" value="{{img_alt}}" type="text" /><br />
{{/if}} {{/if}}
<div class="poll-move">
<div class="poll-move-up">&#9650;</div>
<div class="poll-move-down">&#9660;</div>
</div>
</div> </div>
<span class="tip setting-help"> <span class="tip setting-help">
{{#if image}}This must have an image URL or text, and can have both.{{/if}} {{#if image}}
This must have an image URL or text, and can have both. If you add an image, an alternate text that describes
the image in a way that would allow someone to answer the poll if the image did not load is strongly encouraged.
{{/if}}
</span> </span>
<a href="#" class="button action-button poll-delete-answer" onclick="return false;">Delete</a>
</li> </li>
{{/each}} {{/each}}
</script> </script>
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
<td class="survey-question"> <td class="survey-question">
{{#if img}} {{#if img}}
<div class="poll-image-td"> <div class="poll-image-td">
<img src="{{img}}" /> <img src="{{img}}" alt="img_alt"/>
</div> </div>
{{/if}} {{/if}}
{{{label}}} {{{label}}}
......
...@@ -14,9 +14,7 @@ ...@@ -14,9 +14,7 @@
{% if value.img %} {% if value.img %}
<div class="poll-image"> <div class="poll-image">
<label for="{{url_name}}-answer-{{key}}" class="poll-image-label"> <label for="{{url_name}}-answer-{{key}}" class="poll-image-label">
{% if value.img %} <img src="{{value.img}}" alt="{{value.img_alt}}"/>
<img src="{{value.img}}" />
{% endif %}
</label> </label>
</div> </div>
{% endif %} {% endif %}
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
<td class="survey-question"> <td class="survey-question">
{% if question.img %} {% if question.img %}
<div class="poll-image-td"> <div class="poll-image-td">
<img src="{{question.img}}" /> <img src="{{question.img}}" alt="question.img_alt"/>
</div> </div>
{% endif %} {% endif %}
{{question.label|safe}} {{question.label|safe}}
......
...@@ -93,7 +93,7 @@ function PollEditUtil(runtime, element, pollType) { ...@@ -93,7 +93,7 @@ function PollEditUtil(runtime, element, pollType) {
// A 'key' element will have to be added after the fact, since it needs to be // A 'key' element will have to be added after the fact, since it needs to be
// generated with the current time. // generated with the current time.
return self.extend({'text': '', 'img': ''}, extra) return self.extend({'text': '', 'img': '', 'img_alt': ''}, extra)
}; };
this.empowerDeletes = function (scope) { this.empowerDeletes = function (scope) {
...@@ -175,16 +175,19 @@ function PollEditUtil(runtime, element, pollType) { ...@@ -175,16 +175,19 @@ function PollEditUtil(runtime, element, pollType) {
this.gather = function (scope, tracker, data, prefix, field) { this.gather = function (scope, tracker, data, prefix, field) {
var key = 'label'; var key = 'label';
var name = scope.name.replace(prefix + '-', ''); var name = scope.name.replace(prefix + '-', '');
if (name.indexOf('img-') == 0){ if (name.indexOf('img_alt-') == 0) {
name = name.replace('img_alt-', '');
key = 'img_alt'
} else if (name.indexOf('img-') == 0) {
name = name.replace('img-', ''); name = name.replace('img-', '');
key = 'img' key = 'img'
} else if (name.indexOf('label-') == 0){ } else if (name.indexOf('label-') == 0) {
name = name.replace('label-', ''); name = name.replace('label-', '');
} }
if (! (scope.name.indexOf(prefix + '-') >= 0)) { if (! (scope.name.indexOf(prefix + '-') >= 0)) {
return return
} }
if (tracker.indexOf(name) == -1){ if (tracker.indexOf(name) == -1) {
tracker.push(name); tracker.push(name);
data[field].push({'key': name}) data[field].push({'key': name})
} }
......
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