Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 14 of 14
  1. #1
    Regular Coder oVTech's Avatar
    Join Date
    Nov 2010
    Location
    USA
    Posts
    296
    Thanks
    4
    Thanked 54 Times in 52 Posts

    Simple Unobtrusive JavaScript Quiz

    I have come upon many threads that ask about how to implement a JS quiz. Just yesterday Bullant & I were offering different options to someone. Like everything else in the world there are many ways of doing this. Nevertheless, this is how I went about it.

    I should mention to the newbies out there that JS quizes aren't made for serious testing, but just for fun. Just look at the code, and you will see what I mean.

    Although this example might have a little more code than some other examples, one good thing about it is that it avoids global variables and it does not include any inline javascript.

    Feel free to ask any questions and to suggest changes or addons. I would also like to see how someone else would implement such thing.
    Here is the whole page

    NOTE: This forum adds an extra line in my getTarget function so be aware when you cut and paste. Here is the line that the forum adds: "rel="nofollow". If you seen this anywhere in my code, just take it out. I am unable to take that piece of code out.
    Code:
    <!DOCTYPE html PUBLIC
    "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>SIMPLE UNOBTRUSIVE QUIZ JS</title>
    <style type="text/css">
    body {
    	background: #6d6d6d;
    }
    #page {
    	width: 962px;
    	padding: 2px;
    	margin: 22px auto;
    }
    #q {
    	border: 4px solid #6299C5;
    	padding: 0 8px;
    	background: #ededed;
    	-moz-box-shadow:0px 1px 8px #82ccc5;
    	-webkit-box-shadow:0px 1px 8px #82ccc5;
    	 box-shadow:0px 1px 8px #82ccc5;
    	-o-box-shadow:0px 1px 8px #82ccc5;
    }
    #q h4 {
    	padding: 4px 8px;
    	border-left: 4px solid #6299C5;
    }
    #q #results {border: 2px solid #6299C5; padding:8px; display:none;}
    div.quizQ {
    	border-bottom: 1px solid #bcbcbc;
    	background: #ededed;
    	padding: 12px;
    	margin: 0;
    }
    div.quizQ h3 {
    	margin-bottom: 8px;
    }
    #score {
    	background-color: #6299C5;
        border: 1px solid #cdcdcd;
    	padding: 8px 10px;
        color: #FFFFFF;
    	cursor: pointer;
    	font-weight: bold;
    }
    #h {
    	background-color: #6299C5;
        border: 3px solid #cdcdcd;
    	padding: 8px 10px;
        color: #FFFFFF;
    	font-weight: bold;	
    	-moz-box-shadow:0px 1px 8px #82ccc5;
    	-webkit-box-shadow:0px 1px 8px #82ccc5;
    	 box-shadow:0px 1px 8px #82ccc5;
    	-o-box-shadow:0px 1px 8px #82ccc5;
    }
    #c {
    	width: 777px; 
    	border:1px solid #bebebe; 
    	padding:6px;margin:0; 
    	color:#dfdfdf; 
    	font-family: "Courier New", Courier, monospace;
    	font-weight:bold; 
    	font-style: italic;
    }
    </style>
    <script type="text/javascript">
    /* <![CDATA[ */
    /*
    -I am not putting a copyright on this, but I will 
     appreciate it if you left my nickname in the created by... 
    */
    			 
    	///Simple-Unobtrusive-Quiz-JS created by oVTech
    	var Quiz = {
    		addEvent: function( elm, evType, fn ) {//(required)
    			if (elm.addEventListener) {
    				elm.addEventListener(evType, fn, false);
    			} else if (elm.attachEvent) {
    				elm.attachEvent('on' + evType, fn);
    			} else {
    				elm['on' + evType] = fn;
    			}
    		},
    		getTarget: function( e ) {//(required)
    			var target = window.event ? window.event.srcElement : e ? e.target : null;
    			if (!target){return false;}
    				while(target.nodeType!=1 && target.nodeName.toLowerCase()!='body'){
    					target=target.parentNode;
    				}
    			return target;
    		},
    	
    		//Start Quiz
    		answers: [],
    		correctAnswers: ["a", "b", "c", "c", "a"], 
    		
    		initQuiz: function () {
    			var arrInp = document.getElementsByTagName('input');
    			Quiz.scoreIt = document.getElementById('score')
    			for (var i=0; i<arrInp.length; i++) {
    				if (arrInp[i].type.toLowerCase() == "radio") {
    					Quiz.addEvent( arrInp[i], 'click', Quiz.getAnswer);
    				}
    			}
    		},
    		getAnswer: function (e) {
    			var thisRadio = Quiz.getTarget(e);
    			var which = thisRadio.getAttribute("rel");
    			var val = thisRadio.getAttribute("value");
    			var group = thisRadio.getAttribute("name");
    			Quiz.recordAnswer( which, val, group )
    		},
    		recordAnswer: function (question, userAnswer, groupName) {
    			Quiz.answers[question] = userAnswer;
    		},
    		scoreQuiz: function () {
    			var totalCorrect = 0;
    			var totalIncorrect = 0;
    			
    			var incorrect = [];
    			
    			Quiz.f = document.getElementById('quizForm');
    			
    			var els = Quiz.f.elements;
    			
    			var quizWrap = document.getElementById('q');
    			var outputResults = document.getElementById('results');
    			
    			for (var i = 0; i<Quiz.correctAnswers.length; ++i) {
    				if (Quiz.answers[i] == Quiz.correctAnswers[i]) {
    					++totalCorrect;
    					quizWrap.getElementsByTagName('h4')[i].style.backgroundColor = "#00CC33";
    				}
    				else {
    					++totalIncorrect;
    					quizWrap.getElementsByTagName('h4')[i].style.backgroundColor = "#FF0000";
    				}
    			}
    		outputResults.style.display = "block";
    		outputResults.innerHTML = "You scored " + totalCorrect + " out of " + Quiz.correctAnswers.length;
    		outputResults.innerHTML +=  ", which is " + Math.round(totalCorrect/Quiz.correctAnswers.length * 100) + "%.";
    		
    		outputResults.innerHTML += "<br/>";
    		outputResults.innerHTML += "Total incorrect answers: " + totalIncorrect;
    		
    		for ( var c=-1, k; k=els[++c]; ) {
    			if (els[c].type == 'radio') {
    				k.disabled = true;//(good idea to have this)
    			}
    		}
    		
    		Quiz.scoreIt.disabled = true; //(required - without it bugs will crawl all over you)
    		Quiz.scoreIt.style.backgroundColor = "#92bbC5";
    		}		
    	};
    	function loadEvnts() {
    		Quiz.initQuiz();
    		var scoreIt = document.getElementById('score');
    		Quiz.addEvent( scoreIt, 'click',  Quiz.scoreQuiz);
    	}
    	Quiz.addEvent( window, 'load',  loadEvnts);
    
    /* ]]> */
    </script>
    </head>
    <body>
    
    <form action="#" method="post" id="quizForm">
    <div id="page">
    	<h3 id="h">Simple Unobtrusive Javascript Quiz ... <em>by oVTech</em></h3>
    	
    	<div id="q">
    	<p style="font-family: 'Courier New'; border-bottom: 1px dashed #888; margin: 4px;padding: 8px;">
    		<strong><u>Quick Notes:</u></strong> <br />
    	 - Percentages are rounded up with round() - optionally you can use toFixed(1)<br />
    	 - if you leave a radio button blank, then it counts as a wrong answer<br />
    	 - After submition, radio buttons & submit button are disabled<br />
    	 - Red & green colors let you know which questions you got incorrect and which ones correct<br />
    	 - There is a results div at the end of the page<br />
    	</p>
    		<div class="quizQ">
    		<h4>1. Inside which HTML tag do we put JavaScript code?</h4> 
    			<input type="radio" rel="0" value="a" name="grp0"/> &lt;script&gt; <br /> <!--Correct Answer: A-->
    			<input type="radio" rel="0" value="b" name="grp0"/> &lt;javascript&gt; <br />
    			<input type="radio" rel="0" value="c" name="grp0"/> &lt;jscript&gt; <br />
    		</div>
    
    		<div class="quizQ">
    		<h4>2. What is the correct syntax for referring to an external script called "xxx.js"?</h4>  
    			<input type="radio" rel="1" value="a" name="grp1"/> &lt;script type="text/javascript" href="xxx.js"&gt; <br />
    			<input type="radio" rel="1" value="b" name="grp1"/> &lt;script type="text/javascript" src="xxx.js"&gt; <br /> <!--Correct Answer: B-->
    			<input type="radio" rel="1" value="c" name="grp1"/> &lt;script type="text/javascript" name="xxx.js"&gt; <br />
    		</div>
    
    		<div class="quizQ">
    		<h4>3. The external JavaScript file must contain the &lt;script&gt; tag.</h4>  
    			<input type="radio" rel="2" value="a" name="grp2"/> True <br />
    			<input type="radio" rel="2" value="b" name="grp2"/> It is optional <br />
    			<input type="radio" rel="2" value="c" name="grp2"/> False <br /> <!--Correct Answer: C-->
    		</div>
    		
    		<div class="quizQ">
    		<h4>4. How do you create a function?</h4>  
    			<input type="radio" rel="3" value="a" name="grp3"/> function:fn()<br />
    			<input type="radio" rel="3" value="b" name="grp3"/> function=fn()<br />
    			<input type="radio" rel="3" value="c" name="grp3"/> function fn()<br /> <!--Correct Answer: C-->
    		</div>
    		
    		<div class="quizQ">
    		<h4>5. How do you write a conditional statement for executing some code if "k" is NOT equal to 5?</h4>  
    			<input type="radio" rel="4" value="a" name="grp4"/> if (k != 5)<br /> <!--Correct Answer: C-->
    			<input type="radio" rel="4" value="b" name="grp4"/> if(i = 5) <br />
    			<input type="radio" rel="4" value="c" name="grp4"/> if (i = !5)<br /> 
    		</div>
    		
    		<div style="padding:8px 2px;background:#ededed;">
    			<br />
    			<input type ="button" id="score" value="Score Quiz" /> 
    			<br /><br />
    			
    			<div id="results"></div>
    		</div>
    	</div>
    	
    		<br />
    		<p id="c">
    		<strong> - </strong>Copyright (c) nobody 2010 -> until 11111100100.<br />
    	    <strong> - </strong>Simple Unobtrusive JS Quiz created by <strong> - </strong> <em>oVTech.</em>	
    	   </p>
    		<br /> <br />
    </div>
    </form>
    
    </body>
    </html>
    Last edited by oVTech; 05-17-2011 at 02:50 PM.




    I don't know, I don't care, and it doesn't make any difference!
    -Albert Einstein-




  2. Users who have thanked oVTech for this post:

    mllanapatriciac (05-17-2011)

  • #2
    Banned
    Join Date
    Feb 2011
    Posts
    2,699
    Thanks
    13
    Thanked 395 Times in 395 Posts
    Quote Originally Posted by oVTech View Post
    Feel free to ask any questions and to suggest changes or addons. I would also like to see how someone else would implement such thing.
    Yep agree that this would normally all be done server side in the "real world" but I guess it is a common assignment for students learning javascript.

    Anyway just some food for thought:

    1) In general, I like to code with the view of trying to keep future maintenance down to a minimum. Hence I would prefer to put all the questions and answers in an array and then create the html dynamically. I wouldn't want to have to edit the html manually every time the questions and answers change.

    2) To increase useability I would have all the questions' options in a <label> so the user can click either the radio button or the text associated with it to select that answer.

    Also, I copied and pasted your code into a html file and nothing happens when I click the "Score quiz" button in both IE9 and FF4.

    Below is the demo (with a bonus question in the questions array ) I posted in the other thread you referred to. It doesn't include inline scripting either.

    Each row in the questions array contains the data for each question in the quiz. The first element in each row is the question itself. The second element is the option number for the correct answer to the question. The remaining elements are the options for that question.

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
            <title></title>
            <style type="text/css">
                fieldset {
                    width: 30%;
                    border: 1px solid green;
                }
                fieldset label {
                    display: block;
                }
            </style>
            <script type="text/javascript">
                var questions = [
                    ['What colour is the sun?','1','Yellow','Green','Blue'],
                    ['What is 2 x 3?','2',5,6,7,8],
                    ['What is the 3rd letter in Codingforums','3','z','r','d','a','t']
                ];
                function checkAnswers(){
                    var numCorrectAnswers = 0;
                    for(var i=0; i < questions.length; i++){
                        var radBtnsO = document.getElementsByName('q'+(i+1));
                        disableRadButtons(radBtnsO);
                        if(getAnswer(radBtnsO) == questions[i][1]){
                            ++numCorrectAnswers;
                            radBtnsO[0].parentNode.parentNode.firstChild.style.backgroundColor = 'green';
                        } else {
                            radBtnsO[0].parentNode.parentNode.firstChild.style.backgroundColor = 'red';
                        }
                    }
                    alert('Total correct answers = '+numCorrectAnswers);
                }
                function getAnswer(radBtnsO){
                    for(var i=0; i < radBtnsO.length; i++){
                        if(radBtnsO[i].checked){return radBtnsO[i].value;}
                    }
                    return false;
                }
                function disableRadButtons(radBtnsO){
                    for(var i=0; i < radBtnsO.length; i++){
                        radBtnsO[i].disabled = true;
                    }
                }
                window.onload=function(){
                    fldQuestionsO = document.getElementById('fldQuestions');
                    for(i=0; i < questions.length; i++){
                        var newDiv = document.createElement('div');
                        var newPara = document.createElement('p');
                        newPara.appendChild(document.createTextNode('Q'+(i+1)+' '+questions[i][0]));
                        newDiv.appendChild(newPara);
                        //create the radio buttons for each question
                        var radValue = 1;
                        for(j=2; j < questions[i].length; j++) {
                            var newLabel = document.createElement('label');
                            var newRadBtn = document.createElement('input');
                            newRadBtn.setAttribute('type', 'radio');
                            newRadBtn.setAttribute('name', 'q'+(i+1));
                            newRadBtn.setAttribute('value', radValue++);
                            newLabel.appendChild(newRadBtn);
                            newLabel.appendChild(document.createTextNode(questions[i][j]));
                            newDiv.appendChild(newLabel);
                        }
                        fldQuestionsO.appendChild(newDiv);
                    }
                    document.getElementById('btnSubmit').onclick=checkAnswers;
                }
            </script>
        </head>
        <body>
            <div>
                <fieldset id="fldQuestions"></fieldset>
                <button id="btnSubmit">Submit</button>
            </div>
        </body>
    </html>
    Last edited by bullant; 05-17-2011 at 08:38 AM.

  • Users who have thanked bullant for this post:

    mllanapatriciac (05-17-2011)

  • #3
    New Coder
    Join Date
    May 2011
    Posts
    12
    Thanks
    7
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by oVTech View Post
    I have come upon many threads that ask about how to implement a JS quiz. Just yesterday Bullant & I were offering different options to someone. Like everything else in the world there are many ways of doing this. Nevertheless, this is how I went about it.

    I should mention to the newbies out there that JS quizes aren't made for serious testing, but just for fun. Just look at the code, and you will see what I mean.

    Although this example might have a little more code than some other examples, one good thing about it is that it avoids global variables and it does not include any inline javascript.

    Feel free to ask any questions and to suggest changes or addons. I would also like to see how someone else would implement such thing.
    Here is the whole page:
    Code:
    <!DOCTYPE html PUBLIC
    "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>SIMPLE UNOBTRUSIVE QUIZ JS</title>
    <style type="text/css">
    body {
    	background: #6d6d6d;
    }
    #page {
    	width: 962px;
    	padding: 2px;
    	margin: 22px auto;
    }
    #q {
    	border: 4px solid #6299C5;
    	padding: 0 8px;
    	background: #ededed;
    	-moz-box-shadow:0px 1px 8px #82ccc5;
    	-webkit-box-shadow:0px 1px 8px #82ccc5;
    	 box-shadow:0px 1px 8px #82ccc5;
    	-o-box-shadow:0px 1px 8px #82ccc5;
    }
    #q h4 {
    	padding: 4px 8px;
    	border-left: 4px solid #6299C5;
    }
    #q #results {border: 2px solid #6299C5; padding:8px; display:none;}
    div.quizQ {
    	border-bottom: 1px solid #bcbcbc;
    	background: #ededed;
    	padding: 12px;
    	margin: 0;
    }
    div.quizQ h3 {
    	margin-bottom: 8px;
    }
    #score {
    	background-color: #6299C5;
        border: 1px solid #cdcdcd;
    	padding: 8px 10px;
        color: #FFFFFF;
    	cursor: pointer;
    	font-weight: bold;
    }
    #h {
    	background-color: #6299C5;
        border: 3px solid #cdcdcd;
    	padding: 8px 10px;
        color: #FFFFFF;
    	font-weight: bold;	
    	-moz-box-shadow:0px 1px 8px #82ccc5;
    	-webkit-box-shadow:0px 1px 8px #82ccc5;
    	 box-shadow:0px 1px 8px #82ccc5;
    	-o-box-shadow:0px 1px 8px #82ccc5;
    }
    #c {
    	width: 777px; 
    	border:1px solid #bebebe; 
    	padding:6px;margin:0; 
    	color:#dfdfdf; 
    	font-family: "Courier New", Courier, monospace;
    	font-weight:bold; 
    	font-style: italic;
    }
    </style>
    <script type="text/javascript">
    /* <![CDATA[ */
    /*
    -I am not putting a copyright on this, but I will 
     appreciate it if you left my nickname in the created by... 
    */
    			 
    	///Simple-Unobtrusive-Quiz-JS created by oVTech
    	var Quiz = {
    		addEvent: function( elm, evType, fn ) {//(required)
    			if (elm.addEventListener) {
    				elm.addEventListener(evType, fn, false);
    			} else if (elm.attachEvent) {
    				elm.attachEvent('on' + evType, fn);
    			} else {
    				elm['on' + evType] = fn;
    			}
    		},
    		getTarget: function( e ) {//(required)
    			var target = window.event ? window.event.srcElement : e ? e.target : null;
    			if (!target){return false;}
    				while(target.nodeType!=1 && target.nodeName.toLowerCase()!='body'){
    					target=target.parentNode;
    				}
    			return target;
    		},
    	
    		//Start Quiz
    		answers: [],
    		correctAnswers: ["a", "b", "c", "c", "a"], 
    		
    		initQuiz: function () {
    			var arrInp = document.getElementsByTagName('input');
    			Quiz.scoreIt = document.getElementById('score')
    			for (var i=0; i<arrInp.length; i++) {
    				if (arrInp[i].type.toLowerCase() == "radio") {
    					Quiz.addEvent( arrInp[i], 'click', Quiz.getAnswer);
    				}
    			}
    		},
    		getAnswer: function (e) {
    			var thisRadio = Quiz.getTarget(e);
    			var which = thisRadio.getAttribute("rel");
    			var val = thisRadio.getAttribute("value");
    			var group = thisRadio.getAttribute("name");
    			Quiz.recordAnswer( which, val, group )
    		},
    		recordAnswer: function (question, userAnswer, groupName) {
    			Quiz.answers[question] = userAnswer;
    		},
    		scoreQuiz: function () {
    			var totalCorrect = 0;
    			var totalIncorrect = 0;
    			
    			var incorrect = [];
    			
    			Quiz.f = document.getElementById('quizForm');
    			
    			var els = Quiz.f.elements;
    			
    			var quizWrap = document.getElementById('q');
    			var outputResults = document.getElementById('results');
    			
    			for (var i = 0; i<Quiz.correctAnswers.length; ++i) {
    				if (Quiz.answers[i] == Quiz.correctAnswers[i]) {
    					++totalCorrect;
    					quizWrap.getElementsByTagName('h4')[i].style.backgroundColor = "#00CC33";
    				}
    				else {
    					++totalIncorrect;
    					quizWrap.getElementsByTagName('h4')[i].style.backgroundColor = "#FF0000";
    				}
    			}
    		outputResults.style.display = "block";
    		outputResults.innerHTML = "You scored " + totalCorrect + " out of " + Quiz.correctAnswers.length;
    		outputResults.innerHTML +=  ", which is " + Math.round(totalCorrect/Quiz.correctAnswers.length * 100) + "%.";
    		
    		outputResults.innerHTML += "<br/>";
    		outputResults.innerHTML += "Total incorrect answers: " + totalIncorrect;
    		
    		for ( var c=-1, k; k=els[++c]; ) {
    			if (els[c].type == 'radio') {
    				k.disabled = true;//(good idea to have this)
    			}
    		}
    		
    		Quiz.scoreIt.disabled = true; //(required - without it bugs will crawl all over you)
    		Quiz.scoreIt.style.backgroundColor = "#92bbC5";
    		}		
    	};
    	function loadEvnts() {
    		Quiz.initQuiz();
    		var scoreIt = document.getElementById('score');
    		Quiz.addEvent( scoreIt, 'click',  Quiz.scoreQuiz);
    	}
    	Quiz.addEvent( window, 'load',  loadEvnts);
    
    /* ]]> */
    </script>
    </head>
    <body>
    <form action="#" method="post" id="quizForm">
    <div id="page">
    	<h3 id="h">Simple Unobtrusive Javascript Quiz ... <em>by oVTech</em></h3>
    	
    	<div id="q">
    	<p style="font-family: 'Courier New'; border-bottom: 1px dashed #888; margin: 4px;padding: 8px;">
    		<strong><u>Quick Notes:</u></strong> <br />
    	 - Percentages are rounded up with round() - optionally you can use toFixed(1)<br />
    	 - if you leave a radio button blank, then it counts as a wrong answer<br />
    	 - After submition, the radio buttons & the submit button are disabled<br />
    	 - Red & green colors let you know which questions you got incorrect and which ones correct<br />
    	 - There is a results div at the end of the page with more information<br />
    	</p>
    		<div class="quizQ">
    		<h4>1. Inside which HTML tag do we put JavaScript code?</h4> 
    			<input type="radio" rel="0" value="a" name="grp0"/> &lt;script&gt; <br /> <!--Correct Answer: A-->
    			<input type="radio" rel="0" value="b" name="grp0"/> &lt;javascript&gt; <br />
    			<input type="radio" rel="0" value="c" name="grp0"/> &lt;jscript&gt; <br />
    		</div>
    
    		<div class="quizQ">
    		<h4>2. What is the correct syntax for referring to an external script called "xxx.js"?</h4>  
    			<input type="radio" rel="1" value="a" name="grp1"/> &lt;script type="text/javascript" href="xxx.js"&gt; <br />
    			<input type="radio" rel="1" value="b" name="grp1"/> &lt;script type="text/javascript" src="xxx.js"&gt; <br /> <!--Correct Answer: B-->
    			<input type="radio" rel="1" value="c" name="grp1"/> &lt;script type="text/javascript" name="xxx.js"&gt; <br />
    		</div>
    
    		<div class="quizQ">
    		<h4>3. The external JavaScript file must contain the &lt;script&gt; tag.</h4>  
    			<input type="radio" rel="2" value="a" name="grp2"/> True <br />
    			<input type="radio" rel="2" value="b" name="grp2"/> It is optional <br />
    			<input type="radio" rel="2" value="c" name="grp2"/> False <br /> <!--Correct Answer: C-->
    		</div>
    		
    		<div class="quizQ">
    		<h4>4. How do you create a function?</h4>  
    			<input type="radio" rel="3" value="a" name="grp3"/> function:fn()<br />
    			<input type="radio" rel="3" value="b" name="grp3"/> function=fn()<br />
    			<input type="radio" rel="3" value="c" name="grp3"/> function fn()<br /> <!--Correct Answer: C-->
    		</div>
    		
    		<div class="quizQ">
    		<h4>5. How do you write a conditional statement for executing some code if "k" is NOT equal to 5?</h4>  
    			<input type="radio" rel="4" value="a" name="grp4"/> if (k != 5)<br /> <!--Correct Answer: C-->
    			<input type="radio" rel="4" value="b" name="grp4"/> if(i = 5) <br />
    			<input type="radio" rel="4" value="c" name="grp4"/> if (i = !5)<br /> 
    		</div>
    		
    		<div style="padding:8px 2px;background:#ededed;">
    			<br />
    			<input type ="button" id="score" value="Score Quiz" /> 
    			<br /><br />
    			
    			<div id="results"></div>
    		</div>
    	</div>
    	
    		<br />
    		<p id="c">
    		<strong> - </strong>Copyright (c) nobody 2010 -> until 11111100100.<br />
    	    <strong> - </strong>Simple Unobtrusive JS Quiz created by <strong> - </strong> <em>oVTech.</em>	
    	   </p>
    		<br /> <br />
    </div>
    </form>
    </body>
    </html>
    Thank you very very very much!

  • #4
    New Coder
    Join Date
    May 2011
    Posts
    12
    Thanks
    7
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by bullant View Post
    Yep agree that this would normally all be done server side in the "real world" but I guess it is a common assignment for students learning javascript.

    Anyway just some food for thought:

    1) In general, I like to code with the view of trying to keep future maintenance down to a minimum. Hence I would prefer to put all the questions and answers in an array and then create the html dynamically. I wouldn't want to have to edit the html manually every time the questions and answers change.

    2) To increase useability I would have all the questions' options in a <label> so the user can click either the radio button or the text associated with it to select that answer.

    Also, I copied and pasted your code into a html file and nothing happens when I click the "Score quiz" button in both IE9 and FF4.

    Below is the demo (with a bonus question in the questions array ) I posted in the other thread you referred to. It doesn't include inline scripting either.

    Each row in the questions array contains the data for each question in the quiz. The first element in each row is the question itself. The second element is the option number for the correct answer to the question. The remaining elements are the options for that question.

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
            <title></title>
            <style type="text/css">
                fieldset {
                    width: 30%;
                    border: 1px solid green;
                }
                fieldset label {
                    display: block;
                }
            </style>
            <script type="text/javascript">
                var questions = [
                    ['What colour is the sun?','1','Yellow','Green','Blue'],
                    ['What is 2 x 3?','2',5,6,7,8],
                    ['What is the 3rd letter in Codingforums','3','z','r','d','a','t']
                ];
                function checkAnswers(){
                    var numCorrectAnswers = 0;
                    for(var i=0; i < questions.length; i++){
                        var radBtnsO = document.getElementsByName('q'+(i+1));
                        disableRadButtons(radBtnsO);
                        if(getAnswer(radBtnsO) == questions[i][1]){
                            ++numCorrectAnswers;
                            radBtnsO[0].parentNode.parentNode.firstChild.style.backgroundColor = 'green';
                        } else {
                            radBtnsO[0].parentNode.parentNode.firstChild.style.backgroundColor = 'red';
                        }
                    }
                    alert('Total correct answers = '+numCorrectAnswers);
                }
                function getAnswer(radBtnsO){
                    for(var i=0; i < radBtnsO.length; i++){
                        if(radBtnsO[i].checked){return radBtnsO[i].value;}
                    }
                    return false;
                }
                function disableRadButtons(radBtnsO){
                    for(var i=0; i < radBtnsO.length; i++){
                        radBtnsO[i].disabled = true;
                    }
                }
                window.onload=function(){
                    fldQuestionsO = document.getElementById('fldQuestions');
                    for(i=0; i < questions.length; i++){
                        var newDiv = document.createElement('div');
                        var newPara = document.createElement('p');
                        newPara.appendChild(document.createTextNode('Q'+(i+1)+' '+questions[i][0]));
                        newDiv.appendChild(newPara);
                        //create the radio buttons for each question
                        var radValue = 1;
                        for(j=2; j < questions[i].length; j++) {
                            var newLabel = document.createElement('label');
                            var newRadBtn = document.createElement('input');
                            newRadBtn.setAttribute('type', 'radio');
                            newRadBtn.setAttribute('name', 'q'+(i+1));
                            newRadBtn.setAttribute('value', radValue++);
                            newLabel.appendChild(newRadBtn);
                            newLabel.appendChild(document.createTextNode(questions[i][j]));
                            newDiv.appendChild(newLabel);
                        }
                        fldQuestionsO.appendChild(newDiv);
                    }
                    document.getElementById('btnSubmit').onclick=checkAnswers;
                }
            </script>
        </head>
        <body>
            <div>
                <fieldset id="fldQuestions"></fieldset>
                <button id="btnSubmit">Submit</button>
            </div>
        </body>
    </html>
    Thank you, your help is very much appreciated.

  • #5
    Banned
    Join Date
    Feb 2011
    Posts
    2,699
    Thanks
    13
    Thanked 395 Times in 395 Posts
    you're welcome

  • #6
    Senior Coder
    Join Date
    Apr 2011
    Location
    London, England
    Posts
    2,120
    Thanks
    15
    Thanked 354 Times in 353 Posts
    Interesting, thank you

    Of course, I cheated
    Code:
    alert(Quiz.correctAnswers.join(','));
    Could move the correctAnswers array into the scoreQuiz method as a private member variable
    Code:
    		scoreQuiz: function () {
    			var totalCorrect = 0;
    			var totalIncorrect = 0;
    			var correctAnswers = ["a", "b", "c", "c", "a"]; 
    			var incorrect = [];
    			
    			Quiz.f = document.getElementById('quizForm');
    			
    			var els = Quiz.f.elements;
    			
    			var quizWrap = document.getElementById('q');
    			var outputResults = document.getElementById('results');
    			
    			for (var i = 0; i<correctAnswers.length; ++i) {
    				if (Quiz.answers[i] == correctAnswers[i]) {
    but I only mention this out of academic interest
    "I'm here to save your life. But if I'm going to do that, I'll need total uninanonynymity." Me Myself & Irene.
    Validate your HTML and CSS

  • #7
    Regular Coder oVTech's Avatar
    Join Date
    Nov 2010
    Location
    USA
    Posts
    296
    Thanks
    4
    Thanked 54 Times in 52 Posts
    Quote Originally Posted by bullant View Post
    Also, I copied and pasted your code into a html file and nothing happens when I click the "Score quiz" button in both IE9 and FF4.
    Bullant, for some reason when I paste the code here, this forums adds this line in my getTarget function: "rel="nofollow" . If you remove that line then it should work. I have tested in FF4, IE8 & Chrome.

    If you see something else, please let me know! Thanks for the input.




    I don't know, I don't care, and it doesn't make any difference!
    -Albert Einstein-




  • #8
    Regular Coder oVTech's Avatar
    Join Date
    Nov 2010
    Location
    USA
    Posts
    296
    Thanks
    4
    Thanked 54 Times in 52 Posts
    Quote Originally Posted by bullant View Post
    2) To increase useability I would have all the questions' options in a <label> so the user can click either the radio button or the text associated with it to select that answer.
    Yes, I definitely like this one - Thanks!




    I don't know, I don't care, and it doesn't make any difference!
    -Albert Einstein-




  • #9
    Banned
    Join Date
    Feb 2011
    Posts
    2,699
    Thanks
    13
    Thanked 395 Times in 395 Posts
    Quote Originally Posted by oVTech View Post
    Bullant, for some reason when I paste the code here, this forums adds this line in my getTarget function: "rel="nofollow" . If you remove that line then it should work. I have tested in FF4, IE8 & Chrome.
    If you see something else, please let me know! Thanks for the input.
    hmmm....that's weird, it adding that extra bit of code

    It could be something to do with the editor you are using to write your code.

    Anyway, yep, removing that extra code allows your code to work in IE9 as well.

  • #10
    Regular Coder oVTech's Avatar
    Join Date
    Nov 2010
    Location
    USA
    Posts
    296
    Thanks
    4
    Thanked 54 Times in 52 Posts
    Quote Originally Posted by AndrewGSW View Post
    Interesting, thank you

    Of course, I cheated
    Code:
    alert(Quiz.correctAnswers.join(','));
    Could move the correctAnswers array into the scoreQuiz method as a private member variable
    Why not! Sure... adding the correctAnswers array into the scoreQuiz method makes sense. Thanks for the input!




    I don't know, I don't care, and it doesn't make any difference!
    -Albert Einstein-




  • #11
    Regular Coder oVTech's Avatar
    Join Date
    Nov 2010
    Location
    USA
    Posts
    296
    Thanks
    4
    Thanked 54 Times in 52 Posts
    Quote Originally Posted by bullant View Post
    hmmm....that's weird, it adding that extra bit of code

    It could be something to do with the editor you are using to write your code.

    Anyway, yep, removing that extra code allows your code to work in IE9 as well.
    Actually I am using Notepad++ and the extra code isn't included in my code even after it is saved as an HTML file. I think this forum's editor adds this to prevent "follow" links - you know... for SEO purposes. I can't take it out because when I paste my code into this forum's editor, the "rel="nofollow" thing isn't there, but after I have saved the thread then it shows up. Anyway, thanks for the input.




    I don't know, I don't care, and it doesn't make any difference!
    -Albert Einstein-




  • #12
    Banned
    Join Date
    Feb 2011
    Posts
    2,699
    Thanks
    13
    Thanked 395 Times in 395 Posts
    no problem

    I wasn't saying your editor inserts that code, but there might be something in your code (visible or embedded) that causes the forum to add that code when you paste it in a thread.

    I copy and paste code into threads often from either HTML-Kit or Netbeans and then edit it and I haven't experienced code being added to my posted coded.

  • #13
    New Coder
    Join Date
    May 2011
    Posts
    12
    Thanks
    7
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by oVTech View Post
    I have come upon many threads that ask about how to implement a JS quiz. Just yesterday Bullant & I were offering different options to someone. Like everything else in the world there are many ways of doing this. Nevertheless, this is how I went about it.

    I should mention to the newbies out there that JS quizes aren't made for serious testing, but just for fun. Just look at the code, and you will see what I mean.

    Although this example might have a little more code than some other examples, one good thing about it is that it avoids global variables and it does not include any inline javascript.

    Feel free to ask any questions and to suggest changes or addons. I would also like to see how someone else would implement such thing.
    Here is the whole page

    NOTE: This forum adds an extra line in my getTarget function so be aware when you cut and paste. Here is the line that the forum adds: "rel="nofollow". If you seen this anywhere in my code, just take it out. I am unable to take that piece of code out.
    Code:
    <!DOCTYPE html PUBLIC
    "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>SIMPLE UNOBTRUSIVE QUIZ JS</title>
    <style type="text/css">
    body {
    	background: #6d6d6d;
    }
    #page {
    	width: 962px;
    	padding: 2px;
    	margin: 22px auto;
    }
    #q {
    	border: 4px solid #6299C5;
    	padding: 0 8px;
    	background: #ededed;
    	-moz-box-shadow:0px 1px 8px #82ccc5;
    	-webkit-box-shadow:0px 1px 8px #82ccc5;
    	 box-shadow:0px 1px 8px #82ccc5;
    	-o-box-shadow:0px 1px 8px #82ccc5;
    }
    #q h4 {
    	padding: 4px 8px;
    	border-left: 4px solid #6299C5;
    }
    #q #results {border: 2px solid #6299C5; padding:8px; display:none;}
    div.quizQ {
    	border-bottom: 1px solid #bcbcbc;
    	background: #ededed;
    	padding: 12px;
    	margin: 0;
    }
    div.quizQ h3 {
    	margin-bottom: 8px;
    }
    #score {
    	background-color: #6299C5;
        border: 1px solid #cdcdcd;
    	padding: 8px 10px;
        color: #FFFFFF;
    	cursor: pointer;
    	font-weight: bold;
    }
    #h {
    	background-color: #6299C5;
        border: 3px solid #cdcdcd;
    	padding: 8px 10px;
        color: #FFFFFF;
    	font-weight: bold;	
    	-moz-box-shadow:0px 1px 8px #82ccc5;
    	-webkit-box-shadow:0px 1px 8px #82ccc5;
    	 box-shadow:0px 1px 8px #82ccc5;
    	-o-box-shadow:0px 1px 8px #82ccc5;
    }
    #c {
    	width: 777px; 
    	border:1px solid #bebebe; 
    	padding:6px;margin:0; 
    	color:#dfdfdf; 
    	font-family: "Courier New", Courier, monospace;
    	font-weight:bold; 
    	font-style: italic;
    }
    </style>
    <script type="text/javascript">
    /* <![CDATA[ */
    /*
    -I am not putting a copyright on this, but I will 
     appreciate it if you left my nickname in the created by... 
    */
    			 
    	///Simple-Unobtrusive-Quiz-JS created by oVTech
    	var Quiz = {
    		addEvent: function( elm, evType, fn ) {//(required)
    			if (elm.addEventListener) {
    				elm.addEventListener(evType, fn, false);
    			} else if (elm.attachEvent) {
    				elm.attachEvent('on' + evType, fn);
    			} else {
    				elm['on' + evType] = fn;
    			}
    		},
    		getTarget: function( e ) {//(required)
    			var target = window.event ? window.event.srcElement : e ? e.target : null;
    			if (!target){return false;}
    				while(target.nodeType!=1 && target.nodeName.toLowerCase()!='body'){
    					target=target.parentNode;
    				}
    			return target;
    		},
    	
    		//Start Quiz
    		answers: [],
    		correctAnswers: ["a", "b", "c", "c", "a"], 
    		
    		initQuiz: function () {
    			var arrInp = document.getElementsByTagName('input');
    			Quiz.scoreIt = document.getElementById('score')
    			for (var i=0; i<arrInp.length; i++) {
    				if (arrInp[i].type.toLowerCase() == "radio") {
    					Quiz.addEvent( arrInp[i], 'click', Quiz.getAnswer);
    				}
    			}
    		},
    		getAnswer: function (e) {
    			var thisRadio = Quiz.getTarget(e);
    			var which = thisRadio.getAttribute("rel");
    			var val = thisRadio.getAttribute("value");
    			var group = thisRadio.getAttribute("name");
    			Quiz.recordAnswer( which, val, group )
    		},
    		recordAnswer: function (question, userAnswer, groupName) {
    			Quiz.answers[question] = userAnswer;
    		},
    		scoreQuiz: function () {
    			var totalCorrect = 0;
    			var totalIncorrect = 0;
    			
    			var incorrect = [];
    			
    			Quiz.f = document.getElementById('quizForm');
    			
    			var els = Quiz.f.elements;
    			
    			var quizWrap = document.getElementById('q');
    			var outputResults = document.getElementById('results');
    			
    			for (var i = 0; i<Quiz.correctAnswers.length; ++i) {
    				if (Quiz.answers[i] == Quiz.correctAnswers[i]) {
    					++totalCorrect;
    					quizWrap.getElementsByTagName('h4')[i].style.backgroundColor = "#00CC33";
    				}
    				else {
    					++totalIncorrect;
    					quizWrap.getElementsByTagName('h4')[i].style.backgroundColor = "#FF0000";
    				}
    			}
    		outputResults.style.display = "block";
    		outputResults.innerHTML = "You scored " + totalCorrect + " out of " + Quiz.correctAnswers.length;
    		outputResults.innerHTML +=  ", which is " + Math.round(totalCorrect/Quiz.correctAnswers.length * 100) + "%.";
    		
    		outputResults.innerHTML += "<br/>";
    		outputResults.innerHTML += "Total incorrect answers: " + totalIncorrect;
    		
    		for ( var c=-1, k; k=els[++c]; ) {
    			if (els[c].type == 'radio') {
    				k.disabled = true;//(good idea to have this)
    			}
    		}
    		
    		Quiz.scoreIt.disabled = true; //(required - without it bugs will crawl all over you)
    		Quiz.scoreIt.style.backgroundColor = "#92bbC5";
    		}		
    	};
    	function loadEvnts() {
    		Quiz.initQuiz();
    		var scoreIt = document.getElementById('score');
    		Quiz.addEvent( scoreIt, 'click',  Quiz.scoreQuiz);
    	}
    	Quiz.addEvent( window, 'load',  loadEvnts);
    
    /* ]]> */
    </script>
    </head>
    <body>
    
    <form action="#" method="post" id="quizForm">
    <div id="page">
    	<h3 id="h">Simple Unobtrusive Javascript Quiz ... <em>by oVTech</em></h3>
    	
    	<div id="q">
    	<p style="font-family: 'Courier New'; border-bottom: 1px dashed #888; margin: 4px;padding: 8px;">
    		<strong><u>Quick Notes:</u></strong> <br />
    	 - Percentages are rounded up with round() - optionally you can use toFixed(1)<br />
    	 - if you leave a radio button blank, then it counts as a wrong answer<br />
    	 - After submition, radio buttons & submit button are disabled<br />
    	 - Red & green colors let you know which questions you got incorrect and which ones correct<br />
    	 - There is a results div at the end of the page<br />
    	</p>
    		<div class="quizQ">
    		<h4>1. Inside which HTML tag do we put JavaScript code?</h4> 
    			<input type="radio" rel="0" value="a" name="grp0"/> &lt;script&gt; <br /> <!--Correct Answer: A-->
    			<input type="radio" rel="0" value="b" name="grp0"/> &lt;javascript&gt; <br />
    			<input type="radio" rel="0" value="c" name="grp0"/> &lt;jscript&gt; <br />
    		</div>
    
    		<div class="quizQ">
    		<h4>2. What is the correct syntax for referring to an external script called "xxx.js"?</h4>  
    			<input type="radio" rel="1" value="a" name="grp1"/> &lt;script type="text/javascript" href="xxx.js"&gt; <br />
    			<input type="radio" rel="1" value="b" name="grp1"/> &lt;script type="text/javascript" src="xxx.js"&gt; <br /> <!--Correct Answer: B-->
    			<input type="radio" rel="1" value="c" name="grp1"/> &lt;script type="text/javascript" name="xxx.js"&gt; <br />
    		</div>
    
    		<div class="quizQ">
    		<h4>3. The external JavaScript file must contain the &lt;script&gt; tag.</h4>  
    			<input type="radio" rel="2" value="a" name="grp2"/> True <br />
    			<input type="radio" rel="2" value="b" name="grp2"/> It is optional <br />
    			<input type="radio" rel="2" value="c" name="grp2"/> False <br /> <!--Correct Answer: C-->
    		</div>
    		
    		<div class="quizQ">
    		<h4>4. How do you create a function?</h4>  
    			<input type="radio" rel="3" value="a" name="grp3"/> function:fn()<br />
    			<input type="radio" rel="3" value="b" name="grp3"/> function=fn()<br />
    			<input type="radio" rel="3" value="c" name="grp3"/> function fn()<br /> <!--Correct Answer: C-->
    		</div>
    		
    		<div class="quizQ">
    		<h4>5. How do you write a conditional statement for executing some code if "k" is NOT equal to 5?</h4>  
    			<input type="radio" rel="4" value="a" name="grp4"/> if (k != 5)<br /> <!--Correct Answer: C-->
    			<input type="radio" rel="4" value="b" name="grp4"/> if(i = 5) <br />
    			<input type="radio" rel="4" value="c" name="grp4"/> if (i = !5)<br /> 
    		</div>
    		
    		<div style="padding:8px 2px;background:#ededed;">
    			<br />
    			<input type ="button" id="score" value="Score Quiz" /> 
    			<br /><br />
    			
    			<div id="results"></div>
    		</div>
    	</div>
    	
    		<br />
    		<p id="c">
    		<strong> - </strong>Copyright (c) nobody 2010 -> until 11111100100.<br />
    	    <strong> - </strong>Simple Unobtrusive JS Quiz created by <strong> - </strong> <em>oVTech.</em>	
    	   </p>
    		<br /> <br />
    </div>
    </form>
    
    </body>
    </html>
    Thank you everyone for help. (:

  • #14
    Regular Coder
    Join Date
    Nov 2009
    Posts
    247
    Thanks
    4
    Thanked 22 Times in 22 Posts
    See, an AJAX alternative:

    AJAX Self-Grading Multiple Choice Quiz

    Typical contents of the email sent upon completion and submission of the quiz:
    Code:
    Date Administered: Thursday, 05/19/2011
    Student: Joe 
    ID: 12345
    Course: 4th Period Geography 
    Quiz Name:  Geography Quiz 1 
    Number of Questions: 5
    Correct Answers: 3
    Incorrect Answers: 2
    Skipped Questions: 0
    Score: 60%
    Time Used: 01:15
    Last edited by Sciliano; 05-19-2011 at 01:39 PM.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •