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
30017854
Commit
30017854
authored
Jan 01, 2015
by
Jonathan Piacenti
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactored JS and Python classes for better code reuse.
parent
7fc0f64f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
89 additions
and
56 deletions
+89
-56
poll/poll.py
+37
-24
poll/public/html/survey.html
+1
-0
poll/public/js/poll.js
+51
-32
No files found.
poll/poll.py
View file @
30017854
...
@@ -35,7 +35,35 @@ class ResourceMixin(object):
...
@@ -35,7 +35,35 @@ class ResourceMixin(object):
return
frag
return
frag
class
PollBlock
(
XBlock
,
ResourceMixin
,
PublishEventMixin
):
class
PollBase
(
XBlock
,
ResourceMixin
,
PublishEventMixin
):
"""
Base class for Poll-like XBlocks.
"""
event_namespace
=
'xblock.pollbase'
@XBlock.json_handler
def
load_answers
(
self
,
data
,
suffix
=
''
):
return
{
'answers'
:
[
{
'key'
:
key
,
'text'
:
value
[
'label'
],
'img'
:
value
[
'img'
]
}
for
key
,
value
in
self
.
answers
]
}
@XBlock.json_handler
def
get_results
(
self
,
data
,
suffix
=
''
):
self
.
publish_event_from_dict
(
self
.
event_namespace
+
'.view_results'
,
{})
detail
,
total
=
self
.
tally_detail
()
return
{
'question'
:
markdown
(
self
.
question
),
'tally'
:
detail
,
'total'
:
total
,
'feedback'
:
markdown
(
self
.
feedback
),
'plural'
:
total
>
1
,
}
class
PollBlock
(
PollBase
):
"""
"""
Poll XBlock. Allows a teacher to poll users, and presents the results so
Poll XBlock. Allows a teacher to poll users, and presents the results so
far of the poll to the user when finished.
far of the poll to the user when finished.
...
@@ -54,16 +82,7 @@ class PollBlock(XBlock, ResourceMixin, PublishEventMixin):
...
@@ -54,16 +82,7 @@ class PollBlock(XBlock, ResourceMixin, PublishEventMixin):
scope
=
Scope
.
user_state_summary
,
scope
=
Scope
.
user_state_summary
,
help
=
"Total tally of answers from students."
)
help
=
"Total tally of answers from students."
)
choice
=
String
(
scope
=
Scope
.
user_state
,
help
=
"The student's answer"
)
choice
=
String
(
scope
=
Scope
.
user_state
,
help
=
"The student's answer"
)
event_namespace
=
'xblock.poll'
@XBlock.json_handler
def
get_results
(
self
,
data
,
suffix
=
''
):
self
.
publish_event_from_dict
(
'xblock.poll.view_results'
,
{})
detail
,
total
=
self
.
tally_detail
()
return
{
'question'
:
markdown
(
self
.
question
),
'tally'
:
detail
,
'total'
:
total
,
'feedback'
:
markdown
(
self
.
feedback
),
'plural'
:
total
>
1
,
}
def
clean_tally
(
self
):
def
clean_tally
(
self
):
"""
"""
...
@@ -173,17 +192,6 @@ class PollBlock(XBlock, ResourceMixin, PublishEventMixin):
...
@@ -173,17 +192,6 @@ class PollBlock(XBlock, ResourceMixin, PublishEventMixin):
context
,
"public/html/poll.html"
,
"public/css/poll.css"
,
context
,
"public/html/poll.html"
,
"public/css/poll.css"
,
"public/js/poll.js"
,
"PollBlock"
)
"public/js/poll.js"
,
"PollBlock"
)
@XBlock.json_handler
def
load_answers
(
self
,
data
,
suffix
=
''
):
return
{
'answers'
:
[
{
'key'
:
key
,
'text'
:
value
[
'label'
],
'img'
:
value
[
'img'
]
}
for
key
,
value
in
self
.
answers
]
}
def
studio_view
(
self
,
context
=
None
):
def
studio_view
(
self
,
context
=
None
):
if
not
context
:
if
not
context
:
context
=
{}
context
=
{}
...
@@ -321,7 +329,7 @@ class PollBlock(XBlock, ResourceMixin, PublishEventMixin):
...
@@ -321,7 +329,7 @@ class PollBlock(XBlock, ResourceMixin, PublishEventMixin):
]
]
class
SurveyBlock
(
XBlock
,
ResourceMixin
,
PublishEventMixin
):
class
SurveyBlock
(
PollBase
):
display_name
=
String
(
default
=
'Survey'
)
display_name
=
String
(
default
=
'Survey'
)
answers
=
List
(
answers
=
List
(
default
=
(
default
=
(
...
@@ -345,6 +353,7 @@ class SurveyBlock(XBlock, ResourceMixin, PublishEventMixin):
...
@@ -345,6 +353,7 @@ class SurveyBlock(XBlock, ResourceMixin, PublishEventMixin):
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"
)
event_namespace
=
'xblock.survey'
def
student_view
(
self
,
context
=
None
):
def
student_view
(
self
,
context
=
None
):
"""
"""
...
@@ -354,10 +363,14 @@ class SurveyBlock(XBlock, ResourceMixin, PublishEventMixin):
...
@@ -354,10 +363,14 @@ class SurveyBlock(XBlock, ResourceMixin, PublishEventMixin):
if
not
context
:
if
not
context
:
context
=
{}
context
=
{}
js_template
=
self
.
resource_string
(
'/public/handlebars/poll_results.handlebars'
)
context
.
update
({
context
.
update
({
'choices'
:
self
.
choices
,
'choices'
:
self
.
choices
,
# Offset so choices will always be True.
# Offset so choices will always be True.
'answers'
:
self
.
answers
,
'answers'
:
self
.
answers
,
'js_template'
:
js_template
,
'questions'
:
self
.
questions
,
'questions'
:
self
.
questions
,
# Mustache is treating an empty string as true.
# Mustache is treating an empty string as true.
'feedback'
:
markdown
(
self
.
feedback
)
or
False
,
'feedback'
:
markdown
(
self
.
feedback
)
or
False
,
...
@@ -367,7 +380,7 @@ class SurveyBlock(XBlock, ResourceMixin, PublishEventMixin):
...
@@ -367,7 +380,7 @@ class SurveyBlock(XBlock, ResourceMixin, PublishEventMixin):
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"
,
"
Poll
Block"
)
"public/js/poll.js"
,
"
Survey
Block"
)
@staticmethod
@staticmethod
def
workbench_scenarios
():
def
workbench_scenarios
():
...
...
poll/public/html/survey.html
View file @
30017854
{{ js_template|safe }}
<div
class=
"survey-block"
>
<div
class=
"survey-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 %}
...
...
poll/public/js/poll.js
View file @
30017854
/* Javascript for PollBlock. */
/* Javascript for PollBlock. */
var
PollUtil
=
{
function
PollUtil
(
runtime
,
element
)
{
init
:
function
(
runtime
,
element
)
{
this
.
init
=
function
(
runtime
,
element
)
{
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
.
element
=
element
;
this
.
runtime
=
runtime
;
this
.
runtime
=
runtime
;
this
.
submit
=
$
(
'input[type=button]'
,
element
);
this
.
submit
=
$
(
'input[type=button]'
,
element
);
this
.
answers
=
$
(
'input[type=radio]'
,
element
);
this
.
resultsTemplate
=
Handlebars
.
compile
(
$
(
"#poll-results-template"
,
element
).
html
());
this
.
resultsTemplate
=
Handlebars
.
compile
(
$
(
"#poll-results-template"
,
element
).
html
());
}
,
}
;
poll_init
:
function
(){
this
.
pollInit
=
function
(){
// If the submit button doesn't exist, the user has already
// If the submit button doesn't exist, the user has already
// selected a choice.
// selected a choice.
var
self
=
this
;
var
self
=
this
;
var
enableSubmit
=
self
.
enableSubmit
();
var
getResults
=
self
.
getResults
();
if
(
self
.
submit
.
length
)
{
if
(
self
.
submit
.
length
)
{
var
radio
=
$
(
'input[name=choice]:checked'
,
self
.
element
);
var
radio
=
$
(
'input[name=choice]:checked'
,
self
.
element
);
self
.
submit
.
click
(
function
(
event
)
{
self
.
submit
.
click
(
function
()
{
// Refresh.
// Refresh.
radio
=
$
(
radio
.
selector
,
element
);
radio
=
$
(
radio
.
selector
,
self
.
element
);
var
choice
=
radio
.
val
();
var
choice
=
radio
.
val
();
$
.
ajax
({
$
.
ajax
({
type
:
"POST"
,
type
:
"POST"
,
url
:
self
.
voteUrl
,
url
:
self
.
voteUrl
,
data
:
JSON
.
stringify
({
"choice"
:
choice
}),
data
:
JSON
.
stringify
({
"choice"
:
choice
}),
success
:
self
.
getResults
success
:
getResults
});
});
});
});
// 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]'
,
self
.
element
);
if
(
!
radio
.
val
())
{
if
(
!
radio
.
val
())
{
answers
.
bind
(
"change.EnableSubmit"
,
self
.
enableSubmit
);
answers
.
bind
(
"change.EnableSubmit"
,
enableSubmit
);
}
else
{
}
else
{
self
.
enableSubmit
();
enableSubmit
();
}
}
}
else
{
}
else
{
self
.
getResults
({
'success'
:
true
});
getResults
({
'success'
:
true
});
}
}
}
,
}
;
getResults
:
function
(
data
)
{
this
.
surveyInit
=
function
()
{
};
this
.
getResults
=
function
()
{
var
self
=
this
;
var
self
=
this
;
if
(
!
data
[
'success'
])
{
return
function
(
data
)
{
alert
(
data
[
'errors'
].
join
(
'
\
n'
));
if
(
!
data
[
'success'
])
{
}
alert
(
data
[
'errors'
].
join
(
'
\
n'
));
$
.
ajax
({
// Semantically, this would be better as GET, but we can use helper
// functions with POST.
type
:
"POST"
,
url
:
self
.
tallyURL
,
data
:
JSON
.
stringify
({}),
success
:
function
(
data
)
{
$
(
'div.poll-block'
,
self
.
element
).
html
(
self
.
resultsTemplate
(
data
));
}
}
})
$
.
ajax
({
},
// Semantically, this would be better as GET, but we can use helper
// functions with POST.
type
:
"POST"
,
url
:
self
.
tallyURL
,
data
:
JSON
.
stringify
({}),
success
:
function
(
data
)
{
console
.
log
(
self
);
$
(
'div.poll-block'
,
self
.
element
).
html
(
self
.
resultsTemplate
(
data
));
}
})
}
};
enableSubmit
:
function
()
{
this
.
enableSubmit
=
function
()
{
this
.
submit
.
removeAttr
(
"disabled"
);
var
self
=
this
;
this
.
answers
.
unbind
(
"change.EnableSubmit"
);
return
function
()
{
}
self
.
submit
.
removeAttr
(
"disabled"
);
};
self
.
answers
.
unbind
(
"change.EnableSubmit"
);
}
};
this
.
init
(
runtime
,
element
);
}
function
PollBlock
(
runtime
,
element
)
{
function
PollBlock
(
runtime
,
element
)
{
PollUtil
.
init
(
runtime
,
element
);
var
util
=
new
PollUtil
(
runtime
,
element
);
PollUtil
.
poll_init
();
util
.
pollInit
();
}
function
SurveyBlock
(
runtime
,
element
)
{
var
util
=
new
PollUtil
(
runtime
,
element
);
util
.
surveyInit
();
}
}
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