diff --git a/common/lib/capa/capa/responsetypes.py b/common/lib/capa/capa/responsetypes.py index 273b1a3f8f..d1b58e53a9 100644 --- a/common/lib/capa/capa/responsetypes.py +++ b/common/lib/capa/capa/responsetypes.py @@ -8,6 +8,7 @@ Used by capa_problem.py ''' # standard library imports +import cgi import inspect import json import logging @@ -725,7 +726,8 @@ class NumericalResponse(LoncapaResponse): # I think this is just pyparsing.ParseException, calc.UndefinedVariable: # But we'd need to confirm except: - raise StudentInputError('Invalid input -- please use a number only') + raise StudentInputError("Invalid input: could not parse '%s' as a number" %\ + cgi.escape(student_answer)) if correct: return CorrectMap(self.answer_id, 'correct') @@ -1517,11 +1519,12 @@ class FormulaResponse(LoncapaResponse): cs=self.case_sensitive) except UndefinedVariable as uv: log.debug('formularesponse: undefined variable in given=%s' % given) - raise StudentInputError(uv.message + " not permitted in answer") + raise StudentInputError("Invalid input: " + uv.message + " not permitted in answer") except Exception as err: #traceback.print_exc() log.debug('formularesponse: error %s in formula' % err) - raise StudentInputError("Error in formula") + raise StudentInputError("Invalid input: Could not parse '%s' as a formula" %\ + cgi.escape(given)) if numpy.isnan(student_result) or numpy.isinf(student_result): return "incorrect" if not compare_with_tolerance(student_result, instructor_result, self.tolerance): diff --git a/common/lib/xmodule/xmodule/js/src/capa/display.coffee b/common/lib/xmodule/xmodule/js/src/capa/display.coffee index ea5d939356..0ea6cffb58 100644 --- a/common/lib/xmodule/xmodule/js/src/capa/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/capa/display.coffee @@ -192,8 +192,11 @@ class @Problem if file_not_selected errors.push 'You did not select any files to submit' - if errors.length > 0 - alert errors.join("\n") + error_html = '' + @gentle_alert error_html abort_submission = file_too_large or file_not_selected or unallowed_file_submitted or required_files_not_submitted @@ -208,7 +211,7 @@ class @Problem @render(response.contents) @updateProgress response else - alert(response.success) + @gentle_alert response.success if not abort_submission $.ajaxWithPrefix("#{@url}/problem_check", settings) @@ -220,8 +223,10 @@ class @Problem when 'incorrect', 'correct' @render(response.contents) @updateProgress response + if @el.hasClass 'showed' + @el.removeClass 'showed' else - alert(response.success) + @gentle_alert response.success reset: => Logger.log 'problem_reset', @answers @@ -253,15 +258,19 @@ class @Problem @el.removeClass 'showed' @$('.show').val 'Show Answer' + gentle_alert: (msg) => + if @el.find('.capa_alert').length + @el.find('.capa_alert').remove() + alert_elem = "
" + msg + "
" + @el.find('.action').after(alert_elem) + @el.find('.capa_alert').animate(opacity: 0, 500).animate(opacity: 1, 500) + save: => Logger.log 'problem_save', @answers $.postWithPrefix "#{@url}/problem_save", @answers, (response) => if response.success - if @el.find('.save_message').length - @el.find('.save_message').animate(opacity: 0, 500).animate(opacity: 1, 500) - else - saveMessage = "
Your answers have been saved but not graded. Hit 'Check' to grade them.
" - @el.find('.action').after(saveMessage) + saveMessage = "Your answers have been saved but not graded. Hit 'Check' to grade them." + @gentle_alert saveMessage @updateProgress response refreshMath: (event, element) => diff --git a/common/lib/xmodule/xmodule/js/src/sequence/display.coffee b/common/lib/xmodule/xmodule/js/src/sequence/display.coffee index 35a33a9ea1..ab337d9b7e 100644 --- a/common/lib/xmodule/xmodule/js/src/sequence/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/sequence/display.coffee @@ -2,6 +2,7 @@ class @Sequence constructor: (element) -> @el = $(element).find('.sequence') @contents = @$('.seq_contents') + @num_contents = @contents.length @id = @el.data('id') @modx_url = @el.data('course_modx_root') @initProgress() @@ -90,18 +91,28 @@ class @Sequence @toggleArrows() @hookUpProgressEvent() + sequence_links = @$('#seq_content a.seqnav') + sequence_links.click @goto + goto: (event) => event.preventDefault() - new_position = $(event.target).data('element') - Logger.log "seq_goto", old: @position, new: new_position, id: @id - - # On Sequence chage, destroy any existing polling thread - # for queued submissions, see ../capa/display.coffee - if window.queuePollerID - window.clearTimeout(window.queuePollerID) - delete window.queuePollerID + if $(event.target).hasClass 'seqnav' # Links from courseware ... + new_position = $(event.target).attr('href') + else # Tab links generated by backend template + new_position = $(event.target).data('element') - @render new_position + if (1 <= new_position) and (new_position <= @num_contents) + Logger.log "seq_goto", old: @position, new: new_position, id: @id + + # On Sequence chage, destroy any existing polling thread + # for queued submissions, see ../capa/display.coffee + if window.queuePollerID + window.clearTimeout(window.queuePollerID) + delete window.queuePollerID + + @render new_position + else + alert 'Sequence error! Cannot navigate to tab ' + new_position + 'in the current SequenceModule. Please contact the course staff.' next: (event) => event.preventDefault()