Commit 9ac33a23 by Jonathan Piacenti

CSS Stylings for Survey.

parent 9f198f74
...@@ -72,7 +72,7 @@ class PollBase(XBlock, ResourceMixin, PublishEventMixin): ...@@ -72,7 +72,7 @@ class PollBase(XBlock, ResourceMixin, PublishEventMixin):
return { return {
'question': markdown(self.question), 'tally': detail, 'question': markdown(self.question), 'tally': detail,
'total': total, 'feedback': markdown(self.feedback), 'total': total, 'feedback': markdown(self.feedback),
'plural': total > 1, 'plural': total > 1, 'display_name': self.display_name,
} }
@XBlock.json_handler @XBlock.json_handler
...@@ -227,6 +227,7 @@ class PollBlock(PollBase): ...@@ -227,6 +227,7 @@ class PollBlock(PollBase):
'any_img': self.any_image(), 'any_img': self.any_image(),
# The SDK doesn't set url_name. # The SDK doesn't set url_name.
'url_name': getattr(self, 'url_name', ''), 'url_name': getattr(self, 'url_name', ''),
"display_name": self.display_name,
}) })
if self.choice: if self.choice:
...@@ -241,7 +242,7 @@ class PollBlock(PollBase): ...@@ -241,7 +242,7 @@ class PollBlock(PollBase):
if not context: if not context:
context = {} context = {}
js_template = self.resource_string('/public/handlebars/studio.handlebars') js_template = self.resource_string('/public/handlebars/poll_studio.handlebars')
context.update({ context.update({
'question': self.question, 'question': self.question,
'feedback': self.feedback, 'feedback': self.feedback,
...@@ -249,7 +250,7 @@ class PollBlock(PollBase): ...@@ -249,7 +250,7 @@ class PollBlock(PollBase):
}) })
return self.create_fragment( return self.create_fragment(
context, "public/html/poll_edit.html", context, "public/html/poll_edit.html",
"/public/css/poll_edit.css", "public/js/poll_edit.js", "PollEditBlock") "/public/css/poll_edit.css", "public/js/poll_edit.js", "PollEdit")
@XBlock.json_handler @XBlock.json_handler
def studio_submit(self, data, suffix=''): def studio_submit(self, data, suffix=''):
...@@ -357,7 +358,7 @@ class SurveyBlock(PollBase): ...@@ -357,7 +358,7 @@ class SurveyBlock(PollBase):
scope=Scope.user_state_summary, scope=Scope.user_state_summary,
help="Total tally of answers from students." help="Total tally of answers from students."
) )
choices = Dict(help="The user's answers") choices = Dict(help="The user's answers", scope=Scope.user_state)
event_namespace = 'xblock.survey' event_namespace = 'xblock.survey'
def student_view(self, context=None): def student_view(self, context=None):
...@@ -381,12 +382,27 @@ class SurveyBlock(PollBase): ...@@ -381,12 +382,27 @@ class SurveyBlock(PollBase):
'feedback': markdown(self.feedback) or False, 'feedback': markdown(self.feedback) or False,
# The SDK doesn't set url_name. # The SDK doesn't set url_name.
'url_name': getattr(self, 'url_name', ''), 'url_name': getattr(self, 'url_name', ''),
"display_name": self.display_name,
}) })
return self.create_fragment( return self.create_fragment(
context, "public/html/survey.html", "public/css/poll.css", context, "public/html/survey.html", "public/css/poll.css",
"public/js/poll.js", "SurveyBlock") "public/js/poll.js", "SurveyBlock")
def studio_view(self, context=None):
if not context:
context = {}
js_template = self.resource_string('/public/handlebars/poll_studio.handlebars')
context.update({
'question': self.question,
'feedback': self.feedback,
'js_template': js_template
})
return self.create_fragment(
context, "public/html/poll_edit.html",
"/public/css/poll_edit.css", "public/js/poll_edit.js", "SurveyEditBlock")
def tally_detail(self): def tally_detail(self):
""" """
Return a detailed dictionary from the stored tally that the Return a detailed dictionary from the stored tally that the
...@@ -486,7 +502,7 @@ class SurveyBlock(PollBase): ...@@ -486,7 +502,7 @@ class SurveyBlock(PollBase):
'answers': [ 'answers': [
value['label'] for value in OrderedDict(self.answers).values()], value['label'] for value in OrderedDict(self.answers).values()],
'tally': detail, 'total': total, 'feedback': markdown(self.feedback), 'tally': detail, 'total': total, 'feedback': markdown(self.feedback),
'plural': total > 1, 'plural': total > 1, 'display_name': self.display_name,
} }
@XBlock.json_handler @XBlock.json_handler
......
...@@ -101,4 +101,75 @@ li.poll-result .poll-image { ...@@ -101,4 +101,75 @@ li.poll-result .poll-image {
margin-top: 1em; margin-top: 1em;
margin-bottom: 1em; margin-bottom: 1em;
font-size: smaller; font-size: smaller;
} }
\ No newline at end of file
.survey-table {
width: 100%;
border-collapse: collapse;
border: 0;
}
.survey-table td, .survey-table th {
border: 1px solid #CCC;
border-top: 0;
}
.survey-table tr:last-child td {
border-bottom: 0;
}
.survey-table tr td:first-child,
.survey-table tr th:first-child {
border-left: 0;
}
.survey-table tr td:last-child,
.survey-table tr th:last-child {
border-right: 0;
}
.survey-table thead {
border-top: 0;
background: none;
}
.survey-table thead tr th {
font-weight: normal;
font-size: .8rem;
}
.survey-table .survey-row {
background: none !important;
}
.survey-table .survey-option {
text-align: center;
vertical-align: middle;
}
.survey-option input {
margin: 0;
padding: 0;
}
th.survey-answer {
text-align: center;
width: 2em;
}
.poll-header {
text-transform: uppercase;
}
.survey-percentage {
font-weight: bolder;
font-size: 1.2rem;
}
.survey-question {
font-weight: bold;
}
.survey-choice {
background-color: #e5ebee;
}
<script id="poll-results-template" type="text/html"> <script id="poll-results-template" type="text/html">
<h2 class="poll-header">{{display_name}}</h2>
{{{question}}} {{{question}}}
<ul class="poll-answers-results"> <ul class="poll-answers-results">
{{#each tally}} {{#each tally}}
......
<script id="survey-results-template" type="text/html"> <script id="survey-results-template" type="text/html">
<table> <h3 class="poll-header">{{display_name}}</h3>
<table class="survey-table">
<thead> <thead>
<tr> <tr>
<th></th> <th></th>
{{#each answers}} {{#each answers}}
<th>{{this}}</th> <th class="survey-answer">{{this}}</th>
{{/each}} {{/each}}
</tr> </tr>
</thead> </thead>
{{#each tally}} {{#each tally}}
<tr> <tr class="survey-row">
<td>{{{text}}}</td> <td class="survey-question">{{{text}}}</td>
{{#each answers}} {{#each answers}}
<td class="survey-percentage">{{percent}}%</td> <td class="survey-percentage survey-option{{#if choice}} survey-choice{{/if}}{{#if top}} poll-top-choice{{/if}}">{{percent}}%</td>
{{/each}} {{/each}}
</tr> </tr>
{{/each}} {{/each}}
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
<div class="poll-block"> <div class="poll-block">
{# If no form is present, the Javascript will load the results instead. #} {# If no form is present, the Javascript will load the results instead. #}
{% if not choice %} {% if not choice %}
<h2 class="poll-header">{{display_name}}</h2>
<form> <form>
<div class="poll-question-container"> <div class="poll-question-container">
{{question|safe}} {{question|safe}}
...@@ -26,4 +27,4 @@ ...@@ -26,4 +27,4 @@
<input class="input-main" type="button" name="poll-submit" value="Submit" disabled /> <input class="input-main" type="button" name="poll-submit" value="Submit" disabled />
</form> </form>
{% endif %} {% endif %}
</div> </div>
\ No newline at end of file
...@@ -2,8 +2,9 @@ ...@@ -2,8 +2,9 @@
<div class="poll-block"> <div class="poll-block">
{# If no form is present, the Javascript will load the results instead. #} {# If no form is present, the Javascript will load the results instead. #}
{% if not choices %} {% if not choices %}
<h3 class="poll-header">{{display_name}}</h3>
<form> <form>
<table> <table class="survey-table">
<thead> <thead>
<tr> <tr>
<th></th> <th></th>
...@@ -13,7 +14,7 @@ ...@@ -13,7 +14,7 @@
</tr> </tr>
</thead> </thead>
{% for key, question in questions %} {% for key, question in questions %}
<tr> <tr class="survey-row">
<td class="survey-question"> <td class="survey-question">
{{question}} {{question}}
</td> </td>
......
...@@ -2,12 +2,11 @@ ...@@ -2,12 +2,11 @@
function PollUtil (runtime, element, pollType) { function PollUtil (runtime, element, pollType) {
var self = this; var self = this;
this.init = function(runtime, element) {
this.init = function() {
// Initialization function used for both Poll Types // Initialization function used for both Poll Types
this.voteUrl = runtime.handlerUrl(element, 'vote'); this.voteUrl = runtime.handlerUrl(element, 'vote');
this.tallyURL = runtime.handlerUrl(element, 'get_results'); this.tallyURL = runtime.handlerUrl(element, 'get_results');
this.element = element;
this.runtime = runtime;
this.submit = $('input[type=button]', element); this.submit = $('input[type=button]', element);
this.answers = $('input[type=radio]', element); this.answers = $('input[type=radio]', element);
this.resultsTemplate = Handlebars.compile($("#" + self.pollType + "-results-template", element).html()); this.resultsTemplate = Handlebars.compile($("#" + self.pollType + "-results-template", element).html());
...@@ -23,10 +22,10 @@ function PollUtil (runtime, element, pollType) { ...@@ -23,10 +22,10 @@ function PollUtil (runtime, element, pollType) {
this.pollInit = function(){ this.pollInit = function(){
// Initialization function for PollBlocks. // Initialization function for PollBlocks.
var radio = $('input[name=choice]:checked', self.element); var radio = $('input[name=choice]:checked', element);
self.submit.click(function () { self.submit.click(function () {
// Refresh. // Refresh.
radio = $(radio.selector, self.element); radio = $(radio.selector, element);
var choice = radio.val(); var choice = radio.val();
$.ajax({ $.ajax({
type: "POST", type: "POST",
...@@ -37,7 +36,7 @@ function PollUtil (runtime, element, pollType) { ...@@ -37,7 +36,7 @@ function PollUtil (runtime, element, pollType) {
}); });
// If the user has refreshed the page, they may still have an answer // If the user has refreshed the page, they may still have an answer
// selected and the submit button should be enabled. // selected and the submit button should be enabled.
var answers = $('input[type=radio]', self.element); var answers = $('input[type=radio]', element);
if (! radio.val()) { if (! radio.val()) {
answers.bind("change.enableSubmit", self.enableSubmit); answers.bind("change.enableSubmit", self.enableSubmit);
} else { } else {
...@@ -81,7 +80,7 @@ function PollUtil (runtime, element, pollType) { ...@@ -81,7 +80,7 @@ function PollUtil (runtime, element, pollType) {
// Verify that all questions have an answer selected. // Verify that all questions have an answer selected.
var doEnable = true; var doEnable = true;
self.answers.each(function (index, el) { self.answers.each(function (index, el) {
if (! $(self.checkedElement($(el)), self.element).length) { if (! $(self.checkedElement($(el)), element).length) {
doEnable = false; doEnable = false;
return false return false
} }
...@@ -104,7 +103,7 @@ function PollUtil (runtime, element, pollType) { ...@@ -104,7 +103,7 @@ function PollUtil (runtime, element, pollType) {
data: JSON.stringify({}), data: JSON.stringify({}),
success: function (data) { success: function (data) {
console.log(self); console.log(self);
$('div.poll-block', self.element).html(self.resultsTemplate(data)); $('div.poll-block', element).html(self.resultsTemplate(data));
} }
}) })
}; };
...@@ -116,7 +115,7 @@ function PollUtil (runtime, element, pollType) { ...@@ -116,7 +115,7 @@ function PollUtil (runtime, element, pollType) {
}; };
this.pollType = pollType; this.pollType = pollType;
var run_init = this.init(runtime, element); var run_init = this.init();
if (run_init) { if (run_init) {
var init_map = {'poll': self.pollInit, 'survey': self.surveyInit}; var init_map = {'poll': self.pollInit, 'survey': self.surveyInit};
init_map[pollType]() init_map[pollType]()
......
function PollEditBlock(runtime, element) { function PollEditUtil(runtime, element) {
var loadAnswers = runtime.handlerUrl(element, 'load_answers'); var self = this;
var temp = $('#answer-form-component', element).html();
var answerTemplate = Handlebars.compile(temp);
var pollLineItems =$('#poll-line-items', element);
function empowerDeletes(scope) { this.init = function () {
self.loadAnswers = runtime.handlerUrl(element, 'load_answers');
var temp = $('#answer-form-component', element).html();
self.answerTemplate = Handlebars.compile(temp);
self.pollLineItems =$('#poll-line-items', element);
$(element).find('.cancel-button', element).bind('click', function() {
runtime.notify('cancel', {});
});
$('#poll-add-answer', element).click(function () {
// The degree of precision on date should be precise enough to avoid
// collisions in the real world.
self.pollLineItems.append(self.answerTemplate({'answers': [{'key': new Date().getTime(), 'text': ''}]}));
var new_answer = $(self.pollLineItems.children().last());
self.empowerDeletes(new_answer);
self.empowerArrows(new_answer);
new_answer.fadeOut(250).fadeIn(250);
});
$(element).find('.save-button', element).bind('click', self.pollSubmitHandler);
$(function ($) {
$.ajax({
type: "POST",
url: self.loadAnswers,
data: JSON.stringify({}),
success: self.displayAnswers
});
});
};
this.empowerDeletes = function (scope) {
$('.poll-delete-answer', scope).click(function () { $('.poll-delete-answer', scope).click(function () {
$(this).parent().remove(); $(this).parent().remove();
}); });
} };
/* this.empowerArrows = function(scope) {
The poll answers need to be reorderable. As the UL they are in is not /*
easily isolated, we need to start checking their position to make The poll answers need to be reorderable. As the UL they are in is not
sure they aren't ordered above the other settings, which are also easily isolated, we need to start checking their position to make
in the list. sure they aren't ordered above the other settings, which are also
*/ in the list.
var starting_point = 3; */
function empowerArrows(scope) { var starting_point = 3;
$('.poll-move-up', scope).click(function () { $('.poll-move-up', scope).click(function () {
var tag = $(this).parents('li'); var tag = $(this).parents('li');
if (tag.index() <= starting_point){ if (tag.index() <= starting_point){
...@@ -34,29 +63,23 @@ function PollEditBlock(runtime, element) { ...@@ -34,29 +63,23 @@ function PollEditBlock(runtime, element) {
tag.next().after(tag); tag.next().after(tag);
tag.fadeOut("fast", "swing").fadeIn("fast", "swing"); tag.fadeOut("fast", "swing").fadeIn("fast", "swing");
}); });
} };
function displayAnswers(data) { this.displayAnswers = function(data) {
pollLineItems.append(answerTemplate(data)); self.pollLineItems.append(self.answerTemplate(data));
empowerDeletes(element); self.empowerDeletes(element);
empowerArrows(element); self.empowerArrows(element);
} };
$('#poll-add-answer', element).click(function () { this.check_return = function(data) {
// The degree of precision on date should be precise enough to avoid if (data['success']) {
// collisions in the real world. window.location.reload(false);
pollLineItems.append(answerTemplate({'answers': [{'key': new Date().getTime(), 'text': ''}]})); return;
var new_answer = $(pollLineItems.children().last()); }
empowerDeletes(new_answer); alert(data['errors'].join('\n'));
empowerArrows(new_answer); };
new_answer.fadeOut(250).fadeIn(250);
});
$(element).find('.cancel-button', element).bind('click', function() {
runtime.notify('cancel', {});
});
$(element).find('.save-button', element).bind('click', function() { this.pollSubmitHandler = function() {
var handlerUrl = runtime.handlerUrl(element, 'studio_submit'); var handlerUrl = runtime.handlerUrl(element, 'studio_submit');
var data = {'answers': []}; var data = {'answers': []};
var tracker = []; var tracker = [];
...@@ -81,27 +104,22 @@ function PollEditBlock(runtime, element) { ...@@ -81,27 +104,22 @@ function PollEditBlock(runtime, element) {
data['title'] = $('#poll-title', element).val(); data['title'] = $('#poll-title', element).val();
data['question'] = $('#poll-question-editor', element).val(); data['question'] = $('#poll-question-editor', element).val();
data['feedback'] = $('#poll-feedback-editor', element).val(); data['feedback'] = $('#poll-feedback-editor', element).val();
function check_return(data) {
if (data['success']) {
window.location.reload(false);
return;
}
alert(data['errors'].join('\n'));
}
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: handlerUrl, url: handlerUrl,
data: JSON.stringify(data), data: JSON.stringify(data),
success: check_return success: self.check_return
}); });
}); };
$(function ($) { self.init();
$.ajax({ }
type: "POST",
url: loadAnswers, function PollEdit(runtime, element) {
data: JSON.stringify({}), new PollEditUtil(runtime, element);
success: displayAnswers }
});
}); function SurveyEdit(runtime, element) {
} new PollEditUtil(runtime, element);
\ No newline at end of file }
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