diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py index 76158093b6..46f07796db 100644 --- a/common/lib/xmodule/xmodule/capa_module.py +++ b/common/lib/xmodule/xmodule/capa_module.py @@ -580,76 +580,76 @@ class CapaModule(XModule): 'contents': html, } -def save_problem(self, get): - ''' - Save the passed in answers. - Returns a dict { 'success' : bool, ['error' : error-msg]}, - with the error key only present if success is False. - ''' - event_info = dict() - event_info['state'] = self.lcp.get_state() - event_info['problem_id'] = self.location.url() + def save_problem(self, get): + ''' + Save the passed in answers. + Returns a dict { 'success' : bool, ['error' : error-msg]}, + with the error key only present if success is False. + ''' + event_info = dict() + event_info['state'] = self.lcp.get_state() + event_info['problem_id'] = self.location.url() - answers = self.make_dict_of_responses(get) - event_info['answers'] = answers + answers = self.make_dict_of_responses(get) + event_info['answers'] = answers - # Too late. Cannot submit - if self.closed(): - event_info['failure'] = 'closed' + # Too late. Cannot submit + if self.closed(): + event_info['failure'] = 'closed' + self.system.track_function('save_problem_fail', event_info) + return {'success': False, + 'error': "Problem is closed"} + + # Problem submitted. Student should reset before saving + # again. + if self.lcp.done and self.rerandomize == "always": + event_info['failure'] = 'done' + self.system.track_function('save_problem_fail', event_info) + return {'success': False, + 'error': "Problem needs to be reset prior to save."} + + self.lcp.student_answers = answers + + # TODO: should this be save_problem_fail? Looks like success to me... self.system.track_function('save_problem_fail', event_info) - return {'success': False, - 'error': "Problem is closed"} + return {'success': True} - # Problem submitted. Student should reset before saving - # again. - if self.lcp.done and self.rerandomize == "always": - event_info['failure'] = 'done' - self.system.track_function('save_problem_fail', event_info) - return {'success': False, - 'error': "Problem needs to be reset prior to save."} + def reset_problem(self, get): + ''' Changes problem state to unfinished -- removes student answers, + and causes problem to rerender itself. - self.lcp.student_answers = answers + Returns problem html as { 'html' : html-string }. + ''' + event_info = dict() + event_info['old_state'] = self.lcp.get_state() + event_info['problem_id'] = self.location.url() - # TODO: should this be save_problem_fail? Looks like success to me... - self.system.track_function('save_problem_fail', event_info) - return {'success': True} + if self.closed(): + event_info['failure'] = 'closed' + self.system.track_function('reset_problem_fail', event_info) + return {'success': False, + 'error': "Problem is closed"} -def reset_problem(self, get): - ''' Changes problem state to unfinished -- removes student answers, - and causes problem to rerender itself. + if not self.lcp.done: + event_info['failure'] = 'not_done' + self.system.track_function('reset_problem_fail', event_info) + return {'success': False, + 'error': "Refresh the page and make an attempt before resetting."} - Returns problem html as { 'html' : html-string }. - ''' - event_info = dict() - event_info['old_state'] = self.lcp.get_state() - event_info['problem_id'] = self.location.url() + self.lcp.do_reset() + if self.rerandomize in ["always", "onreset"]: + # reset random number generator seed (note the self.lcp.get_state() + # in next line) + self.lcp.seed = None - if self.closed(): - event_info['failure'] = 'closed' - self.system.track_function('reset_problem_fail', event_info) - return {'success': False, - 'error': "Problem is closed"} + self.lcp = LoncapaProblem(self.definition['data'], + self.location.html_id(), self.lcp.get_state(), + system=self.system) - if not self.lcp.done: - event_info['failure'] = 'not_done' - self.system.track_function('reset_problem_fail', event_info) - return {'success': False, - 'error': "Refresh the page and make an attempt before resetting."} + event_info['new_state'] = self.lcp.get_state() + self.system.track_function('reset_problem', event_info) - self.lcp.do_reset() - if self.rerandomize in ["always", "onreset"]: - # reset random number generator seed (note the self.lcp.get_state() - # in next line) - self.lcp.seed = None - - self.lcp = LoncapaProblem(self.definition['data'], - self.location.html_id(), self.lcp.get_state(), - system=self.system) - - event_info['new_state'] = self.lcp.get_state() - self.system.track_function('reset_problem', event_info) - - return {'html': self.get_problem_html(encapsulate=False)} + return {'html': self.get_problem_html(encapsulate=False)} class CapaDescriptor(RawDescriptor): diff --git a/common/lib/xmodule/xmodule/js/src/selfassessment/display.coffee b/common/lib/xmodule/xmodule/js/src/selfassessment/display.coffee index 8de2043e3b..aabe0cc0e5 100644 --- a/common/lib/xmodule/xmodule/js/src/selfassessment/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/selfassessment/display.coffee @@ -1,84 +1,21 @@ -class @Problem +show: => + Logger.log 'sa_show', problem: @id + $.postWithPrefix "#{@url}/sa_show", (response) => + answers = response.answers + $.each answers, (key, value) => + if $.isArray(value) + for choice in value + @$("label[for='input_#{key}_#{choice}']").attr correct_answer: 'true' + else + answer = @$("#answer_#{key}, #solution_#{key}") + answer.html(value) + Collapsible.setCollapsibles(answer) - constructor: (element) -> - @el = $(element).find('.problems-wrapper') - @id = @el.data('problem-id') - @element_id = @el.attr('id') - @url = @el.data('url') - @render() + @$('.show').val 'Hide Answer' + @el.addClass 'showed' - $: (selector) -> - $(selector, @el) - - bind: => - problem_prefix = @element_id.replace(/sa_/,'') - @inputs = @$("[id^=input_#{problem_prefix}_]") - - @$('section.action input.show').click @show - @$('section.action input.save').click @save - - render: (content) -> - if content - @el.html(content) - JavascriptLoader.executeModuleScripts @el, () => - @setupInputTypes() - @bind() - else - $.postWithPrefix "#{@url}/sa_get", (response) => - @el.html(response.html) - JavascriptLoader.executeModuleScripts @el, () => - @setupInputTypes() - @bind() - - - # TODO add hooks for problem types here by inspecting response.html and doing - # stuff if a div w a class is found - - show: => - Logger.log 'sa_show', problem: @id - $.postWithPrefix "#{@url}/sa_show", (response) => - answers = response.answers - $.each answers, (key, value) => - if $.isArray(value) - for choice in value - @$("label[for='input_#{key}_#{choice}']").attr correct_answer: 'true' - else - answer = @$("#answer_#{key}, #solution_#{key}") - answer.html(value) - Collapsible.setCollapsibles(answer) - - @$('.show').val 'Hide Answer' - @el.addClass 'showed' - - save: => - Logger.log 'problem_save', @answers - $.postWithPrefix "#{@url}/problem_save", @answers, (response) => - if response.success - saveMessage = "Your answers have been saved but not graded. Hit 'Check' to grade them." - @gentle_alert saveMessage - @updateProgress response - - inputtypeShowAnswerMethods: - choicegroup: (element, display, answers) => - element = $(element) - - element.find('input').attr('disabled', 'disabled') - - input_id = element.attr('id').replace(/inputtype_/,'') - answer = answers[input_id] - for choice in answer - element.find("label[for='input_#{input_id}_#{choice}']").addClass 'choicegroup_correct' - - javascriptinput: (element, display, answers) => - answer_id = $(element).attr('id').split("_")[1...].join("_") - answer = JSON.parse(answers[answer_id]) - display.showAnswer(answer) - - inputtypeHideAnswerMethods: - choicegroup: (element, display) => - element = $(element) - element.find('input').attr('disabled', null) - element.find('label').removeClass('choicegroup_correct') - - javascriptinput: (element, display) => - display.hideAnswer() +save: => + Logger.log 'sa_save', @answers + $.postWithPrefix "#{@url}/sa_save", @answers, (response) => + if response.success + @$('p.rubric').replace(response.rubric) diff --git a/common/lib/xmodule/xmodule/self_assessment_module.py b/common/lib/xmodule/xmodule/self_assessment_module.py index 9ed088d406..41ac6a4f7b 100644 --- a/common/lib/xmodule/xmodule/self_assessment_module.py +++ b/common/lib/xmodule/xmodule/self_assessment_module.py @@ -19,12 +19,12 @@ from xmodule.contentstore.content import XASSET_SRCREF_PREFIX, StaticContent log = logging.getLogger("mitx.courseware") -problem_form=('
') +problem_form=('') -rubric_form=('') + 'Incorrect') def only_one(lst, default="", process=lambda x: x): """ @@ -46,7 +46,7 @@ class SelfAssessmentModule(XModule): resource_string(__name__, 'js/src/selfassessment/display.coffee') ] } - js_module_name = "SelfAssessmentModule" + js_module_name = "SelfAssessment" def get_html(self): # cdodge: perform link substitutions for any references to course static content (e.g. images) @@ -71,17 +71,18 @@ class SelfAssessmentModule(XModule): self.html = self.problem def handle_ajax(self, dispatch, get): - ''' - This is called by courseware.module_render, to handle an AJAX call. - "get" is request.POST. + ''' + This is called by courseware.module_render, to handle an AJAX call. + "get" is request.POST. + + Returns a json dictionary: + { 'progress_changed' : True/False, + 'progress' : 'none'/'in_progress'/'done', +