Commit 99e7d007 by Arjun Singh

Adding a method of executing scripts fetched via AJAX in IE8+. Also adds…

Adding a method of executing scripts fetched via AJAX in IE8+. Also adds inputtype-specific handlers so that javascript can be executed when an inputtype is encountered.
parent 2337eeba
class @Problem
constructor: (element) ->
@el = $(element).find('.problems-wrapper')
@id = @el.data('problem-id')
......@@ -28,22 +29,69 @@ class @Problem
render: (content) ->
if content
@el.html(content)
@bind()
@executeProblemScripts () =>
@setupInputTypes()
@bind()
else
$.postWithPrefix "#{@url}/problem_get", (response) =>
@el.html(response.html)
@executeProblemScripts()
@bind()
@executeProblemScripts () =>
@setupInputTypes()
@bind()
# TODO add hooks for problem types here by inspecting response.html and doing
# stuff if a div w a class is found
setupInputTypes: =>
@el.find(".capa_inputtype").each (index, inputtype) =>
classes = $(inputtype).attr('class').split(' ')
for cls in classes
setupMethod = @inputtypeSetupMethods[cls]
setupMethod(inputtype) if setupMethod?
executeProblemScripts: (callback=null) ->
placeholders = @el.find(".script_placeholder")
executeProblemScripts: ->
@el.find(".script_placeholder").each (index, placeholder) ->
s = $("<script>")
s.attr("type", "text/javascript")
s.attr("src", $(placeholder).attr("data-src"))
if placeholders.length == 0
callback()
return
completed = (false for i in [1..placeholders.length])
callbackCalled = false
# This is required for IE8 support.
completionHandlerGeneratorIE = (index) =>
return () ->
if (this.readyState == 'complete' || this.readyState == 'loaded')
#completionHandlerGenerator.call(self, index)()
completionHandlerGenerator(index)()
completionHandlerGenerator = (index) =>
return () =>
allComplete = true
completed[index] = true
for flag in completed
if not flag
allComplete = false
break
if allComplete and not callbackCalled
callbackCalled = true
callback() if callback?
placeholders.each (index, placeholder) ->
s = document.createElement('script')
s.setAttribute('src', $(placeholder).attr("data-src"))
s.setAttribute('type', "text/javascript")
s.onload = completionHandlerGenerator(index)
# s.onload does not fire in IE8; this does.
s.onreadystatechange = completionHandlerGeneratorIE(index)
# Need to use the DOM elements directly or the scripts won't execute
# properly.
$('head')[0].appendChild(s[0])
$('head')[0].appendChild(s)
$(placeholder).remove()
###
......@@ -107,6 +155,9 @@ class @Problem
@render(response.html)
@updateProgress response
# TODO this needs modification to deal with javascript responses; perhaps we
# need something where responsetypes can define their own behavior when show
# is called.
show: =>
if !@el.hasClass 'showed'
Logger.log 'problem_show', problem: @id
......@@ -156,3 +207,20 @@ class @Problem
@$(".CodeMirror").each (index, element) ->
element.CodeMirror.save() if element.CodeMirror.save
@answers = @$("[id^=input_#{@element_id.replace(/problem_/, '')}_]").serialize()
inputtypeSetupMethods:
javascriptinput: (element) =>
data = $(element).find(".javascriptinput_data")
params = JSON.parse(data.attr("data-params"))
submission = JSON.parse(data.attr("data-submission"))
evaluation = JSON.parse(data.attr("data-evaluation"))
problemState = JSON.parse(data.attr("data-problem_state"))
displayClass = eval(data.attr("data-display_class"))
container = $(element).find(".javascriptinput_container")
submissionField = $(element).find(".javascriptinput_input")
display = new displayClass(problemState, submission, evaluation, container, submissionField, params)
display.render()
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