Commit 9545a82a by Diana Huang

Add the ability to make ajax calls on the input type of capa problems.

parent f8adfc62
...@@ -146,6 +146,9 @@ class LoncapaProblem(object): ...@@ -146,6 +146,9 @@ class LoncapaProblem(object):
if not self.student_answers: # True when student_answers is an empty dict if not self.student_answers: # True when student_answers is an empty dict
self.set_initial_display() self.set_initial_display()
self.extracted_tree = self._extract_html(self.tree)
def do_reset(self): def do_reset(self):
''' '''
Reset internal state to unfinished, with no answers Reset internal state to unfinished, with no answers
...@@ -324,7 +327,21 @@ class LoncapaProblem(object): ...@@ -324,7 +327,21 @@ class LoncapaProblem(object):
''' '''
Main method called externally to get the HTML to be rendered for this capa Problem. Main method called externally to get the HTML to be rendered for this capa Problem.
''' '''
return contextualize_text(etree.tostring(self._extract_html(self.tree)), self.context) html = contextualize_text(etree.tostring(self.extracted_tree), self.context)
return html
def handle_input_ajax(self, get):
'''
This passes any specialized input ajax onto the input class
It also parses out the dispatch from the get so that it can be passed onto the input type nicely
'''
if self.input:
dispatch = get['dispatch']
return self.input.handle_ajax(dispatch, get)
return {}
# ======= Private Methods Below ======== # ======= Private Methods Below ========
...@@ -458,6 +475,8 @@ class LoncapaProblem(object): ...@@ -458,6 +475,8 @@ class LoncapaProblem(object):
finally: finally:
sys.path = original_path sys.path = original_path
def _extract_html(self, problemtree): # private def _extract_html(self, problemtree): # private
''' '''
Main (private) function which converts Problem XML tree to HTML. Main (private) function which converts Problem XML tree to HTML.
...@@ -468,6 +487,7 @@ class LoncapaProblem(object): ...@@ -468,6 +487,7 @@ class LoncapaProblem(object):
Used by get_html. Used by get_html.
''' '''
if (problemtree.tag == 'script' and problemtree.get('type') if (problemtree.tag == 'script' and problemtree.get('type')
and 'javascript' in problemtree.get('type')): and 'javascript' in problemtree.get('type')):
# leave javascript intact. # leave javascript intact.
...@@ -505,8 +525,9 @@ class LoncapaProblem(object): ...@@ -505,8 +525,9 @@ class LoncapaProblem(object):
'hintmode': hintmode, }} 'hintmode': hintmode, }}
input_type_cls = inputtypes.registry.get_class_for_tag(problemtree.tag) input_type_cls = inputtypes.registry.get_class_for_tag(problemtree.tag)
the_input = input_type_cls(self.system, problemtree, state) # save the input type so that we can make ajax calls on it if we need to
return the_input.get_html() self.input = input_type_cls(self.system, problemtree, state)
return self.input.get_html()
# let each Response render itself # let each Response render itself
if problemtree in self.responders: if problemtree in self.responders:
......
...@@ -215,6 +215,18 @@ class InputTypeBase(object): ...@@ -215,6 +215,18 @@ class InputTypeBase(object):
""" """
pass pass
def handle_ajax(self, dispatch, get):
"""
InputTypes that need to handle specialized AJAX should override this.
Input:
dispatch: a string that can be used to determine how to handle the data passed in
get: a dictionary containing the data that was sent with the ajax call
Output:
a dictionary object that will then get sent back to the Javascript
"""
pass
def _get_render_context(self): def _get_render_context(self):
""" """
......
...@@ -412,6 +412,7 @@ class CapaModule(XModule): ...@@ -412,6 +412,7 @@ class CapaModule(XModule):
'weight': self.descriptor.weight, 'weight': self.descriptor.weight,
} }
context = {'problem': content, context = {'problem': content,
'id': self.id, 'id': self.id,
'check_button': check_button, 'check_button': check_button,
...@@ -449,6 +450,7 @@ class CapaModule(XModule): ...@@ -449,6 +450,7 @@ class CapaModule(XModule):
'problem_save': self.save_problem, 'problem_save': self.save_problem,
'problem_show': self.get_answer, 'problem_show': self.get_answer,
'score_update': self.update_score, 'score_update': self.update_score,
'input_ajax': self.lcp.handle_input_ajax
} }
if dispatch not in handlers: if dispatch not in handlers:
......
...@@ -76,6 +76,14 @@ class @Problem ...@@ -76,6 +76,14 @@ class @Problem
# TODO: Some logic to dynamically adjust polling rate based on queuelen # TODO: Some logic to dynamically adjust polling rate based on queuelen
window.queuePollerID = window.setTimeout(@poll, 1000) window.queuePollerID = window.setTimeout(@poll, 1000)
# Use this if you want to make an ajax call on the input type object
# static method so you don't have to instantiate a Problem in order to use it
@inputAjax: (url, dispatch, data, callback) ->
data['dispatch'] = dispatch
$.postWithPrefix "#{url}/input_ajax", data, callback
render: (content) -> render: (content) ->
if content if content
@el.html(content) @el.html(content)
......
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