Using JSON - Exercise

Contact Us or call 1-877-932-8228
Using JSON - Exercise

Using JSON

Duration: 30 to 40 minutes.

In this exercise, you will create an Ajax Quiz that uses JSON to pass data to the server.

  1. From the command line, navigate to the directory PassingData/Exercises/ and type npm start to start the Node.js server.
  2. Open PassingData/Exercises/AjaxQuiz.html in your editor.
  3. Review the HTML. Notice the questions are named "q1", "q2", and "q3" and that each question has an associated result div.
  4. When the page loads, we call the init() function, which attaches the checkAnswer() function to click events of all the input elements in the form.
  5. Write the checkAnswer() function. It should do the following:
    1. Create an object with two properties: question and answer, that hold the question number (e.g, "q3") and the user's answer (e.g, "3").
    2. Pass that object to the JSON parser to stringify. That should result in a string like: {"question" : "q3","answer" : "3"}
    3. Encode that, and store it in a new object as the strJSON property.
    4. Write out "checking..." to the appropriate result div while awaiting a response from the server.
    5. Using Ajax, send the data to the server to be processed by /AjaxQuiz, which expects a strJSON parameter to be posted.
    6. The callback function is respond() and expects two parameters: the XMLHttpRequest object and the result div.
  6. Write the respond() function so that it outputs the server response text to the appropriate result div.
  7. Test your solution in a browser by visiting http://localhost:8080/AjaxQuiz.html.

Challenge

Modify the quiz so that all questions are processed at once:

  1. Save AjaxQuiz.html as AjaxQuiz-challenge.html. Add a button at the bottom of the HTML form that, when clicked, calls checkQuiz() and passes it the form object.
  2. The checkQuiz() function should create a string with the following format:
    { "answers" : [a1, a2, a3] }
    where a1, a2, and a3 hold the user's answers, or "x" if the question is not answered. For example, if the user answers 3 for the first question, 2 for the second question, and leaves the third question unanswered, the JSON string should look like this: { "answers" : ["1", "3", "x"] }. The function should then pass that string to the /AjaxQuiz-challenge Node.js response route, which is already written.
  3. The server-side script will return a JSON string with the following format:
    {"q1":"Wrong","q2":"Right","q3":"Unanswered"}
  4. Based on the string the server returns, write out the server responses (e.g, "Wrong") to the q1Result, q2Result, and q3Result divs.

Solution:

PassingData/Solutions/AjaxQuiz.html
---- C O D E   O M I T T E D ----

	function respond(xmlhttp, resultDiv) {
		resultDiv.innerHTML = xmlhttp.responseText;
	}

	function checkAnswer(e) {
		var target = getTarget(e);
		var q = target.name;
		var a = target.value;
		var objQuestion = {
			question: q,
			answer: a
		};
		var resultDiv = document.getElementById(q + "Result");
		var strJSON = encodeURIComponent(JSON.stringify(objQuestion));
		resultDiv.innerHTML = "checking...";
		var xmlhttp = new XMLHttpRequest();
		xmlhttp.open("post", "AjaxQuiz", true);
		xmlhttp.onreadystatechange = function() {
			if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
				respond(xmlhttp, resultDiv);
			}
		}
		xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
		xmlhttp.send("strJSON=" + strJSON);
	}

	observeEvent(window, "load", init);
</script>
---- C O D E   O M I T T E D ----

Challenge Solution:

PassingData/Solutions/AjaxQuiz-challenge.html
---- C O D E   O M I T T E D ----

	function init() {
		var quiz=document.getElementById("quizForm");
		var sbtButton = document.getElementById("sbtButton");
		observeEvent(sbtButton,"click",function() {
			checkQuiz(quiz);
		});
	}
	
	function respond(xmlhttp) {
		var strJSON = decodeURIComponent(xmlhttp.responseText);
		var objJSON = JSON.parse(strJSON);
		for (i in objJSON) {
			document.getElementById(i + "Result").innerHTML = objJSON[i];
		}
	}
	
	function checkQuiz(form) {
		var a1 = getAnswer(form.q1);
		var a2 = getAnswer(form.q2);
		var a3 = getAnswer(form.q3);
		var objJSON = {
			"answers" : [a1, a2, a3]
		}
		var strJSON = JSON.stringify(objJSON);
		var xmlhttp = new XMLHttpRequest();
		xmlhttp.open("post","AjaxQuiz-challenge",true);
		xmlhttp.onreadystatechange = function() {
			if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
				respond(xmlhttp);
			}
		}
		xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
		xmlhttp.send("strJSON=" + encodeURIComponent(strJSON));
	}
	
	function getAnswer(radio) {
		for (var i=0; i<radio.length; i++) {
			if (radio[i].checked) {
				return radio[i].value;
			}
		}
		return null;
	}
	
	observeEvent(window,"load",init);
</script>
---- C O D E   O M I T T E D ----

<input type="button" id="sbtButton" name="Submit" value="Check Answers">
</form>
</body>
</html>
Next