Commit 3999ec31 by Jonathan Piacenti

Fixed several issues with studio authoring.

parent 50c1d944
"""TO-DO: Write a description of what this XBlock is."""
from collections import OrderedDict
from django.template import Template, Context
......@@ -104,8 +103,8 @@ class PollBase(XBlock, ResourceMixin, PublishEventMixin):
if image and not image_link:
result['success'] = False
result['errors'].append(
"{0} has no text or img. Please make sure all {0}s "
"have one or the other, or both.".format(noun))
"{0} has no text or img. Please make sure all {1}s "
"have one or the other, or both.".format(noun, noun.lower()))
elif not image:
result['success'] = False
# If there's a bug in the code or the user just forgot to relabel a question,
......@@ -334,11 +333,11 @@ class PollBlock(PollBase):
result['errors'].append("You must specify a question.")
result['success'] = False
answers = self.gather_items(data, result, 'Answer', 'answers')
if not result['success']:
return result
answers = self.gather_items(data, result, 'Answer', 'answers')
self.answers = answers
self.question = question
self.feedback = feedback
......
......@@ -2,11 +2,11 @@
{{#each items}}
<li class="field comp-setting-entry is-set poll-{{noun}}-studio-item">
<div class="wrapper-comp-setting">
<label class="label setting-label poll-setting-label" for="{{noun}}-{{key}}">{{noun}}</label>
<input class="input setting-input" name="{{noun}}-{{key}}" id="{{noun}}-{{key}}" value="{{text}}" type="text" /><br />
<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 />
{{#if image}}
<label class="label setting-label" for="img-{{noun}}-{{key}}">Image URL</label>
<input class="input setting-input" name="img-{{noun}}-{{key}}" id="img-{{noun}}-{{key}}" value="{{img}}" type="text" />
<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" />
{{/if}}
<div class="poll-move">
<div class="poll-move-up">&#9650;</div>
......
......@@ -25,7 +25,9 @@ function PollEditUtil(runtime, element, pollType) {
// The degree of precision on date should be precise enough to avoid
// collisions in the real world.
var bottom = $(button_mapping[context_key]['bottomMarker']);
var new_item = $(self.answerTemplate(button_mapping[context_key]['itemList']));
var new_item_dict = self.extend({}, button_mapping[context_key]['template']);
new_item_dict['key'] = Date.now();
var new_item = $(self.answerTemplate({'items': [new_item_dict]}));
bottom.before(new_item);
self.empowerDeletes(new_item);
self.empowerArrows(
......@@ -80,7 +82,10 @@ function PollEditUtil(runtime, element, pollType) {
// 'extra' should contain 'image', a boolean value that determines whether
// an image path field should be provided, and 'noun', which should be either
// 'question' or 'answer' depending on what is needed.
return self.extend({'key': new Date().getTime(), 'text': '', 'img': ''}, extra)
// A 'key' element will have to be added after the fact, since it needs to be
// generated with the current time.
return self.extend({'text': '', 'img': ''}, extra)
};
this.empowerDeletes = function (scope) {
......@@ -125,7 +130,7 @@ function PollEditUtil(runtime, element, pollType) {
'poll': {
'buttons': {
'#poll-add-answer': {
'itemList': {'items': [self.makeNew({'image': true, 'noun': 'answer'})]},
'template': self.makeNew({'image': true, 'noun': 'answer'}),
'topMarker': '#poll-answer-marker', 'bottomMarker': '#poll-answer-end-marker'
}
},
......@@ -135,11 +140,11 @@ function PollEditUtil(runtime, element, pollType) {
'survey': {
'buttons': {
'#poll-add-answer': {
'itemList': {'items': [self.makeNew({'image': false, 'noun': 'answer'})]},
'template': self.makeNew({'image': false, 'noun': 'answer'}),
'topMarker': '#poll-answer-marker', 'bottomMarker': '#poll-answer-end-marker'
},
'#poll-add-question': {
'itemList': {'items': [self.makeNew({'image': true, 'noun': 'question'})]},
'template': self.makeNew({'image': true, 'noun': 'question'}),
'topMarker': '#poll-question-marker', 'bottomMarker': '#poll-question-end-marker'
}
},
......@@ -159,25 +164,14 @@ function PollEditUtil(runtime, element, pollType) {
self.empowerArrows(result, topMarker, bottomMarker);
};
this.checkReturn = function(data) {
// Handle the return value JSON from the server.
// It would be better if we could have a different function
// for errors, as AJAX calls normally allow, but our version of XBlock
// does not support status codes other than 200 for JSON encoded
// responses.
if (data['success']) {
window.location.reload(false);
return;
}
alert(data['errors'].join('\n'));
};
this.gather = function (scope, tracker, data, prefix, field) {
var key = 'label';
var name = scope.name.replace(prefix + '-', '');
if (scope.name.indexOf('img-') == 0){
if (name.indexOf('img-') == 0){
name = name.replace('img-', '');
key = 'img'
} else if (name.indexOf('label-') == 0){
name = name.replace('label-', '');
}
if (! (scope.name.indexOf(prefix + '-') >= 0)) {
return
......@@ -191,6 +185,16 @@ function PollEditUtil(runtime, element, pollType) {
return true
};
this.format_errors = function(errors) {
var new_list = [];
for (var line in errors) {
// Javascript has no sane HTML escape method.
// Do this instead.
new_list.push($('<div/>').text(errors[line]).html())
}
return new_list.join('<br />')
};
this.pollSubmitHandler = function () {
// Take all of the fields, serialize them, and pass them to the
// server for saving.
......@@ -211,11 +215,23 @@ function PollEditUtil(runtime, element, pollType) {
data['question'] = $('#poll-question-editor', element).val();
data['feedback'] = $('#poll-feedback-editor', element).val();
runtime.notify('save', {state: 'start', message: "Saving"});
$.ajax({
type: "POST",
url: handlerUrl,
data: JSON.stringify(data),
success: self.checkReturn
// There are issues with using proper status codes at the moment.
// So we pass along a 'success' key for now.
success: function(result) {
if (result['success']) {
runtime.notify('save', {state: 'end'})
} else {
runtime.notify('error', {
'title': 'Error saving poll',
'message': self.format_errors(result['errors'])
});
}
}
});
};
......
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