| Printed |
Page .
Modify printResults() so users can view their answers and embed the |
answer data within an HTML form to send the waiting server.
Adding the Key to The Constructor
Once the user's answers make it back to the server, who knows which
questions go with which answers? You'll have to add some type of key
on the server side that references each question. So, let's start by
adding a key (an object property) to the question constructor in
questions.js. Just change this:
function question(answer, support, question, a, b, c, d) {
this.answer = answer;
this.support = support;
this.question = question;
this.a = a;
this.b = b;
this.c = c;
this.d = d;
return this;
}
to:
function question(key, question, a, b, c, d) {
this.key = key;
this.question = question;
this.a = a;
this.b = b;
this.c = c;
this.d = d;
return this;
}
Variable key has been added. So has object property this.key. These
two will enable you to reference each question after the test results
reach the server side. Even though the questions are shuffled, each
key stays with its question. Notice that answers, support,
this.answers, and this.support have been removed. Since there is no
test grading, these aren't necessary.
Modifying Each Question
In order to match the structure and expectations of the new
constructor, we need to change what is passed in with every call to a
question in the units array. In other words, pass in a key, and don't
pass in the supporting text or an answer. For the key, try to keep it
simple. Use 1 for the first, 2, for the second, and so on. Just put
each key as the first argument passed to each question call. The
first two would look like this.
new question(1, "Select the method added in JavaScript 1.2:",
"concat()", "link()", "split()", "join()"),
new question(2, "Select the method not supported by JavaScript 1.1:",
"sort()", "slice()", "split()", "reverse()"),
Notice also that the answer (e.g., a, b, etc.) has been removed. So
has the supporting text to display after the test grading.
Binding the Key to Each Chosen Answer
Now that we've added a key for each question, we need to be able to
"bind" it to whatever answer the user picks. This happens in function
buildQuestion() in administer.html. Just change lines 46-49 from:
makeButton("a", units[qIdx].a) +
makeButton("b", units[qIdx].b) +
makeButton("c", units[qIdx].c) +
makeButton("d", units[qIdx].d) +
to:
makeButton("a", units[qIdx].key + ":" + units[qIdx].a) +
makeButton("b", units[qIdx].key + ":" + units[qIdx].b) +
makeButton("c", units[qIdx].key + ":" + units[qIdx].c) +
makeButton("d", units[qIdx].key + ":" + units[qIdx].d) +
This creates a key:answer string that is passed to makeButton().
When the user chooses answer a to the question assigned a key of 1,
the value passed will be 1:a. Choosing answer b produces 1:b, and so
on.
Removing gradeTest() and Modifying buildQuestion()
Since the answers and explanations no longer exist, there is no
reason to grade the test or display any results. That means you can
get rid of function gradeTest(). Just delete lines 74 - 79 in
administer.html. This also means that you can get rid of the call to
gradeTest() in buildQuestion() at line 43. Actually, you'll want to
replace it with a call to printResults() so the user can see his or
her answers and the answers can be embedded in an HTML form.
Lines 42-45 go from this:
if (qIdx == howMany) {
gradeTest();
return;
}
To this:
if (qIdx == howMany) {
printResults();
return;
}
Modifying printResults()
All that remains is to print an HTML form of hidden fields, each
containing a reference to a question and its answer. The user can
then submit this form a server-side script. Line 90 in
administer.html currently looks like this:
'<BR><BR><FONT SIZE=4>Here is how you scored: </FONT><BR><BR>';
Change it to this:
'<BR><BR><FONT SIZE=4>Here are your answers: </FONT><BR><BR>' +
'<FORM ACTION="your_server_script_URL" METHOD=POST>';
The next few lines build the HTML form of hidden fields, one question
key and answer each. Replace lines 92-105 with the following:
var qSplit = keeper[i].split(":");
results += '<INPUT TYPE HIDDEN NAME="q' + qSplit[0] + '" VALUE="'
+ qSplit[1] + '"><B><I><FONT COLOR=GREEN>You chose '
+ qSplit[1] + '</I></B></FONT><BR><BR><BR>';
As printResults() iterates through the keepers array, it needs to
separate the key:answer string created after the user answers each
question. The reason: Each hidden form field has a NAME attribute and
a VALUE attribute. NAME will be assigned according to the value of
the question key, and VALUE will be assigned the user's answer. That
sets things up so a server-side script can grade the results.
Variable qSplit is set to an array created by the split() method.
Each element of keepers is a string delimited by a colon (:). So,
qSplit[0] represents the key; qSplit[1] represents the answer. These
are assigned appropriately to the NAME and VALUE attributes of each
hidden form field. For example, if a user answered d to a question
with keys of 1-3, respectively, the corresponding hidden fields would
look like this:
<INPUT TYPE=HIDDEN NAME="q1" VALUE="d">
<INPUT TYPE=HIDDEN NAME="q2" VALUE="d">
<INPUT TYPE=HIDDEN NAME="q3" VALUE="d">
To close out the form change line 117 to this:
results += '<INPUT TYPE=SUBMIT VALUE="Submit">
</FORM></BODY></HTML>';
In spite of all these changes, printResults() still displays the
questions, four choices, and the user's answers. The test isn't
graded, however. All the user has to do is choose Submit to send the
answers off for a grading.
|
Anonymous |
|