root/trunk/max-javahotpot-tutorial/tutorial/eng/jquiz2.htm @ 35

Revision 35, 49.8 KB (checked in by max, 23 months ago)

mario.izquierdo
max-javahotpot-tutorial (3.1.max1)

  • New release
Line 
1<?xml version="1.0"?>
2       <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "xhtml11.dtd">
3       <html xmlns="http://www.w3.org/1999/xhtml"
4             xml:lang="en"><head><meta name="author" content="Created with Hot Potatoes by Half-Baked Software, registered to Martin Holmes."></meta><meta name="keywords" content="Hot Potatoes, Hot Potatoes, Half-Baked Software, Windows, University of Victoria"></meta>
5
6<link rel="schema.DC" href="http://purl.org/dc/elements/1.1/" />
7<meta name="DC:Creator" content="Martin Holmes" />
8<meta name="DC:Title" content="Example JQuiz exercise showing all four question types" />
9
10
11<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> 
12
13<title>
14Example JQuiz exercise showing all four question types
15</title>
16
17<!-- Made with executable version 6.0 Release 1 Build 11 -->
18
19<!-- The following insertion allows you to add your own code directly to this head tag from the configuration screen -->
20
21
22
23<style type="text/css">
24
25
26/* This is the CSS stylesheet used in the exercise. */
27/* Elements in square brackets are replaced by data based on configuration settings when the exercise is built. */
28
29
30body{
31        font-family: Geneva,Arial;
32        background-color: #ffffff;
33        color: #000000;
34 
35        margin-right: 5%;
36        margin-left: 5%;
37        font-size: small;
38}
39
40p{
41        text-align: left;
42        margin: 0px;
43        font-size: small;
44}
45
46div,span,td{
47        font-size: small;
48        color: #000000;
49}
50
51.RTLText{
52        text-align: right;
53        font-size: 150%;
54        direction: rtl;
55        font-family: "Simplified Arabic", "Traditional Arabic", "Times New Roman", Geneva,Arial;
56}
57
58.CentredRTLText{
59        text-align: center;
60        font-size: 150%;
61        direction: rtl;
62        font-family: "Simplified Arabic", "Traditional Arabic", "Times New Roman", Geneva,Arial;
63}
64
65button p.RTLText{
66        text-align: center;
67}
68
69.RTLGapBox{
70        text-align: right;
71        font-size: 150%;
72        direction: rtl;
73        font-family: "Times New Roman", Geneva,Arial;
74}
75
76.Guess{
77        font-weight: bold;
78}
79
80.CorrectAnswer{
81        font-weight: bold;
82}
83
84div.Titles{
85        padding: 10px;
86        text-align: center;
87        color: #000000;
88}
89
90button{
91        display: inline;
92}
93
94.ExerciseTitle{
95        font-size: large;
96        color: #000000;
97}
98
99.ExerciseSubtitle{
100        color: #000000;
101}
102
103div#Timer{
104        padding: 6px;
105        margin-left: auto;
106        margin-right: auto;
107        text-align: center;
108}
109
110span#TimerText{
111        padding: 6px;
112        border-width: 1px;
113        border-style: solid;
114        font-weight: bold;
115        display: none;
116}
117
118span.Instructions{
119
120}
121
122div.ExerciseText{
123
124}
125
126.FeedbackText{
127
128}
129
130span.LeftItem{
131        font-size: small;
132        color: #000000;
133}
134
135span.RightItem{
136        font-weight: bold;
137        font-size: small;
138        color: #000000;
139}
140
141span.CorrectMark{
142
143}
144
145div.Feedback {
146        background-color: #ffffff;
147        left: 33%;
148        width: 34%;
149        top: 33%;
150        z-index: 1;
151        border-style: solid;
152        border-width: 1px;
153        padding: 5px;
154        text-align: center;
155        color: #000000;
156        position: absolute;
157        display: none;
158        font-size: small;
159}
160
161
162
163
164div.ExerciseDiv{
165        color: #000000;
166}
167
168/* JMatch flashcard styles */
169table.FlashcardTable{
170        background-color: transparent;
171        color: #000000;
172        border-color: #000000;
173        margin-left: 5%;
174        margin-right: 5%;
175        margin-top: 2em;
176        margin-bottom: 2em;
177        width: 90%;
178        position: relative;
179        align: center;
180        padding: 0px;
181}
182
183table.FlashcardTable tr{
184        border-style: none;
185        margin: 0px;
186        padding: 0px;
187        background-color: #dddddd;
188}
189
190table.FlashcardTable td.Showing{
191        font-size: large;
192        text-align: center;
193        width: 50%;
194        display: table-cell;
195        padding: 2em;
196        margin: 0px;
197        border-style: solid;
198        border-width: 1px;
199        color: #000000;
200        background-color: #dddddd;
201}
202
203table.FlashcardTable td.Hidden{
204        display: none;
205}
206
207/* JMix styles */
208div#SegmentDiv{
209        margin-top: 2em;
210        margin-bottom: 2em;
211        text-align: center;
212}
213
214a.ExSegment{
215        font-size: medium;
216        font-weight: bold;
217        text-decoration: none;
218        color: #000000;
219}
220
221span.RemainingWordList{
222        font-style: italic;
223}
224
225div.DropLine {
226        position: absolute;
227        text-align: center;
228        border-bottom-style: solid;
229        border-bottom-width: 1px;
230        border-bottom-color: #000000;
231        width: 80%;
232}
233
234/* JCloze styles */
235
236input{
237        font-family: Geneva,Arial;
238        font-size: larger;
239}
240
241div.ClozeWordList{
242        text-align: center;
243        font-weight: bold;
244}
245
246div.ClozeBody{
247        text-align: left;
248        margin-top: 2em;
249        margin-bottom: 2em;
250        line-height: 2.0
251}
252
253span.GapSpan{
254        font-weight: bold;
255}
256
257/* JCross styles */
258
259table.CrosswordGrid{
260        margin: auto auto 1em auto;
261        border-collapse: collapse;
262        padding: 0px;
263}
264
265table.CrosswordGrid td{
266        width: 1.5em;
267        height: 1.5em;
268        text-align: center;
269        vertical-align: middle;
270        font-size: large;
271        padding: 0px;
272        margin: 0px;
273        border-style: solid;
274        border-width: 1px;
275        border-color: #000000;
276}
277
278table.CrosswordGrid td.BlankCell{
279        background-color: #000000;
280        color: #000000;
281}
282
283table.CrosswordGrid td.LetterOnlyCell{
284        text-align: center;
285        vertical-align: middle;
286        background-color: #ffffff;
287        color: #000000;
288        font-weight: bold;
289}
290
291table.CrosswordGrid td.NumLetterCell{
292        text-align: left;
293        vertical-align: top;
294        background-color: #ffffff;
295        color: #000000;
296        padding: 1px;
297        font-weight: bold;
298}
299
300.NumLetterCellText{
301        cursor: pointer;
302}
303
304.GridNum{
305        vertical-align: super;
306        font-size: x-small;
307        font-weight: bold;
308        text-decoration: none;
309        color: #000000;
310}
311
312table#Clues{
313        margin: auto;
314        vertical-align: top;
315}
316
317table#Clues td{
318        vertical-align: top;
319}
320
321table.ClueList{
322  margin: auto;
323}
324
325td.ClueNum{
326        text-align: right;
327        font-weight: bold;
328        vertical-align: top;
329}
330
331td.Clue{
332        text-align: left;
333}
334
335div#ClueEntry{
336        text-align: left;
337        margin-bottom: 1em;
338}
339
340/* Keypad styles */
341
342div.Keypad{
343        text-align: center;
344}
345
346div.Keypad button{
347        font-family: Geneva,Arial;
348        font-size: 120%;
349        background-color: #ffffff;
350        color: #000000;
351        width: 2em;
352}
353
354/* JQuiz styles */
355
356div.QuestionNavigation{
357        text-align: center;
358}
359
360.QNum{
361        margin: 0em 1em 0.5em 1em;
362        font-weight: bold;
363        vertical-align: middle;
364}
365
366textarea{
367        font-family: Geneva,Arial;
368        font-size: larger;
369}
370
371.QuestionText{
372
373}
374
375.Answer{
376        font-size: 120%;
377        letter-spacing: 0.1em;
378}
379
380.Highlight{
381        color: #000000;
382        background-color: #ffff00;
383        font-weight: bold;
384        font-size: 120%;
385}
386
387ol.QuizQuestions{
388        text-align: left;
389        list-style-type: none;
390}
391
392li.QuizQuestion{
393        padding: 1em;
394        border-style: solid;
395        border-width: 0px 0px 1px 0px;
396}
397
398ol.MCAnswers{
399        text-align: left;
400        list-style-type: upper-alpha;
401        padding: 1em;
402}
403
404ol.MCAnswers li{
405        margin-bottom: 1em;
406}
407
408ol.MSelAnswers{
409        text-align: left;
410        list-style-type: lower-alpha;
411        padding: 1em;
412}
413
414div.ShortAnswer{
415        padding: 1em;
416}
417
418div.StdDiv{
419        background-color: #dddddd;
420        text-align: center;
421        font-size: small;
422        color: #000000;
423        padding: 8px;
424        border-style: solid;
425        border-width: 1px 1px 1px 1px;
426        border-color: #000000;
427        margin: 1px;
428}
429
430.FuncButton {
431        text-align: center;
432        border-style: solid;
433
434        border-left-color: #eeeeee;
435        border-top-color: #eeeeee;
436        border-right-color: #6e6e6e;
437        border-bottom-color: #6e6e6e;
438        color: #000000;
439        background-color: #dddddd;
440
441        border-width: 2px;
442        padding: 3px 6px 3px 6px;
443        cursor: pointer;
444}
445
446.FuncButtonUp {
447        color: #dddddd;
448        text-align: center;
449        border-style: solid;
450
451        border-left-color: #eeeeee;
452        border-top-color: #eeeeee;
453        border-right-color: #6e6e6e;
454        border-bottom-color: #6e6e6e;
455
456        background-color: #000000;
457        color: #dddddd;
458        border-width: 2px;
459        padding: 3px 6px 3px 6px;
460        cursor: pointer;
461}
462
463.FuncButtonDown {
464        color: #dddddd;
465        text-align: center;
466        border-style: solid;
467
468        border-left-color: #6e6e6e;
469        border-top-color: #6e6e6e;
470        border-right-color: #eeeeee;
471        border-bottom-color: #eeeeee;
472        background-color: #000000;
473        color: #dddddd;
474
475        border-width: 2px;
476        padding: 3px 6px 3px 6px;
477        cursor: pointer;
478}
479
480/*BeginNavBarStyle*/
481
482div.NavButtonBar{
483        background-color: #999999;
484        text-align: center;
485        margin: 2px 0px 2px 0px;
486        clear: both;
487        font-size: small;
488}
489
490.NavButton {
491        border-style: solid;
492       
493        border-left-color: #cccccc;
494        border-top-color: #cccccc;
495        border-right-color: #4c4c4c;
496        border-bottom-color: #4c4c4c;
497        background-color: #999999;
498        color: #000000;
499
500        border-width: 2px;
501        cursor: pointer;       
502}
503
504.NavButtonUp {
505        border-style: solid;
506
507        border-left-color: #cccccc;
508        border-top-color: #cccccc;
509        border-right-color: #4c4c4c;
510        border-bottom-color: #4c4c4c;
511        color: #999999;
512        background-color: #000000;
513
514        border-width: 2px;
515        cursor: pointer;       
516}
517
518.NavButtonDown {
519        border-style: solid;
520
521        border-left-color: #4c4c4c;
522        border-top-color: #4c4c4c;
523        border-right-color: #cccccc;
524        border-bottom-color: #cccccc;
525        color: #999999;
526        background-color: #000000;
527
528        border-width: 2px;
529        cursor: pointer;       
530}
531
532/*EndNavBarStyle*/
533
534a{
535        color: #0000cc;
536}
537
538a: visited{
539        color: #0000ff;
540}
541
542a:hover{
543        color: #0000cc;
544}
545
546div.CardStyle {
547        position: absolute;
548        font-family: Geneva,Arial;
549        font-size: small;
550        padding: 5px;
551        border-style: solid;
552        border-width: 1px;
553        color: #000000;
554        background-color: #dddddd;
555        left: -50px;
556        top: -50px;
557        overflow: visible;
558}
559
560.rtl{
561        text-align: right;
562        font-size: large;
563}
564
565
566</style>
567
568<script type="text/javascript">
569
570//<![CDATA[
571
572<!--
573
574
575function Client(){
576//if not a DOM browser, hopeless
577        this.min = false; if (document.getElementById){this.min = true;};
578
579        this.ua = navigator.userAgent;
580        this.name = navigator.appName;
581        this.ver = navigator.appVersion; 
582
583//Get data about the browser
584        this.mac = (this.ver.indexOf('Mac') != -1);
585        this.win = (this.ver.indexOf('Windows') != -1);
586
587//Look for Gecko
588        this.gecko = (this.ua.indexOf('Gecko') > 1);
589        if (this.gecko){
590                this.geckoVer = parseInt(this.ua.substring(this.ua.indexOf('Gecko')+6, this.ua.length));
591                if (this.geckoVer < 20020000){this.min = false;}
592        }
593       
594//Look for Firebird
595        this.firebird = (this.ua.indexOf('Firebird') > 1);
596       
597//Look for Safari
598        this.safari = (this.ua.indexOf('Safari') > 1);
599        if (this.safari){
600                this.gecko = false;
601        }
602       
603//Look for IE
604        this.ie = (this.ua.indexOf('MSIE') > 0);
605        if (this.ie){
606                this.ieVer = parseFloat(this.ua.substring(this.ua.indexOf('MSIE')+5, this.ua.length));
607                if (this.ieVer < 5.5){this.min = false;}
608        }
609       
610//Look for Opera
611        this.opera = (this.ua.indexOf('Opera') > 0);
612        if (this.opera){
613                this.operaVer = parseFloat(this.ua.substring(this.ua.indexOf('Opera')+6, this.ua.length));
614                if (this.operaVer < 7.04){this.min = false;}
615        }
616        if (this.min == false){
617                alert('Your browser may not be able to handle this page.');
618        }
619       
620//Special case for the horrible ie5mac
621        this.ie5mac = (this.ie&&this.mac&&(this.ieVer<6));
622}
623
624var C = new Client();
625
626//for (prop in C){
627//      alert(prop + ': ' + C[prop]);
628//}
629
630
631
632//CODE FOR HANDLING NAV BUTTONS AND FUNCTION BUTTONS
633
634//[strNavBarJS]
635function NavBtnOver(Btn){
636        if (Btn.className != 'NavButtonDown'){Btn.className = 'NavButtonUp';}
637}
638
639function NavBtnOut(Btn){
640        Btn.className = 'NavButton';
641}
642
643function NavBtnDown(Btn){
644        Btn.className = 'NavButtonDown';
645}
646//[/strNavBarJS]
647
648function FuncBtnOver(Btn){
649        if (Btn.className != 'FuncButtonDown'){Btn.className = 'FuncButtonUp';}
650}
651
652function FuncBtnOut(Btn){
653        Btn.className = 'FuncButton';
654}
655
656function FuncBtnDown(Btn){
657        Btn.className = 'FuncButtonDown';
658}
659
660function FocusAButton(){
661        if (document.getElementById('CheckButton1') != null){
662                document.getElementById('CheckButton1').focus();
663        }
664        else{
665                if (document.getElementById('CheckButton2') != null){
666                        document.getElementById('CheckButton2').focus();
667                }
668                else{
669                        document.getElementsByTagName('button')[0].focus();
670                }
671        }
672}
673
674
675
676
677//CODE FOR HANDLING DISPLAY OF POPUP FEEDBACK BOX
678
679var topZ = 1000;
680
681function ShowMessage(Feedback){
682        var Output = Feedback + '<br /><br />';
683        document.getElementById('FeedbackContent').innerHTML = Output;
684        var FDiv = document.getElementById('FeedbackDiv');
685        topZ++;
686        FDiv.style.zIndex = topZ;
687        FDiv.style.top = TopSettingWithScrollOffset(30) + 'px';
688//IE can't focus a hidden div; Moz needs to focus before display to avoid jumping
689        if (C.gecko){
690                document.getElementById('FeedbackOKButton').focus();
691        }
692        FDiv.style.display = 'block';
693
694        ShowElements(false, 'input');
695        ShowElements(false, 'select');
696
697        if (C.ie){
698                document.getElementById('FeedbackOKButton').focus();
699        }
700       
701//
702}
703
704function ShowElements(Show, TagName){
705//Special for IE bug -- hide all the form elements that will show through the popup
706        if (C.ie){
707                var Els = document.getElementsByTagName(TagName);
708                for (var i=0; i<Els.length; i++){
709                        if (Show == true){
710                                Els[i].style.display = 'inline';
711                        }
712                        else{
713                                Els[i].style.display = 'none';
714                        }
715                }
716        }
717}
718
719function HideFeedback(){
720        document.getElementById('FeedbackDiv').style.display = 'none';
721        ShowElements(true, 'input');
722        ShowElements(true, 'select');
723        if (Finished == true){
724                Finish();
725        }
726}
727
728
729//GENERAL UTILITY FUNCTIONS AND VARIABLES
730
731//PAGE DIMENSION FUNCTIONS
732function PageDim(){
733//Get the page width and height
734        this.W = 600;
735        this.H = 400;
736        this.W = document.getElementsByTagName('body')[0].clientWidth;
737        this.H = document.getElementsByTagName('body')[0].clientHeight;
738}
739
740var pg = null;
741
742function GetPageXY(El) {
743        var XY = {x: 0, y: 0};
744        while(El){
745                XY.x += El.offsetLeft;
746                XY.y += El.offsetTop;
747                El = El.offsetParent;
748        }
749        return XY;
750}
751
752function GetScrollTop(){
753        if (document.documentElement && document.documentElement.scrollTop){
754                return document.documentElement.scrollTop;
755        }
756        else{
757                if (document.body){
758                        return document.body.scrollTop;
759                }
760                else{
761                        return window.pageYOffset;
762                }
763        }
764}
765
766function GetViewportHeight(){
767        if (window.innerWidth){
768                return window.innerWidth;
769        }
770        else{
771                return document.getElementsByTagName('body')[0].clientHeight;
772        }
773}
774
775function TopSettingWithScrollOffset(TopPercent){
776        var T = Math.floor(GetViewportHeight() * (TopPercent/100));
777        return GetScrollTop() + T;
778}
779
780//CODE FOR AVOIDING LOSS OF DATA WHEN BACKSPACE KEY INVOKES history.back()
781var InTextBox = false;
782
783function SuppressBackspace(e){
784        if (InTextBox == true){return;}
785        if (C.ie) {
786                thisKey = window.event.keyCode;
787        }
788        else {
789                thisKey = e.keyCode;
790        }
791
792        var Suppress = false;
793
794        if (thisKey == 8) {
795                Suppress = true;
796        }
797
798        if (Suppress == true){
799                if (C.ie){
800                        window.event.returnValue = false;       
801                        window.event.cancelBubble = true;
802                }
803                else{
804                        e.preventDefault();
805                }
806        }
807}
808
809if (C.ie){
810        document.attachEvent('onkeydown',SuppressBackspace);
811        window.attachEvent('onkeydown',SuppressBackspace);
812}
813else{
814        window.addEventListener('keypress',SuppressBackspace,false);
815}
816
817function ReduceItems(InArray, ReduceToSize){
818        var ItemToDump=0;
819        var j=0;
820        while (InArray.length > ReduceToSize){
821                ItemToDump = Math.floor(InArray.length*Math.random());
822                InArray.splice(ItemToDump, 1);
823        }
824}
825
826function Shuffle(InArray){
827        Temp = new Array();
828        var Len = InArray.length;
829
830        var j = Len;
831
832        for (var i=0; i<Len; i++){
833                Temp[i] = InArray[i];
834        }
835
836        for (i=0; i<Len; i++){
837                Num = Math.floor(j  *  Math.random());
838                InArray[i] = Temp[Num];
839
840                for (var k=Num; k < j; k++) {
841                        Temp[k] = Temp[k+1];
842                }
843                j--;
844        }
845        return InArray;
846}
847
848function WriteToInstructions(Feedback) {
849        Feedback = '<span class="FeedbackText">' + Feedback + '</span>';
850        document.getElementById('InstructionsDiv').innerHTML = Feedback;
851
852}
853
854
855
856
857function EscapeDoubleQuotes(InString){
858        return InString.replace(/"/g, '&quot;')
859}
860
861function FocusAButton(){
862        if (document.getElementById('CheckButton1') != null){
863                document.getElementById('CheckButton1').focus();
864        }
865        else{
866                document.getElementsByTagName('button')[0].focus();
867        }
868}
869
870function TrimString(InString){
871        var x = 0;
872
873        if (InString.length != 0) {
874                while ((InString.charAt(InString.length - 1) == '\u0020') || (InString.charAt(InString.length - 1) == '\u000A') || (InString.charAt(InString.length - 1) == '\u000D')){
875                        InString = InString.substring(0, InString.length - 1)
876                }
877
878                while ((InString.charAt(0) == '\u0020') || (InString.charAt(0) == '\u000A') || (InString.charAt(0) == '\u000D')){
879                        InString = InString.substring(1, InString.length)
880                }
881
882                while (InString.indexOf('  ') != -1) {
883                        x = InString.indexOf('  ')
884                        InString = InString.substring(0, x) + InString.substring(x+1, InString.length)
885                 }
886
887                return InString;
888        }
889
890        else {
891                return '';
892        }
893}
894
895function FindLongest(InArray){
896        if (InArray.length < 1){return -1;}
897
898        var Longest = 0;
899        for (var i=1; i<InArray.length; i++){
900                if (InArray[i].length > InArray[Longest].length){
901                        Longest = i;
902                }
903        }
904        return Longest;
905}
906
907//UNICODE CHARACTER FUNCTIONS
908function IsCombiningDiacritic(CharNum){
909        var Result = (((CharNum >= 0x0300)&&(CharNum <= 0x370))||((CharNum >= 0x20d0)&&(CharNum <= 0x20ff)));
910        Result = Result || (((CharNum >= 0x3099)&&(CharNum <= 0x309a))||((CharNum >= 0xfe20)&&(CharNum <= 0xfe23)));
911        return Result;
912}
913
914function IsCJK(CharNum){
915        return ((CharNum >= 0x3000)&&(CharNum < 0xd800));
916}
917
918//SETUP FUNCTIONS
919//BROWSER WILL REFILL TEXT BOXES FROM CACHE IF NOT PREVENTED
920function ClearTextBoxes(){
921        var NList = document.getElementsByTagName('input');
922        for (var i=0; i<NList.length; i++){
923                if (NList[i].id.indexOf('Guess') > -1){
924                        NList[i].value = '';
925                }
926                if (NList[i].id.indexOf('Chk') > -1){
927                        NList[i].checked = '';
928                }
929        }
930}
931
932//EXTENSION TO ARRAY OBJECT
933function Array_IndexOf(Input){
934        var Result = -1;
935        for (var i=0; i<this.length; i++){
936                if (this[i] == Input){
937                        Result = i;
938                }
939        }
940        return Result;
941}
942Array.prototype.indexOf = Array_IndexOf;
943
944//IE HAS RENDERING BUG WITH BOTTOM NAVBAR
945function RemoveBottomNavBarForIE(){
946        if (C.ie){
947                if (document.getElementById('BottomNavBar') != null){
948                        document.getElementById('TheBody').removeChild(document.getElementById('BottomNavBar'));
949                }
950        }
951}
952
953
954
955
956//HOTPOTNET-RELATED CODE
957
958var HPNStartTime = (new Date()).getTime();
959var SubmissionTimeout = 30000;
960var Detail = ''; //Global that is used to submit tracking data
961
962function Finish(){
963//If there's a form, fill it out and submit it
964        if (document.store != null){
965                Frm = document.store;
966                Frm.starttime.value = HPNStartTime;
967                Frm.endtime.value = (new Date()).getTime();
968                Frm.mark.value = Score;
969                Frm.detail.value = Detail;
970                Frm.submit();
971        }
972}
973
974
975
976//JQUIZ CORE JAVASCRIPT CODE
977
978var CurrQNum = 0;
979var CorrectIndicator = ':-)';
980var IncorrectIndicator = 'X';
981var YourScoreIs = 'Your score is: ';
982var ContinuousScoring = true;
983var CorrectFirstTime = 'Questions answered correctly first time: ';
984var ShowCorrectFirstTime = false;
985var ShuffleQs = false;
986var ShuffleAs = false;
987var DefaultRight = 'Correct!';
988var DefaultWrong = 'Sorry! Try again.';
989var QsToShow = 4;
990var Score = 0;
991var Finished = false;
992var Qs = null;
993var QArray = new Array();
994var ShowingAllQuestions = false;
995var ShowAllQuestionsCaption = 'Show all questions';
996var ShowOneByOneCaption = 'Show questions one by one';
997var State = new Array();
998var Feedback = '';
999
1000function CompleteEmptyFeedback(){
1001        var QNum, ANum;
1002        for (QNum=0; QNum<I.length; QNum++){
1003                for (ANum = 0; ANum<I[QNum][3].length; ANum++){
1004                        if (I[QNum][3][ANum][1].length < 1){
1005                                if (I[QNum][3][ANum][2] > 0){
1006                                        I[QNum][3][ANum][1] = DefaultRight;
1007                                }
1008                                else{
1009                                        I[QNum][3][ANum][1] = DefaultWrong;
1010                                }
1011                        }
1012                }
1013        }
1014}
1015
1016function SetUpQuestions(){
1017        var AList = new Array();
1018        var QList = new Array();
1019        var i, j;
1020        Qs = document.getElementById('Questions');
1021        while (Qs.getElementsByTagName('li').length > 0){
1022                QList.push(Qs.removeChild(Qs.getElementsByTagName('li')[0]));
1023        }
1024        var DumpItem = 0;
1025        while (QsToShow < QList.length){
1026                DumpItem = Math.floor(QList.length*Math.random());
1027                for (j=DumpItem; j<(QList.length-1); j++){
1028                        QList[j] = QList[j+1];
1029                }
1030                QList.length = QList.length-1;
1031        }
1032        if (ShuffleQs == true){
1033                QList = Shuffle(QList);
1034        }
1035        if (ShuffleAs == true){
1036                var As;
1037                for (var i=0; i<QList.length; i++){
1038                        As = QList[i].getElementsByTagName('ol')[0];
1039                        if (As != null){
1040                        AList.length = 0;
1041                                while (As.getElementsByTagName('li').length > 0){
1042                                        AList.push(As.removeChild(As.getElementsByTagName('li')[0]));
1043                                }
1044                                AList = Shuffle(AList);
1045                                for (j=0; j<AList.length; j++){
1046                                        As.appendChild(AList[j]);
1047                                }
1048                        }
1049                }
1050        }
1051       
1052        for (i=0; i<QList.length; i++){
1053                Qs.appendChild(QList[i]);
1054                QArray[QArray.length] = QList[i];
1055        }
1056       
1057//Now hide all except the first item
1058        for (i=1; i<QArray.length; i++){
1059                QArray[i].style.display = 'none';
1060        }               
1061        SetQNumReadout();
1062}
1063
1064function ChangeQ(ChangeBy){
1065        if (((CurrQNum + ChangeBy) < 0)||((CurrQNum + ChangeBy) >= QArray.length)){return;}
1066        QArray[CurrQNum].style.display = 'none';
1067        CurrQNum += ChangeBy;
1068        QArray[CurrQNum].style.display = '';
1069        SetQNumReadout();
1070//if there's a textbox, set the focus in it
1071        if (QArray[CurrQNum].getElementsByTagName('input')[0] != null){
1072                QArray[CurrQNum].getElementsByTagName('input')[0].focus();
1073        }
1074}
1075
1076function SetQNumReadout(){
1077        document.getElementById('QNumReadout').innerHTML = (CurrQNum+1) + ' / ' + QArray.length;
1078}
1079
1080I=new Array();
1081I[0]=new Array();I[0][0]=100;
1082I[0][1]='';
1083I[0][2]='0';
1084I[0][3]=new Array();
1085I[0][3][0]=new Array('Microsoft','Sorry! Microsoft is a very serious company, and would never dream of using a potato for a logo. Try again.',0,0,1);
1086I[0][3][1]=new Array('Apple','Sorry! Apple doesn\'t produce many programs for Windows! Try again.',0,0,1);
1087I[0][3][2]=new Array('Half-Baked Software','That\'s us! Half-Baked Software Inc. publishes Hot Potatoes and Quandary.',1,100,1);
1088I[0][3][3]=new Array('Adobe','Sorry! Adobe software is usually related to graphic design. Try again.',0,0,1);
1089I[1]=new Array();I[1][0]=100;
1090I[1][1]='';
1091I[1][2]='1';
1092I[1][3]=new Array();
1093I[1][3][0]=new Array('JCross','Sorry! JCross is used to make crosswords.',0,0,1);
1094I[1][3][1]=new Array('JQuiz','That\'s correct! JQuiz is the program used to create question-based exercises.',1,100,1);
1095I[1][3][2]=new Array('JCloze','Sorry! JCloze is used to make gap-fill exercises.',0,0,1);
1096I[2]=new Array();I[2][0]=100;
1097I[2][1]='';
1098I[2][2]='2';
1099I[2][3]=new Array();
1100I[2][3][0]=new Array('JCloze','Correct! JCloze is used to make cloze, or gap-fill, exercises.',1,100,1);
1101I[2][3][1]=new Array('JCross','Sorry! JCross is used to make crosswords.',0,0,1);
1102I[2][3][2]=new Array('JQuiz','Sorry! JQuiz is used to make question-based exercises.',0,0,1);
1103I[2][3][3]=new Array('JMix','Sorry! JMix is used to make jumbled-word or jumbled-sentence exercises.',0,0,1);
1104I[2][3][4]=new Array('JMatch','Sorry! JMatch is used to make matching exercises.',0,0,1);
1105I[3]=new Array();I[3][0]=100;
1106I[3][1]='';
1107I[3][2]='3';
1108I[3][3]=new Array();
1109I[3][3][0]=new Array('JCloth','Hint: a JCloth is used for cleaning up the kitchen.',0,0,1);
1110I[3][3][1]=new Array('JCPenney','Hint: JCPenney is a department store.',0,0,1);
1111I[3][3][2]=new Array('JQuiz','Hint: JQuiz is a Potato.',1,100,1);
1112I[3][3][3]=new Array('JMix','Hint: JMix is a Potato.',1,100,1);
1113I[3][3][4]=new Array('JLo','Hint: JLo is a famous singer.',0,0,1);
1114I[3][3][5]=new Array('JMatch','Hint: JMatch is a Potato.',1,100,1);
1115I[3][3][6]=new Array('JCross','Hint: JCross is a Potato.',1,100,1);
1116I[3][3][7]=new Array('JCloze','Hint: JCloze is a Potato.',1,100,1);
1117I[3][3][8]=new Array('The Masher','Hint: The Masher is a Potato.',1,100,1);
1118
1119
1120function StartUp(){
1121        RemoveBottomNavBarForIE();
1122       
1123
1124       
1125
1126       
1127        CompleteEmptyFeedback();
1128
1129        SetUpQuestions();
1130        ClearTextBoxes();
1131        CreateStatusArray();
1132       
1133
1134       
1135}
1136
1137function ShowHideQuestions(){
1138        FuncBtnOut(document.getElementById('ShowMethodButton'));
1139        document.getElementById('ShowMethodButton').style.display = 'none';
1140        if (ShowingAllQuestions == false){
1141                for (var i=0; i<QArray.length; i++){
1142                                QArray[i].style.display = '';
1143                        }
1144                document.getElementById('Questions').style.listStyleType = 'decimal';
1145                document.getElementById('OneByOneReadout').style.display = 'none';
1146                document.getElementById('ShowMethodButton').innerHTML = ShowOneByOneCaption;
1147                ShowingAllQuestions = true;
1148        }
1149        else{
1150                for (var i=0; i<QArray.length; i++){
1151                                if (i != CurrQNum){
1152                                        QArray[i].style.display = 'none';
1153                                }
1154                        }
1155                document.getElementById('Questions').style.listStyleType = 'none';
1156                document.getElementById('OneByOneReadout').style.display = '';
1157                document.getElementById('ShowMethodButton').innerHTML = ShowAllQuestionsCaption;
1158                ShowingAllQuestions = false;   
1159        }
1160        document.getElementById('ShowMethodButton').style.display = 'inline';
1161}
1162
1163function CreateStatusArray(){
1164        var QNum, ANum;
1165//For each item in the item array
1166        for (QNum=0; QNum<I.length; QNum++){
1167//Check if the question still exists (hasn't been nuked by showing a random selection)
1168                if (document.getElementById('Q_' + QNum) != null){
1169                        State[QNum] = new Array();
1170                        State[QNum][0] = -1; //Score for this q; -1 shows question not done yet
1171                        State[QNum][1] = new Array(); //answers
1172                        for (ANum = 0; ANum<I[QNum][3].length; ANum++){
1173                                State[QNum][1][ANum] = 0; //answer not chosen yet; when chosen, will store its position in the series of choices
1174                        }
1175                        State[QNum][2] = 0; //tries at this q so far
1176                        State[QNum][3] = 0; //incrementing percent-correct values of selected answers
1177                        State[QNum][4] = 0; //penalties incurred for hints
1178                        State[QNum][5] = ''; //Sequence of answers chosen by number
1179                }
1180        }
1181}
1182
1183
1184
1185function CheckMCAnswer(QNum, ANum, Btn){
1186//if question doesn't exist, bail
1187        if (State[QNum].length < 1){return;}
1188       
1189//Get the feedback
1190        Feedback = I[QNum][3][ANum][1];
1191       
1192//Now show feedback and bail if question already complete
1193        if (State[QNum][0] > -1){
1194                ShowMessage(Feedback);
1195                return;
1196        }
1197       
1198//Hide the button while processing
1199        Btn.style.display = 'none';
1200
1201//Increment the number of tries
1202        State[QNum][2]++;
1203       
1204//Add the percent-correct value of this answer
1205        State[QNum][3] += I[QNum][3][ANum][3];
1206       
1207//Store the try number in the answer part of the State array, for tracking purposes
1208        State[QNum][1][ANum] = State[QNum][2];
1209        State[QNum][5] += String.fromCharCode(65+ANum) + ',';
1210       
1211//Should this answer be accepted as correct?
1212        if (I[QNum][3][ANum][2] < 1){
1213//It's wrong
1214
1215//Mark the answer
1216                Btn.innerHTML = IncorrectIndicator;
1217               
1218//Check whether this leaves just one MC answer unselected, in which case the Q is terminated
1219                var RemainingAnswer = FinalAnswer(QNum);
1220                if (RemainingAnswer > -1){
1221//Behave as if the last answer had been selected, but give no credit for it
1222//Increment the number of tries
1223                        State[QNum][2]++;               
1224               
1225//Calculate the score for this question
1226                        CalculateMCQuestionScore(QNum);
1227
1228//Get the overall score and add it to the feedback
1229                        CalculateOverallScore();
1230                        if ((ContinuousScoring == true)||(Finished == true)){
1231                                Feedback += '<br />' + YourScoreIs + ' ' + Score + '%.';
1232                                WriteToInstructions(YourScoreIs + ' ' + Score + '%.');
1233                        }
1234                }
1235        }
1236        else{
1237//It's right
1238//Mark the answer
1239                Btn.innerHTML = CorrectIndicator;
1240                               
1241//Calculate the score for this question
1242                CalculateMCQuestionScore(QNum);
1243
1244//Get the overall score and add it to the feedback
1245                if (ContinuousScoring == true){
1246                        CalculateOverallScore();
1247                        if ((ContinuousScoring == true)||(Finished == true)){
1248                                Feedback += '<br />' + YourScoreIs + ' ' + Score + '%.';
1249                                WriteToInstructions(YourScoreIs + ' ' + Score + '%.');
1250                        }
1251                }
1252        }
1253       
1254//Show the button again
1255        Btn.style.display = 'inline';
1256       
1257//Finally, show the feedback   
1258        ShowMessage(Feedback);
1259       
1260//Check whether all questions are now done
1261        CheckFinished();
1262}
1263
1264function CalculateMCQuestionScore(QNum){
1265        var Tries = State[QNum][2] + State[QNum][4]; //include tries and hint penalties
1266        var PercentCorrect = State[QNum][3];
1267        var TotAns = GetTotalMCAnswers(QNum);
1268        var HintPenalties = State[QNum][4];
1269       
1270//Make sure it's not already complete
1271
1272        if (State[QNum][0] < 0){
1273//Allow for Hybrids
1274                if (HintPenalties >= 1){
1275                        State[QNum][0] = 0;
1276                }
1277                else{
1278                        State[QNum][0] = ((TotAns-(Tries-1))/TotAns)*(PercentCorrect/(100*Tries));
1279                }
1280                if (State[QNum][0] < 0){
1281                        State[QNum][0] = 0;
1282                }
1283        }
1284}
1285
1286function GetTotalMCAnswers(QNum){
1287        var Result = 0;
1288        for (var ANum=0; ANum<I[QNum][3].length; ANum++){
1289                if (I[QNum][3][ANum][4] == 1){ //This is an MC answer
1290                        Result++;
1291                }
1292        }
1293        return Result;
1294}
1295
1296function FinalAnswer(QNum){
1297        var UnchosenAnswers = 0;
1298        var FinalAnswer = -1;
1299        for (var ANum=0; ANum<I[QNum][3].length; ANum++){
1300                if (I[QNum][3][ANum][4] == 1){ //This is an MC answer
1301                        if (State[QNum][1][ANum] < 1){ //This answer hasn't been chosen yet
1302                                UnchosenAnswers++;
1303                                FinalAnswer = ANum;
1304                        }
1305                }
1306        }
1307        if (UnchosenAnswers == 1){
1308                return FinalAnswer;
1309        }
1310        else{
1311                return -1;
1312        }
1313}
1314
1315
1316
1317
1318
1319function CheckMultiSelAnswer(QNum){
1320//bail if question doesn't exist or exercise finished
1321        if ((State[QNum].length < 1)||(Finished == true)){return;}
1322
1323//Increment the tries for this question
1324        State[QNum][2]++;
1325       
1326        var ShouldBeChecked;
1327        var Matches = 0;
1328        State[QNum][5] += '|';
1329       
1330//Check if there are any mismatches
1331        Feedback = '';
1332        var CheckBox = null;
1333        for (var ANum=0; ANum<I[QNum][3].length; ANum++){
1334                CheckBox = document.getElementById('Q_' + QNum + '_' + ANum + '_Chk');
1335                if (CheckBox.checked == true){
1336                        State[QNum][5] += 'Y';
1337                }
1338                else{
1339                        State[QNum][5] += 'N';
1340                }
1341                ShouldBeChecked = (I[QNum][3][ANum][2] == 1);
1342                if (ShouldBeChecked == CheckBox.checked){
1343                        Matches++;
1344                }
1345                else{
1346                        Feedback = I[QNum][3][ANum][1];
1347                }
1348        }
1349//Add the hit readout
1350        Feedback = Matches + ' / ' + I[QNum][3].length + '<br />' + Feedback;
1351        if (Matches == I[QNum][3].length){
1352//It's right
1353                CalculateMultiSelQuestionScore(QNum);
1354                if (ContinuousScoring == true){
1355                        CalculateOverallScore();
1356                        if ((ContinuousScoring == true)||(Finished == true)){
1357                                Feedback += '<br />' + YourScoreIs + ' ' + Score + '%.';
1358                                WriteToInstructions(YourScoreIs + ' ' + Score + '%.');
1359                        }
1360                }
1361        }
1362//If it's wrong, no need to do anything but show the feedback
1363        ShowMessage(Feedback);
1364}
1365
1366function CalculateMultiSelQuestionScore(QNum){
1367        var Tries = State[QNum][2];
1368        var TotAns = State[QNum][1].length;
1369       
1370//Make sure it's not already complete
1371        if (State[QNum][0] < 0){
1372                State[QNum][0] = (TotAns - (Tries-1)) / TotAns;
1373                if (State[QNum][0] < 0){
1374                        State[QNum][0] = 0;
1375                }
1376        }
1377}
1378
1379
1380
1381function CalculateOverallScore(){
1382        var TotalWeighting = 0;
1383        var TotalScore = 0;
1384       
1385        for (var QNum=0; QNum<State.length; QNum++){
1386                if (State[QNum] != null){
1387                        if (State[QNum][0] > -1){
1388                                TotalWeighting += I[QNum][0];
1389                                TotalScore += (I[QNum][0] * State[QNum][0]);
1390                        }
1391                }
1392        }
1393        Score = Math.floor((TotalScore/TotalWeighting)*100);
1394}
1395
1396function CheckFinished(){
1397        var FB = '';
1398
1399        var AllDone = true;
1400        for (var QNum=0; QNum<State.length; QNum++){
1401                if (State[QNum][0] < 0){
1402                        AllDone = false;
1403                }
1404        }
1405        if (AllDone == true){
1406       
1407//Report final score and submit if necessary
1408                CalculateOverallScore();
1409                FB = YourScoreIs + ' ' + Score + '%.';
1410                if (ShowCorrectFirstTime == true){
1411                        var CFT = 0;
1412                        for (QNum=0; QNum<State.length; QNum++){
1413                                if (State[QNum][0] >= 1){
1414                                        CFT++;
1415                                }
1416                        }
1417                        FB += '<br />' + CorrectFirstTime + ' ' + CFT + '/' + State.length;
1418                }
1419                WriteToInstructions(FB);
1420               
1421                Finished == true;
1422
1423                TimeOver = true;
1424                Locked = true;
1425               
1426
1427
1428                Finished = true;
1429                Detail = '<?xml version="1.0"?><hpnetresult><fields>';
1430                for (QNum=0; QNum<State.length; QNum++){
1431                        if (State[QNum][5].length > 0){
1432                                Detail += '<field><fieldname>Question #' + (QNum+1) + '</fieldname><fieldtype>question-tracking</fieldtype><fieldlabel>Q ' + (QNum+1) + '</fieldlabel><fieldlabelid>QuestionTrackingField</fieldlabelid><fielddata>' + State[QNum][5] + '</fielddata></field>';
1433                        }
1434                }
1435                Detail += '</fields></hpnetresult>';
1436                setTimeout('Finish()', SubmissionTimeout);
1437        }
1438}
1439
1440
1441
1442
1443
1444//CORE CODE FOR CHECKING SHORT ANSWER GUESSES AGAINST ANSWER ARRAYS
1445
1446var CaseSensitive = false;
1447var ShowAlsoCorrect = true;
1448var PleaseEnter = 'Please enter a guess.';
1449var HybridTries = 2;
1450var PartlyIncorrect = 'Your answer is partly wrong: ';
1451var CorrectList = 'Correct answers: ';
1452var NextCorrect = 'Next correct letter in the answer: ';
1453var CurrBox = null;
1454
1455function TrackFocus(BoxID){
1456        InTextBox = true;
1457        CurrBox = document.getElementById(BoxID);
1458}
1459
1460function LeaveGap(){
1461        InTextBox = false;
1462}
1463
1464function TypeChars(Chars){
1465        if (CurrBox != null){
1466//              if (CurrBox.style.display != 'none'){
1467                        CurrBox.value += Chars;
1468//              }
1469        }
1470}
1471
1472function CheckGuess(Guess, Answer, CaseSensitive, PercentCorrect, Feedback){
1473        this.Guess = Guess;
1474        this.Answer = Answer;
1475        this.PercentCorrect = PercentCorrect;
1476        this.Feedback = Feedback;
1477        if (CaseSensitive == false){
1478                this.WorkingGuess = Guess.toLowerCase();
1479                this.WorkingAnswer = Answer.toLowerCase();
1480        }
1481        else{
1482                this.WorkingGuess = Guess;
1483                this.WorkingAnswer = Answer;                           
1484        }
1485        this.Hint = '';
1486        this.HintPenalty = 1/Answer.length;
1487        this.CorrectStart = '';
1488        this.WrongMiddle = '';
1489        this.CorrectEnd = '';
1490        this.PercentMatch = 0;
1491        this.DoCheck();
1492}
1493
1494function CheckGuess_DoCheck(){
1495//Check if it's an exact match
1496        if (this.WorkingAnswer == this.WorkingGuess){
1497                this.PercentMatch = 100;
1498                this.CorrectStart = this.Guess;
1499        return;
1500        }
1501//Figure out how much of the beginning is correct
1502        var i = 0;
1503        var CorrectChars = 0;
1504        while (this.WorkingAnswer.charAt(i) == this.WorkingGuess.charAt(i)){
1505                i++;
1506                CorrectChars++;
1507        }
1508//Stash the hint
1509        this.Hint = this.Answer.charAt(i);
1510       
1511        this.CorrectStart = this.Guess.substring(0, i);
1512//Figure out how much of the end is correct
1513        var j = this.WorkingGuess.length-1;
1514        var k = this.WorkingAnswer.length-1;
1515        while ((this.WorkingAnswer.charAt(k) == this.WorkingGuess.charAt(j))&&(CorrectChars < this.Answer.length)){
1516                CorrectChars++;
1517                j--;
1518                k--;
1519        }
1520        this.CorrectEnd = this.Guess.substring(j+1, this.Guess.length);
1521        this.WrongMiddle = this.Guess.substring(i, j+1);
1522        if (TrimString(this.WrongMiddle).length < 1){this.WrongMiddle = '_____';}
1523//Calculate match score based on how much of the guess is correct
1524        if (CorrectChars < this.Answer.length){
1525                this.PercentMatch = Math.floor(100*CorrectChars)/this.Answer.length;
1526        }
1527        else{
1528                this.PercentMatch = Math.floor((100 * CorrectChars)/this.Guess.length);
1529        }       
1530}
1531
1532CheckGuess.prototype.DoCheck = CheckGuess_DoCheck;
1533
1534function CheckAnswerArray(CaseSensitive){
1535        this.CaseSensitive = CaseSensitive;
1536        this.Answers = new Array();
1537        this.Score = 0;
1538        this.Feedback = '';
1539        this.Hint = '';
1540        this.HintPenalty = 0;
1541        this.MatchedAnswerLength = 1;
1542        this.CompleteMatch = false;
1543        this.MatchNum = -1;
1544}
1545
1546function CheckAnswerArray_AddAnswer(Guess, Answer, PercentCorrect, Feedback){
1547        this.Answers.push(new CheckGuess(Guess, Answer, this.CaseSensitive, PercentCorrect, Feedback));
1548}
1549
1550CheckAnswerArray.prototype.AddAnswer = CheckAnswerArray_AddAnswer;
1551
1552function CheckAnswerArray_ClearAll(){
1553        this.Answers.length = 0;
1554}
1555
1556CheckAnswerArray.prototype.ClearAll = CheckAnswerArray_ClearAll;
1557
1558function CheckAnswerArray_GetBestMatch(){
1559//First check for a 100% match
1560        for (var i=0; i<this.Answers.length; i++){
1561                if (this.Answers[i].PercentMatch == 100){
1562                        this.Feedback = this.Answers[i].Feedback;
1563                        this.Score = this.Answers[i].PercentCorrect;
1564                        this.CompleteMatch = true;
1565                        this.MatchNum = i;
1566                        return;
1567                }
1568        }
1569//Now check for the best alternative match
1570        var PercentMatch = 0;
1571        var BestMatch = -1;
1572        for (i=0; i<this.Answers.length; i++){
1573                if ((this.Answers[i].PercentMatch > PercentMatch)&&(this.Answers[i].PercentCorrect == 100)){
1574                        BestMatch = i;
1575                        PercentMatch = this.Answers[i].PercentMatch;
1576                }
1577        }
1578        if (BestMatch > -1){
1579                this.Score = this.Answers[BestMatch].PercentMatch;
1580                this.Feedback = PartlyIncorrect + ' ';
1581                this.Feedback += '<span class="Answer">' + this.Answers[BestMatch].CorrectStart;
1582                this.Feedback += '<span class="Highlight">' + this.Answers[BestMatch].WrongMiddle + '</span>';
1583                this.Feedback += this.Answers[BestMatch].CorrectEnd + '</span>';
1584                this.Hint = '<span class="Answer">' + this.Answers[BestMatch].CorrectStart;
1585                this.Hint += '<span class="Highlight">' + this.Answers[BestMatch].Hint + '</span></span>';
1586                this.HintPenalty = this.Answers[BestMatch].HintPenalty;
1587        }
1588        else{
1589                this.Score = 0;
1590                this.Feedback = '';
1591        }
1592}
1593
1594CheckAnswerArray.prototype.GetBestMatch = CheckAnswerArray_GetBestMatch;
1595
1596function CheckShortAnswer(QNum){
1597//bail if question doesn't exist or exercise finished
1598        if ((State[QNum].length < 1)||(Finished == true)){return;}
1599       
1600//bail if question already complete
1601        if (State[QNum][0] > -1){return;}
1602
1603//Get the guess
1604        var G = document.getElementById('Q_' + QNum + '_Guess').value;
1605       
1606//If no guess, bail with message; no penalty
1607        if (G.length < 1){
1608                ShowMessage(PleaseEnter);
1609                return;
1610        }
1611
1612//Increment tries
1613        State[QNum][2]++;
1614       
1615//Create a check object
1616        var CA = new CheckAnswerArray(CaseSensitive);
1617
1618        CA.ClearAll();
1619        for (var ANum=0; ANum<I[QNum][3].length; ANum++){
1620                CA.AddAnswer(G, I[QNum][3][ANum][0], I[QNum][3][ANum][3], I[QNum][3][ANum][1]);
1621        }
1622        CA.GetBestMatch();
1623       
1624//Store any match in the state tracking field
1625        if (CA.MatchNum > -1){
1626                State[QNum][5] += String.fromCharCode(65+CA.MatchNum) + ',';
1627        }
1628
1629//Add the percent correct value for this answer to the Q State (works for all
1630//situations, wrong or right
1631        State[QNum][3] += CA.Score;
1632       
1633//Now branch, based on the nature of the match
1634//Is it a complete match?
1635        if (CA.CompleteMatch == true){
1636               
1637//Is it with a wrong answer, or a right answer?
1638                if (CA.Score == 100){
1639//It's right
1640                        CalculateShortAnsQuestionScore(QNum);
1641//Get correct answer list if required, assuming there are any other correct alternatives
1642                        if (ShowAlsoCorrect == true){
1643                                var AlsoCorrectList = GetCorrectList(QNum, G, false);
1644                                if (AlsoCorrectList.length > 0){
1645                                        CA.Feedback += '<br />' + CorrectList + '<br />' +  '<span class="Answer">' + AlsoCorrectList + '</span>';
1646                                }
1647                        }       
1648               
1649//Get the overall score and add it to the feedback
1650                        if (ContinuousScoring == true){
1651                                CalculateOverallScore();
1652                                CA.Feedback += '<br />' + YourScoreIs + ' ' + Score + '%.';
1653                                WriteToInstructions(YourScoreIs + ' ' + Score + '%.');
1654                        }
1655                        ShowMessage(CA.Feedback);
1656//Put the answer in
1657                        ReplaceGuessBox(QNum, G);
1658                        CheckFinished();
1659                        return;
1660                }
1661        }
1662       
1663//Otherwise, it's a match to a predicted wrong/partially correct, or a partial
1664//match to a right answer
1665        if (CA.Feedback.length < 1){CA.Feedback = DefaultWrong;}
1666        ShowMessage(CA.Feedback);
1667
1668//If necessary, switch a hybrid question to m/c
1669        if (State[QNum][2] >= HybridTries){
1670                SwitchHybridDisplay(QNum);
1671        }
1672}
1673
1674function CalculateShortAnsQuestionScore(QNum){
1675        var Tries = State[QNum][2] + State[QNum][4]; //include tries and hint penalties;
1676        var PercentCorrect = State[QNum][3];
1677        var HintPenalties = State[QNum][4];
1678
1679//Make sure it's not already complete
1680        if (State[QNum][0] < 0){
1681                if (HintPenalties >= 1){
1682                        State[QNum][0] = 0;
1683                }
1684                else{
1685                        State[QNum][0] = (PercentCorrect/(100*Tries));
1686                }
1687                if (State[QNum][0] < 0){
1688                        State[QNum][0] = 0;
1689                }
1690        }
1691}
1692
1693function SwitchHybridDisplay(QNum){
1694        if (document.getElementById('Q_' + QNum + '_Hybrid_MC') != null){
1695                document.getElementById('Q_' + QNum + '_Hybrid_MC').style.display = '';
1696                if (document.getElementById('Q_' + QNum + '_SA') != null){
1697                        document.getElementById('Q_' + QNum + '_SA').style.display = 'none';
1698                }
1699        }
1700}
1701
1702function GetCorrectArray(QNum){
1703        var Result = new Array();
1704        for (var ANum=0; ANum<I[QNum][3].length; ANum++){
1705                if (I[QNum][3][ANum][2] == 1){ //This is an acceptable correct answer
1706                        Result.push(I[QNum][3][ANum][0]);
1707                }
1708        }       
1709        return Result;
1710}
1711
1712function GetCorrectList(QNum, Answer, IncludeAnswer){
1713        var As = GetCorrectArray(QNum);
1714        var Result = '';
1715        for (var ANum=0; ANum<As.length; ANum++){
1716                if ((IncludeAnswer == true)||(As[ANum] != Answer)){
1717                        Result += As[ANum] + '<br />';
1718                }
1719        }
1720        return Result;
1721}
1722
1723function GetFirstCorrectAnswer(QNum){
1724        var As = GetCorrectArray(QNum);
1725        if (As.length > 0){
1726                return As[0];
1727        }
1728        else{
1729                return '';
1730        }
1731}
1732
1733function ReplaceGuessBox(QNum, Ans){
1734        if (document.getElementById('Q_' + QNum + '_SA') != null){
1735                var El = document.getElementById('Q_' + QNum + '_SA');
1736                while (El.childNodes.length > 0){
1737                        El.removeChild(El.childNodes[0]);
1738                }
1739                var A = document.createElement('span');
1740                A.setAttribute('class', 'Answer');
1741                var T = document.createTextNode(Ans);
1742                A.appendChild(T);
1743                El.appendChild(A);
1744        }
1745}
1746
1747
1748
1749function ShowAnswers(QNum){
1750//bail if question doesn't exist or exercise finished
1751        if ((State[QNum].length < 1)||(Finished == true)){return;}
1752       
1753//Get the answer list to display
1754        var Ans = GetCorrectList(QNum, '', false);
1755        Ans = CorrectList + '<br /><span class="Answer">' + Ans + '</span>';
1756       
1757//Display feedback
1758        ShowMessage(Ans);
1759       
1760//Set the score for this question to 0 if no
1761        if (State[QNum][0] < 1){
1762                State[QNum][0] = 0;
1763        }
1764
1765//Get the first correct answer
1766        var FirstAns = GetFirstCorrectAnswer(QNum);
1767       
1768//Replace the textbox
1769        ReplaceGuessBox(QNum, FirstAns);
1770       
1771//This may be the last, so check finished status
1772        CheckFinished();
1773}
1774
1775
1776
1777
1778
1779function ShowHint(QNum){
1780//bail if question doesn't exist or exercise finished
1781        if ((State[QNum].length < 1)||(Finished == true)){return;}
1782       
1783//bail if question already complete
1784        if (State[QNum][0] > -1){return;}
1785
1786//Get the guess
1787        var G = document.getElementById('Q_' + QNum + '_Guess').value;
1788       
1789//If no guess, give the first correct bit
1790        if (G.length < 1){
1791                var Ans = GetFirstCorrectAnswer(QNum);
1792                var Hint = Ans.charAt(0);
1793                ShowMessage(NextCorrect + '<br />' + Hint);
1794//Penalty for hint
1795                State[QNum][4] += (1/Ans.length);
1796                return;
1797        }
1798
1799//Increment tries
1800        State[QNum][2]++;
1801       
1802//Create a check object
1803        var CA = new CheckAnswerArray(CaseSensitive);
1804
1805        CA.ClearAll();
1806        for (var ANum=0; ANum<I[QNum][3].length; ANum++){
1807//Use only correct answers
1808                if (I[QNum][3][ANum][2] == 1){
1809                        CA.AddAnswer(G, I[QNum][3][ANum][0], I[QNum][3][ANum][3], I[QNum][3][ANum][1]);
1810                }
1811        }
1812        CA.GetBestMatch();
1813        if (CA.CompleteMatch == true){
1814//It's right!
1815                CheckShortAnswer(QNum);
1816                return;
1817        }
1818        else{
1819                if (CA.Hint.length > 0){
1820                        ShowMessage(NextCorrect + '<br />' + CA.Hint);
1821                        State[QNum][4] += CA.HintPenalty;
1822                }
1823                else{
1824                        ShowMessage(DefaultWrong + '<br />' + NextCorrect + '<br />' + GetFirstCorrectAnswer(QNum)[0]);
1825                }
1826        }
1827}
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837//-->
1838
1839//]]>
1840
1841</script>
1842
1843
1844</head>
1845
1846<body onload="StartUp()" id="TheBody">
1847
1848<!-- BeginTopNavButtons -->
1849
1850
1851
1852<!-- EndTopNavButtons -->
1853
1854<div class="Titles">
1855        <h2 class="ExerciseTitle">Example JQuiz exercise showing all four question types</h2>
1856        <h3 class="ExerciseSubtitle"></h3>
1857
1858
1859</div>
1860
1861<div id="InstructionsDiv" class="StdDiv">
1862        <p id="Instructions"></p>
1863</div>
1864
1865
1866
1867
1868<div id="MainDiv" class="StdDiv">
1869 
1870<div class="QuestionNavigation">
1871
1872<p style="text-align: right;">
1873<button id="ShowMethodButton" class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)" onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOver(this)" onclick="ShowHideQuestions(); return false;">Show all questions</button>
1874</p>
1875
1876<div id="OneByOneReadout">
1877<button id="PrevQButton" class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)" onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOver(this)" onclick="ChangeQ(-1); return false;">&lt;=</button>
1878
1879<span id="QNumReadout" class="QNum">&nbsp;</span>
1880
1881<button id="NextQButton" class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)" onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOver(this)" onclick="ChangeQ(1); return false;">=&gt;</button>
1882<br />
1883</div>
1884
1885</div>
1886 
1887<ol class="QuizQuestions" id="Questions">
1888<li class="QuizQuestion" id="Q_0"><p class="QuestionText">This is a multiple-choice question:<br /><br />Which software company publishes Hot Potatoes?</p><ol class="MCAnswers"><li id="Q_0_0"><button class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)"  onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" id="Q_0_0_Btn" onclick="CheckMCAnswer(0,0,this)">&nbsp;&nbsp;?&nbsp;&nbsp;</button>&nbsp;&nbsp;Microsoft</li><li id="Q_0_1"><button class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)"  onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" id="Q_0_1_Btn" onclick="CheckMCAnswer(0,1,this)">&nbsp;&nbsp;?&nbsp;&nbsp;</button>&nbsp;&nbsp;Apple</li><li id="Q_0_2"><button class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)"  onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" id="Q_0_2_Btn" onclick="CheckMCAnswer(0,2,this)">&nbsp;&nbsp;?&nbsp;&nbsp;</button>&nbsp;&nbsp;Half-Baked Software</li><li id="Q_0_3"><button class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)"  onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" id="Q_0_3_Btn" onclick="CheckMCAnswer(0,3,this)">&nbsp;&nbsp;?&nbsp;&nbsp;</button>&nbsp;&nbsp;Adobe</li></ol></li>
1889<li class="QuizQuestion" id="Q_1"><p class="QuestionText">This is a short-answer question. The correct answer is "JQuiz". Try typing a wrong answer (such as "JCloze") to see specific feedback for that answer, and try typing an answer which is partly correct (such as "JQuoz") to see the response you get.<br /><br />Which program was used to make this quiz?</p><div class="ShortAnswer" id="Q_1_SA"><form method="post" action="" onsubmit="return false;"><div><input type="text" id="Q_1_Guess" onfocus="TrackFocus('Q_1_Guess')" onblur="LeaveGap()" class="GapBox" size="9"></input><br /><br /><button class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)"  onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" onclick="CheckShortAnswer(1)">Check</button><button class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)"  onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" onclick="ShowHint(1)">Hint</button><button class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)"  onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" onclick="ShowAnswers(1)">Show answer</button></div></form></div></li>
1890<li class="QuizQuestion" id="Q_2"><p class="QuestionText">This question is a "hybrid" question. You will have two tries at answering it correctly by typing the answer in; if you still don't get it right, you will see some multiple-choice answers to choose from.<br /><br />Which program is used to make gap-fill exercises?</p><div class="ShortAnswer" id="Q_2_SA"><form method="post" action="" onsubmit="return false;"><div><input type="text" id="Q_2_Guess" onfocus="TrackFocus('Q_2_Guess')" onblur="LeaveGap()" class="GapBox" size="9"></input><br /><br /><button class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)"  onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" onclick="CheckShortAnswer(2)">Check</button><button class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)"  onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" onclick="ShowHint(2)">Hint</button><button class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)"  onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" onclick="ShowAnswers(2)">Show answer</button></div></form></div><ol class="MCAnswers" id="Q_2_Hybrid_MC" style="display: none;"><li id="Q_2_0"><button class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)"  onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" id="Q_2_0_Btn" onclick="CheckMCAnswer(2,0,this)">&nbsp;&nbsp;?&nbsp;&nbsp;</button>&nbsp;&nbsp;JCloze</li><li id="Q_2_1"><button class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)"  onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" id="Q_2_1_Btn" onclick="CheckMCAnswer(2,1,this)">&nbsp;&nbsp;?&nbsp;&nbsp;</button>&nbsp;&nbsp;JCross</li><li id="Q_2_2"><button class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)"  onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" id="Q_2_2_Btn" onclick="CheckMCAnswer(2,2,this)">&nbsp;&nbsp;?&nbsp;&nbsp;</button>&nbsp;&nbsp;JQuiz</li><li id="Q_2_3"><button class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)"  onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" id="Q_2_3_Btn" onclick="CheckMCAnswer(2,3,this)">&nbsp;&nbsp;?&nbsp;&nbsp;</button>&nbsp;&nbsp;JMix</li><li id="Q_2_4"><button class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)"  onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" id="Q_2_4_Btn" onclick="CheckMCAnswer(2,4,this)">&nbsp;&nbsp;?&nbsp;&nbsp;</button>&nbsp;&nbsp;JMatch</li></ol></li>
1891<li class="QuizQuestion" id="Q_3"><p class="QuestionText">This final question is a multiselect question. Which of the following are Hot Potatoes programs?</p><ol class="MSelAnswers"><li id="Q_3_0"><form method="post" action="" onsubmit="return false;"><div><input type="checkbox" id="Q_3_0_Chk" class="MSelCheckbox" />JCloth</div></form></li><li id="Q_3_1"><form method="post" action="" onsubmit="return false;"><div><input type="checkbox" id="Q_3_1_Chk" class="MSelCheckbox" />JCPenney</div></form></li><li id="Q_3_2"><form method="post" action="" onsubmit="return false;"><div><input type="checkbox" id="Q_3_2_Chk" class="MSelCheckbox" />JQuiz</div></form></li><li id="Q_3_3"><form method="post" action="" onsubmit="return false;"><div><input type="checkbox" id="Q_3_3_Chk" class="MSelCheckbox" />JMix</div></form></li><li id="Q_3_4"><form method="post" action="" onsubmit="return false;"><div><input type="checkbox" id="Q_3_4_Chk" class="MSelCheckbox" />JLo</div></form></li><li id="Q_3_5"><form method="post" action="" onsubmit="return false;"><div><input type="checkbox" id="Q_3_5_Chk" class="MSelCheckbox" />JMatch</div></form></li><li id="Q_3_6"><form method="post" action="" onsubmit="return false;"><div><input type="checkbox" id="Q_3_6_Chk" class="MSelCheckbox" />JCross</div></form></li><li id="Q_3_7"><form method="post" action="" onsubmit="return false;"><div><input type="checkbox" id="Q_3_7_Chk" class="MSelCheckbox" />JCloze</div></form></li><li id="Q_3_8"><form method="post" action="" onsubmit="return false;"><div><input type="checkbox" id="Q_3_8_Chk" class="MSelCheckbox" />The Masher</div></form></li></ol><button class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)"  onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" onclick="CheckMultiSelAnswer(3)">Check</button></li></ol>
1892
1893
1894
1895</div>
1896
1897
1898
1899<div class="Feedback" id="FeedbackDiv">
1900<div class="FeedbackText" id="FeedbackContent"></div>
1901<button id="FeedbackOKButton" class="FuncButton" onfocus="FuncBtnOver(this)" onblur="FuncBtnOut(this)" onmouseover="FuncBtnOver(this)" onmouseout="FuncBtnOut(this)" onmousedown="FuncBtnDown(this)" onmouseup="FuncBtnOut(this)" onclick="HideFeedback(); return false;">&nbsp;OK&nbsp;</button>
1902</div>
1903
1904<!-- BeginBottomNavButtons -->
1905
1906
1907
1908<!-- EndBottomNavButtons -->
1909
1910<!-- BeginSubmissionForm -->
1911
1912<!-- EndSubmissionForm -->
1913
1914</body>
1915
1916</html>
Note: See TracBrowser for help on using the browser.