Commit 9ac33a23 by Jonathan Piacenti

CSS Stylings for Survey.

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