Linked answer boxes in the HTML question type

One of the greatest features of the HTML question type is the ability to have answer boxes 'chained' together so that a student's answers can effect the grading of the whole question. An example of this is error carried forward marks or grading calculations students do on data that they have collected.
This example is of an error carried forward question, the student is asked to differentiate a polynomial for the first part and then asked to evaluate the derivative at a point. Getting the derivative correct awards 3/4 of the marks and evaluating it at the point awards 1/4. If the student doesn't calculate the derivative correctly BUT correctly evaluates their expression at the point then 1/4 of the marks are awarded.
This is what the question looks like when first loaded:
In the question designer, under 'question text' there is only 1 HTML question box. Under 'algorithm' there is:
# MapleTA $a = rint(2,6); $b = rint(2,6); $c = rint(4);
In the HTML question box, the 'Question HTML' is:
<div> <form method="GET" action="" onSubmit="" style="margin:0; padding:0; width:500px;"> <p> \( y(x) = $a x^3 + $b x^2 \) Calculate \( \dfrac{dy}{dx} \) </p> <p> \( \dfrac{dy}{dx} =\) <input type="text" name="BoxA" id="BoxA" style="width:100px; display:inline;"/> </p> <p> Evaluate \( \dfrac{dy}{dx} \) at \( x = $c \) </p> <p> \( y'($c) =\) <input type="text" name="BoxB" id="BoxB" style="width:100px; display:inline;"/> </p> </form> </div>
The 'Question Javascript' is:
function initialize(interactiveMode){ /*Called when the question is being initialized. interactiveMode: if it is true, interaction is allowed on question. */ /*Your code starts from here:*/ }; function setFeedback(response, answer){ /* Phil's witchcraft. Gets answer boxes out in order into an array*/ if (response == "No answer") return; response = JSON.parse(response); jQuery("input[type='text']").each(function(i,e) { jQuery(e).val(response[i]); var parenturl = window.parent.location.pathname; /* Disables answer boxes in the gradebook */ if (parenturl.indexOf("gradeProctoredTest") !== 1  parenturl.indexOf("gradebook") !== 1) { jQuery(e).prop("readonly", true); } });
}; function getResponse(){ /*called when grade button is clicked, to retrieve back student's response.*/ /*Your code starts from here:*/ var answer = []; jQuery("input[type='text']").each(function(i,e) { answer.push(jQuery(e).val()); }); return JSON.stringify(answer); };
And the 'Grading code' is:
# Maple A :=parse( $RESPONSE[1] ): B :=parse( $RESPONSE[2] ): DiffAns := diff($a*x^3 + $b*x^2, x): DiffMark := 0: if simplify(DiffAns  A) = 0 then DiffMark := 1 else DiffMark := 0 end if: EvalAns := eval(A, x=$c): EvalMark := 0: if simplify(EvalAns  B) = 0 then EvalMark := 1 else EvalMark := 0 end if: TotMark := (3*DiffMark + EvalMark)/4: evalf(TotMark);
This is only a primitive version of a linked answer box question and there are a few formatting issues and bugs with the code, but the general framework of linking answer boxes is there.
The purpose of each part of code is detailed below:
MapleTA algorithm: Generate random numbers to be used in the question.
HTML: Display the question and the various answer boxes.
Javascript: Takes input from HTML answer boxes when "Grade" is pressed and sends them to Maple Grading Code.
Maple Grading Code: Takes inputs from any number of the answer boxes and can use them to return the grade for the question.

Here is a template for creating your own linked answer box question

If you have a list of answers as a variable in the algorithm section of your question. e.g.
$TA=["2*Pi",5,"x/y"];
You can put the following grading code to award points based on how many input boxes have the correct answer.
TA:=$TA: RESP:=$RESPONSE: grade := 0.0: for i to nops(TA) do if TA[i] = parse(RESP[i]) then grade := grade+1.0/nops(TA); end if end do: grade;
The order of answer boxes in the html must be the same as the order in $TA. With this code each box is worth 1/n, where n is the number of answer boxes.