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.
Page 2 of 2 FirstFirst 12
Results 16 to 22 of 22
  1. #16
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,304
    Thanks
    28
    Thanked 276 Times in 270 Posts
    I took another look at the code I wrote, tested it in a few browsers, and realized that it doesn't work properly in IE9-11, so I rewrote it with fixes.

    IE9-11 don't support the relatively new template element which means that getElementsByClassName doesn't return a correct count that excludes the class attribute of the internal elements. I wasn't aware that class attributes inside this element aren't counted by getElementsByClassName. I removed the element, which I shouldn't have used in the first place, reverted the querySelectorAll change, and turned the instructional code into an HTML comment.

    IE9 doesn't support the relatively new hidden attribute, so I hard-coded support for that in the style sheet.

    IE9 lists all answers in the "Correct Answers" list preceded by "0." in a styling bug I had never seen before. I fixed that with some IE9-only code, but there's still an unusual amount of space preceding each list item in IE9. I have no solution for that issue.

    IE9 doesn't support the required attribute, so I coded in support for the attribute manually for browsers that don't support the attribute. Then I found that IE10 and IE11 only enforce the required attribute on the first form submission, so IE9-11 all use the aforementioned code.

    Then I realized that IE10 and IE11 don't style radio buttons correctly when it enforces the required attribute and the attribute is only present on one of the radio button elements. So I ended up specifying the attribute for every radio button element.

    After so much pain, I turned the quiz code into a live demo: https://patrick.dark.name/web.dev/de....submission.3/. Revised code follows:

    Code:
    <!doctype html>
    <html lang="en">
    	<head>
    		<meta charset="utf-8">
    		<title>Demo</title>
    		<style>
    			* { margin: 0; padding: 0; }
    			[hidden] { display: none; }
    			section { padding-left: 1rem; }
    			h1 { margin: 1rem 0 0.25rem; font: inherit; font-weight: bolder; }
    			#quiz { counter-reset: questions; }
    			#quiz dt { counter-increment: questions; margin: 0.25rem 0 0; }
    			#quiz dt::before { content: counter(questions) ". "; }
    			#quiz dd { margin-left: 1rem; }
    			#invalid\.submission\.warning, #quiz button { margin: 0.25rem 0; }
    			#invalid\.submission\.warning { color: crimson; }
    			#correct\.answers ol { list-style-position: inside; margin-left: 1rem; }
    		</style>
    	</head>
    	<body>
    		<section id="quiz">
    			<h1>Quiz</h1>
    			<form>
    				<dl>
    					<dt>Kind of fruit:</dt>
    					<dd><label><input type="radio" name="fruit" value="disk" required> disk</label></dd>
    					<dd><label><input type="radio" name="fruit" value="sofa" required> sofa</label></dd>
    					<dd><label><input type="radio" name="fruit" value="orange" required class="correct.answer"> orange</label></dd>
    					<dd><label><input type="radio" name="fruit" value="book" required> book</label></dd>
    					<dt>Kind of furniture:</dt>
    					<dd><label><input type="radio" name="furniture" value="banana" required> banana</label></dd>
    					<dd><label><input type="radio" name="furniture" value="chair" required class="correct.answer"> chair</label></dd>
    					<dd><label><input type="radio" name="furniture" value="pencil" required> pencil</label></dd>
    					<dd><label><input type="radio" name="furniture" value="eraser" required> eraser</label></dd>
    					<dt>Kind of mammal:</dt>
    					<dd><label><input type="radio" name="mammal" value="albatross" required> albatross</label></dd>
    					<dd><label><input type="radio" name="mammal" value="starfish" required> starfish</label></dd>
    					<dd><label><input type="radio" name="mammal" value="butterfly" required> butterfly</label></dd>
    					<dd><label><input type="radio" name="mammal" value="platypus" required class="correct.answer"> platypus</label></dd>
    					<!-- To add a new question, duplicate the following code and customize the “Question:”, “question.group.ID”, and “answer” text. Then, move the “class="correct.answer"” attribute to the input element representing the correct answer. 
    					<dt>Question:</dt>
    					<dd><label><input type="radio" name="question.group.ID" value="answer" required class="correct.answer"> answer</label></dd>
    					<dd><label><input type="radio" name="question.group.ID" value="answer" required> answer</label></dd>
    					<dd><label><input type="radio" name="question.group.ID" value="answer" required> answer</label></dd>
    					<dd><label><input type="radio" name="question.group.ID" value="answer" required> answer</label></dd>
    					-->
    				</dl>
    				<p id="invalid.submission.warning" hidden>You must answer all questions before submitting the form!</p>
    				<button>Get Score</button>
    				<button type="reset">Reset Quiz</button>
    			</form>
    		</section>
    		<section id="score" hidden>
    			<h1>Score</h1>
    			<p>The score is <output id="score.text">0</output>.</p>
    		</section>
    		<section id="correct.answers" hidden>
    			<h1>Correct Answers</h1>
    			<ol id="correct.answers.list"></ol>
    		</section>
    		<script>
    			(function () {
    				"use strict";
    				var quiz = document.getElementById("quiz");
    				var totalQuestions = quiz.getElementsByTagName("dt").length;
    				var correctAnswerRadioButtons = document.getElementsByClassName("correct.answer");
    				var scoreDenominator = (totalQuestions * 10).toString();
    				var scoreSection = document.getElementById("score");
    				var scoreText = document.getElementById("score.text");
    				var correctAnswersSection = document.getElementById("correct.answers");
    				var answersRadioButtonsGroupIDs = [];
    				var invalidSubmissionWarning = document.getElementById("invalid.submission.warning");
    				function fillCorrectAnswersList() {
    					var correctAnswerRadioButtonIndex = 0;
    					var correctAnswersList = document.getElementById("correct.answers.list");
    					var correctAnswerListItem = null;
    					while (correctAnswerRadioButtonIndex < correctAnswerRadioButtons.length) {
    						correctAnswerListItem = document.createElement("li");
    						correctAnswerListItem.textContent = correctAnswerRadioButtons.item(correctAnswerRadioButtonIndex).value;
    						correctAnswersList.appendChild(correctAnswerListItem);
    						correctAnswerRadioButtonIndex += 1;
    					}
    				}
    				function validateRequiredFields() {
    					var answersRadioButtonsGroupIDIndex = 0;
    					var answersRadioButtonsGroup = null;
    					var answersRadioButtonsGroupIndex = 0;
    					var answersRadioButtonsGroupHasValue = false;
    					while (answersRadioButtonsGroupIDIndex < answersRadioButtonsGroupIDs.length) {
    						answersRadioButtonsGroup = document.getElementsByName(answersRadioButtonsGroupIDs[answersRadioButtonsGroupIDIndex]);
    						if (answersRadioButtonsGroup.item(0).hasAttribute("required")) {
    							answersRadioButtonsGroupIndex = 0;
    							while (answersRadioButtonsGroupIndex < answersRadioButtonsGroup.length) {
    								if (answersRadioButtonsGroup.item(answersRadioButtonsGroupIndex).checked === true) {
    									answersRadioButtonsGroupHasValue = true;
    									break;
    								}
    								answersRadioButtonsGroupIndex += 1;
    							}
    							if (answersRadioButtonsGroupHasValue === false) {
    								return false;
    							}
    							answersRadioButtonsGroupHasValue = false;
    						}
    						answersRadioButtonsGroupIDIndex += 1;
    					}
    					return true;
    				}
    				function resetScore() {
    					if (!invalidSubmissionWarning.hasAttribute("hidden")) {
    						invalidSubmissionWarning.setAttribute("hidden", "");
    					}
    					if (!scoreSection.hasAttribute("hidden")) { // && !scoreSection.hasAttribute("hidden")
    						scoreSection.setAttribute("hidden", "");
    						correctAnswersSection.setAttribute("hidden", "");
    					}
    					if (scoreText.textContent !== "0") {
    						scoreText.textContent = "0";
    					}
    				}
    				function getScore(formSubmissionEvent) {
    					formSubmissionEvent.preventDefault();
    					var requiredFieldsFilled = null;
    					var correctAnswerRadioButtonIndex = 0;
    					var scoreNumerator = 0;
    					if (typeof document.createElement("input").required === "undefined" || /Trident\/[6-7].0/.test(navigator.userAgent)) {
    						// Internet Explorer 10 and 11 have a buggy implementation of the required attribute.
    						requiredFieldsFilled = validateRequiredFields();
    						if (!requiredFieldsFilled) {
    							invalidSubmissionWarning.removeAttribute("hidden");
    							return;
    						}
    						else if (!invalidSubmissionWarning.hasAttribute("hidden")) {
    							invalidSubmissionWarning.setAttribute("hidden", "");
    						}
    					}
    					while (correctAnswerRadioButtonIndex < correctAnswerRadioButtons.length) {
    						if (correctAnswerRadioButtons.item(correctAnswerRadioButtonIndex).checked === true) {
    							scoreNumerator += 10;
    						}
    						correctAnswerRadioButtonIndex += 1;
    					}
    					scoreText.textContent = scoreNumerator.toString() + "/" + scoreDenominator;
    					scoreSection.removeAttribute("hidden");
    					correctAnswersSection.removeAttribute("hidden");
    					if (/Trident\/5.0/.test(navigator.userAgent)) { // Windows Internet Explorer 9 Bug Fix
    						// Official Bug Report: https://connect.microsoft.com/IE/feedback/details/657695/ordered-list-numbering-changes-from-correct-to-0-0
    						// Bug Fix: http://stackoverflow.com/questions/5584500/ordered-list-showing-all-zeros-in-ie9
    						if (correctAnswersSection.hasAttribute("class")) {
    							correctAnswersSection.setAttribute("class", correctAnswersSection.getAttribute("class"));
    						}
    						else {
    							correctAnswersSection.setAttribute("class", "");
    							correctAnswersSection.removeAttribute("class");
    						}
    					}
    				}
    				if (typeof document.createElement("input").required === "undefined" || /Trident\/[6-7].0/.test(navigator.userAgent)) {
    					// Internet Explorer 10 and 11 have a buggy implementation of the required attribute.
    					var correctAnswerRadioButtonIndex = 0;
    					while (correctAnswerRadioButtonIndex < correctAnswerRadioButtons.length) {
    						answersRadioButtonsGroupIDs.push(correctAnswerRadioButtons.item(correctAnswerRadioButtonIndex).getAttribute("name"));
    						correctAnswerRadioButtonIndex += 1;
    					}
    				}
    				fillCorrectAnswersList();
    				quiz.addEventListener("submit", getScore);
    				quiz.addEventListener("reset", resetScore);
    			})();
    		</script>
    	</body>
    </html>
    Last edited by Arbitrator; 02-11-2014 at 05:56 PM. Reason: I converted a namespace-aware method to a non-namespace-aware method.
    For every complex problem, there is an answer that is clear, simple, and wrong.

  2. Users who have thanked Arbitrator for this post:

    ranaran (02-12-2014)

  3. #17
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,981
    Thanks
    56
    Thanked 557 Times in 554 Posts
    I think you may have omitted this line in your posted code:
    Code:
    var namespaces = Object.create(null, { XHTML: { value: "http://www.w3.org/1999/xhtml" } });

  4. The Following 2 Users Say Thank You to xelawho For This Useful Post:

    Arbitrator (02-11-2014), ranaran (02-12-2014)

  5. #18
    New to the CF scene
    Join Date
    Feb 2014
    Location
    The Beautiful World
    Posts
    9
    Thanks
    12
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by jmrker View Post
    It is not only the number of questions, it is ALSO the array of correct answers.

    For each question there are (in your example) 4 responses for each question within the <li>
    Considered them numbered in sequence 0, 1, 2 or 3 for positions 1, 2, 3 and 4.
    Put the correct SEQUENCE value into the answer array for each question response POSITION.
    Code:
    var answers = [2,1,0];  // correlates to items 3, 2 and 1 of questions 1, 2 and 3.
    For your questions, the correct answer is the 3rd <li> position (sequence 2) in question #1
    and is the 2nd <li> position (sequence 1) in question #2.

    I added the 3rd question with the answer as position #1 (sequence 0).

    That's a really complicated answer for a really simple concept.
    In short, the answer array contains the sequence # for each position of each question and the # of questions is the length of the array.
    Ok jmrker , , I kind of understood you, please check this code after adding the fourth question and the answer is the first choice which I think it is equal = 0 in the array.

    Code:
    <html>
    <head>
    <title> Quiz </title>
    <script type="text/javascript"> <!-- archaic form: language="JavaScript" -->
    // Modified for: http://www.codingforums.com/showthread.php?t=317362
    
    var answers = [2,1,0,0];
    
    function getScore() {
      var score = 0, rbName = '', correctAnswers = "";
      var info = [];
      for (i=0; i<answers.length; i++) {
        rbName = 'q'+(i+1);
        info = getRBtnName(rbName);
        var sel = document.getElementsByName(rbName);
        ans = sel[answers[i]].value;
        correctAnswers += (i+1) + ". " + ans + "\n"; 
        if (info[0] == answers[i].toString()) { score++; }
      }
      score = (score/answers.length*100).toFixed(0);
      document.getElementById('percentage').value = score + "%";
      document.getElementById('solutions').value = correctAnswers;
    }
    function getScore() {
      var score = 0, rbName = '', correctAnswers = "";
      var info = [];
      for (i=0; i<answers.length; i++) {
        rbName = 'q'+(i+1);
        info = getRBtnName(rbName);
        var sel = document.getElementsByName(rbName);
        ans = sel[answers[i]].value;
        correctAnswers += (i+1) + ". " + ans + "\n"; 
        if (info[0] == answers[i].toString()) { score++; }
      }
      score = (score*10)+' / '+(answers.length*10);
      document.getElementById('percentage').value = score;
      document.getElementById('solutions').value = correctAnswers;
    }
    function getRBtnName(GrpName) {
      var sel = document.getElementsByName(GrpName);
      var fnd = -1;
      var str = '';
      for (var i=0; i<sel.length; i++) {
        if (sel[i].checked == true) { str = sel[i].value;  fnd = i; }
      }
    //  return fnd;   // return option index of selection
    // comment out next line if option index used in line above  
    //  return str;
      return [fnd,str];
    } 
    
    </script>
    </head>
    <body>
    
    <form name="quiz" action="" method="post" onsubmit="return false">
    1. Kind of fruit:
    <ol start="a" type="a">
     <li><label><input type="radio" name="q1" value="disk">disk</label></li>
     <li><label><input type="radio" name="q1" value="sofa">sofa</label></li>
     <li><label><input type="radio" name="q1" value="orange">orange</li>
     <li><label><input type="radio" name="q1" value="book">book</label></li>
    </ol>
    <p>
    
    2. Kind of furniture:
    <ol start="a" type="a">
     <li><label><input type="radio" name="q2" value="banana">banana</label></li>
     <li><label><input type="radio" name="q2" value="chair">chair</label></li>
     <li><label><input type="radio" name="q2" value="pencil">pencil</label></li>
     <li><label><input type="radio" name="q2" value="eraser">eraser</label></li>
    </ol>
    <p>
    
    3. Kind of color:
    <ol start="a" type="a">
     <li><label><input type="radio" name="q3" value="red">red</label></li>
     <li><label><input type="radio" name="q3" value="tree">tree</label></li>
     <li><label><input type="radio" name="q3" value="fence">fence</label></li>
     <li><label><input type="radio" name="q3" value="road">road</label></li>
    </ol>
    <p>
    
    4. part of body:
    <ol start="a" type="a">
     <li><label><input type="radio" name="q2" value="hand">hand</label></li>
     <li><label><input type="radio" name="q2" value="chair">chair</label></li>
     <li><label><input type="radio" name="q2" value="pencil">pencil</label></li>
     <li><label><input type="radio" name="q2" value="eraser">eraser</label></li>
    </ol>
    <p>
    
    <input type="button" value="Get score" onClick="getScore()">
    <input type="reset" value="Clear"><p>
    Score = <input type=text size=15 id="percentage"><br>
    Correct answers:<br>
    <textarea id="solutions" wrap="virtual" rows="4" cols="40"></textarea>
    </form>
    
    </body>
    </html>

  6. #19
    New to the CF scene
    Join Date
    Feb 2014
    Location
    The Beautiful World
    Posts
    9
    Thanks
    12
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by ranaran View Post
    Ok jmrker , , I kind of understood you, please check this code after adding the fourth question and the answer is the first choice which I think it is equal = 0 in the array. AND I forgot to tell u, it didn't work !

    Code:
    <html>
    <head>
    <title> Quiz </title>
    <script type="text/javascript"> <!-- archaic form: language="JavaScript" -->
    // Modified for: http://www.codingforums.com/showthread.php?t=317362
    
    var answers = [2,1,0,0];
    
    function getScore() {
      var score = 0, rbName = '', correctAnswers = "";
      var info = [];
      for (i=0; i<answers.length; i++) {
        rbName = 'q'+(i+1);
        info = getRBtnName(rbName);
        var sel = document.getElementsByName(rbName);
        ans = sel[answers[i]].value;
        correctAnswers += (i+1) + ". " + ans + "\n"; 
        if (info[0] == answers[i].toString()) { score++; }
      }
      score = (score/answers.length*100).toFixed(0);
      document.getElementById('percentage').value = score + "%";
      document.getElementById('solutions').value = correctAnswers;
    }
    function getScore() {
      var score = 0, rbName = '', correctAnswers = "";
      var info = [];
      for (i=0; i<answers.length; i++) {
        rbName = 'q'+(i+1);
        info = getRBtnName(rbName);
        var sel = document.getElementsByName(rbName);
        ans = sel[answers[i]].value;
        correctAnswers += (i+1) + ". " + ans + "\n"; 
        if (info[0] == answers[i].toString()) { score++; }
      }
      score = (score*10)+' / '+(answers.length*10);
      document.getElementById('percentage').value = score;
      document.getElementById('solutions').value = correctAnswers;
    }
    function getRBtnName(GrpName) {
      var sel = document.getElementsByName(GrpName);
      var fnd = -1;
      var str = '';
      for (var i=0; i<sel.length; i++) {
        if (sel[i].checked == true) { str = sel[i].value;  fnd = i; }
      }
    //  return fnd;   // return option index of selection
    // comment out next line if option index used in line above  
    //  return str;
      return [fnd,str];
    } 
    
    </script>
    </head>
    <body>
    
    <form name="quiz" action="" method="post" onsubmit="return false">
    1. Kind of fruit:
    <ol start="a" type="a">
     <li><label><input type="radio" name="q1" value="disk">disk</label></li>
     <li><label><input type="radio" name="q1" value="sofa">sofa</label></li>
     <li><label><input type="radio" name="q1" value="orange">orange</li>
     <li><label><input type="radio" name="q1" value="book">book</label></li>
    </ol>
    <p>
    
    2. Kind of furniture:
    <ol start="a" type="a">
     <li><label><input type="radio" name="q2" value="banana">banana</label></li>
     <li><label><input type="radio" name="q2" value="chair">chair</label></li>
     <li><label><input type="radio" name="q2" value="pencil">pencil</label></li>
     <li><label><input type="radio" name="q2" value="eraser">eraser</label></li>
    </ol>
    <p>
    
    3. Kind of color:
    <ol start="a" type="a">
     <li><label><input type="radio" name="q3" value="red">red</label></li>
     <li><label><input type="radio" name="q3" value="tree">tree</label></li>
     <li><label><input type="radio" name="q3" value="fence">fence</label></li>
     <li><label><input type="radio" name="q3" value="road">road</label></li>
    </ol>
    <p>
    
    4. part of body:
    <ol start="a" type="a">
     <li><label><input type="radio" name="q2" value="hand">hand</label></li>
     <li><label><input type="radio" name="q2" value="chair">chair</label></li>
     <li><label><input type="radio" name="q2" value="pencil">pencil</label></li>
     <li><label><input type="radio" name="q2" value="eraser">eraser</label></li>
    </ol>
    <p>
    
    <input type="button" value="Get score" onClick="getScore()">
    <input type="reset" value="Clear"><p>
    Score = <input type=text size=15 id="percentage"><br>
    Correct answers:<br>
    <textarea id="solutions" wrap="virtual" rows="4" cols="40"></textarea>
    </form>
    
    </body>
    </html>
    The code after adding fourth question

  7. #20
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,304
    Thanks
    28
    Thanked 276 Times in 270 Posts
    Quote Originally Posted by xelawho View Post
    I think you may have omitted this line in your posted code:
    Code:
    var namespaces = Object.create(null, { XHTML: { value: "http://www.w3.org/1999/xhtml" } });
    Good catch, although not the error exactly. I replaced querySelectorAll in the HTML version by copying from the live, XHTML version at the last minute and accidentally forgot to change getElementByTagNameNS to getElementByTagName. I'll fix that with a post edit in a moment.

    Quote Originally Posted by ranaran View Post
    The code after adding fourth question
    Your name="" values have to be unique. You're using the q2 name multiple times which technically makes answers to question four in your code answers to question two in actuality.
    For every complex problem, there is an answer that is clear, simple, and wrong.

  8. Users who have thanked Arbitrator for this post:

    ranaran (02-12-2014)

  9. #21
    Senior Coder jmrker's Avatar
    Join Date
    Aug 2006
    Location
    FL
    Posts
    3,091
    Thanks
    38
    Thanked 498 Times in 492 Posts

    Thumbs up

    Quote Originally Posted by ranaran View Post
    The code after adding fourth question
    Yes that is correct for the answer array,
    except you need to change the name of the 4th question to 'q4'.
    Otherwise you have a duplicated question 'q2'.

  10. Users who have thanked jmrker for this post:

    ranaran (02-12-2014)

  11. #22
    New to the CF scene
    Join Date
    Feb 2014
    Location
    The Beautiful World
    Posts
    9
    Thanks
    12
    Thanked 0 Times in 0 Posts
    Xelawho , thanks for giving a hand.


    Arbitrator & Jmrker YOU TWO Guys are Wonderful. All what can I do, is praying for you.

    I liked both codes.
    - The most important thing, I understood how to add more questions using these codes.
    AND
    - I tried them on my blog and both worked.


 
Page 2 of 2 FirstFirst 12

Tags for this Thread

Posting Permissions

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