Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
xblock-poll
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
xblock-poll
Commits
cb450d50
Commit
cb450d50
authored
Jan 21, 2015
by
Xavier Antoviaque
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1 from open-craft/fixes
Addressed bugs from QA
parents
1b9c44da
3999ec31
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
58 additions
and
38 deletions
+58
-38
poll/poll.py
+12
-10
poll/public/css/poll.css
+2
-1
poll/public/handlebars/poll_studio.handlebars
+4
-4
poll/public/handlebars/survey_results.handlebars
+1
-1
poll/public/html/poll.html
+1
-1
poll/public/html/poll_edit.html
+1
-0
poll/public/html/survey.html
+1
-1
poll/public/js/poll_edit.js
+36
-20
No files found.
poll/poll.py
View file @
cb450d50
"""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
...
...
@@ -375,6 +374,9 @@ class PollBlock(PollBase):
class
SurveyBlock
(
PollBase
):
display_name
=
String
(
default
=
'Survey'
)
# The display name affects how the block is labeled in the studio,
# but either way we want it to say 'Poll' by default on the page.
block_name
=
String
(
default
=
'Poll'
)
answers
=
List
(
default
=
(
(
'Y'
,
'Yes'
),
(
'N'
,
'No'
),
...
...
@@ -424,7 +426,7 @@ 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
,
"
block_name"
:
self
.
block
_name
,
})
return
self
.
create_fragment
(
...
...
@@ -438,7 +440,7 @@ class SurveyBlock(PollBase):
js_template
=
self
.
resource_string
(
'/public/handlebars/poll_studio.handlebars'
)
context
.
update
({
'feedback'
:
self
.
feedback
,
'display_name'
:
self
.
display
_name
,
'display_name'
:
self
.
block
_name
,
'js_template'
:
js_template
,
'multiquestion'
:
True
,
})
...
...
@@ -567,7 +569,7 @@ class SurveyBlock(PollBase):
'answers'
:
[
value
for
value
in
OrderedDict
(
self
.
answers
)
.
values
()],
'tally'
:
detail
,
'total'
:
total
,
'feedback'
:
markdown
(
self
.
feedback
),
'plural'
:
total
>
1
,
'
display_name'
:
self
.
display
_name
,
'plural'
:
total
>
1
,
'
block_name'
:
self
.
block
_name
,
}
@XBlock.json_handler
...
...
@@ -639,7 +641,7 @@ class SurveyBlock(PollBase):
result
=
{
'success'
:
True
,
'errors'
:
[]}
feedback
=
data
.
get
(
'feedback'
,
''
)
.
strip
()
display
_name
=
data
.
get
(
'display_name'
,
''
)
.
strip
()
block
_name
=
data
.
get
(
'display_name'
,
''
)
.
strip
()
answers
=
self
.
gather_items
(
data
,
result
,
'Answer'
,
'answers'
,
image
=
False
)
questions
=
self
.
gather_items
(
data
,
result
,
'Question'
,
'questions'
)
...
...
@@ -650,7 +652,7 @@ class SurveyBlock(PollBase):
self
.
answers
=
answers
self
.
questions
=
questions
self
.
feedback
=
feedback
self
.
display_name
=
display
_name
self
.
block_name
=
block
_name
# Tally will not be updated until the next attempt to use it, per
# scoping limitations.
...
...
poll/public/css/poll.css
View file @
cb450d50
...
...
@@ -110,6 +110,7 @@ li.poll-result .poll-image {
margin-top
:
1em
;
margin-bottom
:
1em
;
font-size
:
smaller
;
font-weight
:
bold
;
}
.survey-table
{
...
...
@@ -143,7 +144,7 @@ li.poll-result .poll-image {
}
.survey-table
thead
tr
th
{
font-weight
:
normal
;
font-weight
:
bold
;
font-size
:
.8rem
;
}
...
...
poll/public/handlebars/poll_studio.handlebars
View file @
cb450d50
...
...
@@ -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
>
...
...
poll/public/handlebars/survey_results.handlebars
View file @
cb450d50
<script
id=
"survey-results-template"
type=
"text/html"
>
<
h3
class
=
"poll-header"
>
{{
display
_name
}}
<
/h3
>
<
h3
class
=
"poll-header"
>
{{
block
_name
}}
<
/h3
>
<
table
class
=
"survey-table"
>
<
thead
>
<
tr
>
...
...
poll/public/html/poll.html
View file @
cb450d50
...
...
@@ -2,7 +2,7 @@
<div
class=
"poll-block"
>
{# If no form is present, the Javascript will load the results instead. #}
{% if not choice %}
<h
2
class=
"poll-header"
>
{{display_name}}
</h2
>
<h
3
class=
"poll-header"
>
{{display_name}}
</h3
>
<form>
<div
class=
"poll-question-container"
>
{{question|safe}}
...
...
poll/public/html/poll_edit.html
View file @
cb450d50
...
...
@@ -5,6 +5,7 @@
<li
class=
"field comp-setting-entry is-set"
>
<div
class=
"wrapper-comp-setting"
>
<label
class=
"label setting-label poll-setting-label"
for=
"display_name"
>
Display Name
</label>
<!-- In the case of surveys, this field will actually be used for block_name. -->
<input
class=
"input setting-input"
name=
"display_name"
id=
"poll-display-name"
value=
"{{ display_name }}"
type=
"text"
/>
</div>
</li>
...
...
poll/public/html/survey.html
View file @
cb450d50
...
...
@@ -2,7 +2,7 @@
<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>
<h3
class=
"poll-header"
>
{{
block
_name}}
</h3>
<form>
<table
class=
"survey-table"
>
<thead>
...
...
poll/public/js/poll_edit.js
View file @
cb450d50
...
...
@@ -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'
])
});
}
}
});
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment