diff --git a/common/lib/xmodule/setup.py b/common/lib/xmodule/setup.py
index b3a8dabe1b..a405d111be 100644
--- a/common/lib/xmodule/setup.py
+++ b/common/lib/xmodule/setup.py
@@ -39,7 +39,8 @@ setup(
"course_info = xmodule.html_module:CourseInfoDescriptor",
"static_tab = xmodule.html_module:StaticTabDescriptor",
"custom_tag_template = xmodule.raw_module:RawDescriptor",
- "about = xmodule.html_module:AboutDescriptor"
+ "about = xmodule.html_module:AboutDescriptor",
+ "poll = xmodule.poll_module:PollDescriptor",
],
}
)
diff --git a/common/lib/xmodule/xmodule/js/src/poll/display.coffee b/common/lib/xmodule/xmodule/js/src/poll/display.coffee
new file mode 100644
index 0000000000..f72ac8d319
--- /dev/null
+++ b/common/lib/xmodule/xmodule/js/src/poll/display.coffee
@@ -0,0 +1,13 @@
+class @PollModule
+ constructor: (element) ->
+ @el = element
+ @ajaxUrl = @$('.container').data('url')
+ @$('.upvote').on('click', () => $.postWithPrefix(@url('upvote'), @handleVote))
+ @$('.downvote').on('click', () => $.postWithPrefix(@url('downvote'), @handleVote))
+
+ $: (selector) -> $(selector, @el)
+
+ url: (target) -> "#{@ajaxUrl}/#{target}"
+
+ handleVote: (response) =>
+ @$('.container').replaceWith(response.results)
\ No newline at end of file
diff --git a/common/lib/xmodule/xmodule/poll_module.py b/common/lib/xmodule/xmodule/poll_module.py
new file mode 100644
index 0000000000..db0b3fd0c4
--- /dev/null
+++ b/common/lib/xmodule/xmodule/poll_module.py
@@ -0,0 +1,54 @@
+import json
+import logging
+
+from lxml import etree
+from pkg_resources import resource_string, resource_listdir
+
+from xmodule.x_module import XModule
+from xmodule.raw_module import RawDescriptor
+from .model import Int, Scope, Boolean
+
+log = logging.getLogger(__name__)
+
+
+class PollModule(XModule):
+
+ js = {'coffee': [resource_string(__name__, 'js/src/poll/display.coffee')]}
+ js_module_name = "PollModule"
+
+ upvotes = Int(help="Number of upvotes this poll has recieved", scope=Scope.content, default=0)
+ downvotes = Int(help="Number of downvotes this poll has recieved", scope=Scope.content, default=0)
+ voted = Boolean(help="Whether this student has voted on the poll", scope=Scope.student_state, default=False)
+
+ def handle_ajax(self, dispatch, get):
+ '''
+ Handle ajax calls to this video.
+ TODO (vshnayder): This is not being called right now, so the position
+ is not being saved.
+ '''
+ if self.voted:
+ return json.dumps({'error': 'Already Voted!'})
+ elif dispatch == 'upvote':
+ self.upvotes += 1
+ self.voted = True
+ return json.dumps({'results': self.get_html()})
+ elif dispatch == 'downvote':
+ self.downvotes += 1
+ self.voted = True
+ return json.dumps({'results': self.get_html()})
+
+ return json.dumps({'error': 'Unknown Command!'})
+
+ def get_html(self):
+ return self.system.render_template('poll.html', {
+ 'upvotes': self.upvotes,
+ 'downvotes': self.downvotes,
+ 'voted': self.voted,
+ 'ajax_url': self.system.ajax_url,
+ })
+
+
+class PollDescriptor(RawDescriptor):
+ module_class = PollModule
+ stores_state = True
+ template_dir_name = "poll"
\ No newline at end of file
diff --git a/common/test/data/toy/course/2012_Fall.xml b/common/test/data/toy/course/2012_Fall.xml
index 46dba8b8d8..31244ef60c 100644
--- a/common/test/data/toy/course/2012_Fall.xml
+++ b/common/test/data/toy/course/2012_Fall.xml
@@ -3,6 +3,7 @@