diff --git a/djangoapps/courseware/capa/inputtypes.py b/djangoapps/courseware/capa/inputtypes.py index bb3ecd209f..ac0c502f03 100644 --- a/djangoapps/courseware/capa/inputtypes.py +++ b/djangoapps/courseware/capa/inputtypes.py @@ -13,6 +13,13 @@ These are matched by *.html files templates/*.html which are mako templates with ''' +# TODO: rename "state" to "status" for all below +# status is currently the answer for the problem ID for the input element, +# but it will turn into a dict containing both the answer and any associated message for the problem ID for the input element. + +import re + +from django.conf import settings from lxml.etree import Element from lxml import etree @@ -22,7 +29,7 @@ from mitxmako.shortcuts import render_to_string #----------------------------------------------------------------------------- #takes the xml tree as 'element', the student's previous answer as 'value', and the graded status as 'state' -def choicegroup(element, value, state): +def choicegroup(element, value, state, msg=""): ''' Radio button inputs: multiple choice or true/false @@ -43,8 +50,8 @@ def choicegroup(element, value, state): context={'id':eid, 'value':value, 'state':state, 'type':type, 'choices':choices} html=render_to_string("choicegroup.html", context) return etree.XML(html) - -def textline(element, value, state): + +def textline(element, value, state, msg=""): eid=element.get('id') count = int(eid.split('_')[-2])-1 # HACK size = element.get('size') @@ -52,6 +59,43 @@ def textline(element, value, state): html=render_to_string("textinput.html", context) return etree.XML(html) +#----------------------------------------------------------------------------- +# TODO: Make a wrapper for +# TODO: Make an AJAX loop to confirm equation is okay in real-time as user types +def js_textline(element, value, state, msg=""): + ''' + textline is used for simple one-line inputs, like formularesponse and symbolicresponse. + ''' + eid=element.get('id') + count = int(eid.split('_')[-2])-1 # HACK + size = element.get('size') + dojs = element.get('dojs') # dojs is used for client-side javascript display & return + # when dojs=='math', a `{::}` + # and a hidden textarea with id=input_eid_fromjs will be output + context = {'id':eid, 'value':value, 'state':state, 'count':count, 'size': size, + 'dojs':dojs, + 'msg':msg, + } + html=render_to_string("textinput.html", context) + return etree.XML(html) + +#----------------------------------------------------------------------------- +## TODO: Make a wrapper for +def textbox(element, value, state, msg=''): + ''' + The textbox is used for code input. The message is the return HTML string from + evaluating the code, eg error messages, and output from the code tests. + + TODO: make this use rows and cols attribs, not size + ''' + eid=element.get('id') + count = int(eid.split('_')[-2])-1 # HACK + size = element.get('size') + context = {'id':eid, 'value':value, 'state':state, 'count':count, 'size': size, 'msg':msg} + html=render_to_string("textbox.html", context) + return etree.XML(html) + +#----------------------------------------------------------------------------- def schematic(element, value, state): eid = element.get('id') height = element.get('height') @@ -74,4 +118,89 @@ def schematic(element, value, state): html=render_to_string("schematicinput.html", context) return etree.XML(html) +#----------------------------------------------------------------------------- +### TODO: Move out of inputtypes +def math(element, value, state, msg=''): + ''' + This is not really an input type. It is a convention from Lon-CAPA, used for + displaying a math equation. + + Examples: + + $\displaystyle U(r)=4 U_0 + $r_0$ + + We convert these to [mathjax]...[/mathjax] and [mathjaxinline]...[/mathjaxinline] + + TODO: use shorter tags (but this will require converting problem XML files!) + ''' + mathstr = element.text[1:-1] + if '\\displaystyle' in mathstr: + isinline = False + mathstr = mathstr.replace('\\displaystyle','') + else: + isinline = True + + html=render_to_string("mathstring.html",{'mathstr':mathstr,'isinline':isinline,'tail':element.tail}) + xhtml = etree.XML(html) + # xhtml.tail = element.tail # don't forget to include the tail! + return xhtml + +#----------------------------------------------------------------------------- + +def solution(element, value, state, msg=''): + ''' + This is not really an input type. It is just a ... which is given an ID, + that is used for displaying an extended answer (a problem "solution") after "show answers" + is pressed. Note that the solution content is NOT sent with the HTML. It is obtained + by a JSON call. + ''' + eid=element.get('id') + size = element.get('size') + context = {'id':eid, + 'value':value, + 'state':state, + 'size': size, + 'msg':msg, + } + html=render_to_string("solutionspan.html", context) + return etree.XML(html) + +#----------------------------------------------------------------------------- + +def imageinput(element, value, status, msg=''): + ''' + Clickable image as an input field. Element should specify the image source, height, and width, eg + + + TODO: showanswer for imageimput does not work yet - need javascript to put rectangle over acceptable area of image. + + ''' + eid = element.get('id') + src = element.get('src') + height = element.get('height') + width = element.get('width') + + # if value is of the form [x,y] then parse it and send along coordinates of previous answer + m = re.match('\[([0-9]+),([0-9]+)]',value.strip().replace(' ','')) + if m: + (gx,gy) = [int(x)-15 for x in m.groups()] + else: + (gx,gy) = (0,0) + + context = { + 'id':eid, + 'value':value, + 'height': height, + 'width' : width, + 'src':src, + 'gx':gx, + 'gy':gy, + 'state' : status, # to change + 'msg': msg, # to change + } + if settings.DEBUG: + print '[courseware.capa.inputtypes.imageinput] context=',context + html=render_to_string("imageinput.html", context) + return etree.XML(html)