Creating a Quiz Application - Exercise

Contact Us or call 1-877-932-8228
Creating a Quiz Application - Exercise

Creating a Quiz Application

Duration: 30 to 45 minutes.

In this exercise, you will create a quiz application that allows the user to save and resume later. It also protects the user from losing data if he/she accidentally refreshes.

  1. Open html5-storage/Solutions/saving-quiz-challenge.html in your browser and play with the application:
    1. Answer one or more questions and then refresh the browser. You will get a dialog giving you the chance to use refill the form with values stored in sessionStorage:
    2. Press OK and your values get added back.
    3. Refresh again and press Cancel on the dialog. Your values do not get added back.
    4. Refresh again. You don't get the JavaScript dialog because the sessionStorage key/value pairs were removed when you pressed Cancel in the previous step.
    5. Answer one or more questions again and click the Save My Answers for Later button.
    6. Close and reopen the browser. You will get a dialog giving you the chance to use refill the form with values stored in localStorage:
    7. If you click Cancel, the localStorage key/value pairs will be removed and you'll have to start the quiz over.
    8. If you click OK, the form will be refilled with your previous answers and they will be saved into sessionStorage.
    9. Also notice that the footer contains the time and date the quiz answers were last saved: This is the challenge to the exercise.
  2. Now open html5-storage/Exercises/saving-quiz.html in your editor.
  3. In the the addLoadEvents() function:
    1. Loop through the inputs and add event listeners that capture change events to save the associated key/value pair in sessionStorage. Don't forget to use the prefix.
    2. Add an event listener to the Save button to capture a click event and call saveAnswers.
    3. Call the refill() function at the end.
  4. Write the code in the saveAnswers() function to save all the answers in localStorage.
  5. The refill() function:
    1. calls hasAnswers(), which returns "session", "local", or false, depending on if and where it finds saved answers. If there are no saved answers, it returns without doing anything.
    2. declares some variables:
      1. confirmed - we'll change it to true if the user wishes to refill the form.
      2. msg - the message to ask the user if he/she wants to refill the form.
      3. questions - the question inputs
    3. loops through the inputs. On the first iteration, it prompts the user with the message. If the user clicks Cancel, the key/value pairs are deleted (via the deleteAnswers() function) and the function returns/ends. Otherwise, we iterate through the questions. This is where you come in...
    4. Add code to populate the question inputs from the appropriate storage location (based on the value of fillFrom).

Challenge

  1. Notice that an external script called dateFormat.js is included. That extends the Date object prototype with a format() method, which you use as follows:
    var now = new Date(); var dateMask = "yyyy-mm-dd H:MM:ss"; var formattedNow = now.format(dateMask);
  2. Use this to write out the date last saved to the output element below the form.
  3. You will need to store the date in sessionStorage and localStorage as appropriate. Don't forget the prefix.
  4. Note that the dateMask variable is already set in the code.

Solution:

html5-storage/Solutions/saving-quiz.html
<!DOCTYPE HTML>
---- C O D E   O M I T T E D ----
	function addLoadEvents() {
		document.getElementById('quiz').addEventListener("change",function() {
			updateMeasures();
		}, false);
		var questions = document.getElementById("quiz").getElementsByTagName("input");
		for (var i=0; i < questions.length; ++i)  {
			questions[i].addEventListener("change",function() {
				sessionStorage.setItem(prefix+this.id,this.value);
			},false);
		}
		document.getElementById("save").addEventListener("click",saveAnswers,false);
		refill();
	}
	
	function saveAnswers() {
		var questions = document.getElementById("quiz").getElementsByTagName("input");
		for (var i=0; i < questions.length; ++i)  {
			localStorage.setItem(prefix+questions[i].id,questions[i].value);
		}
	}
	
	function refill() {
		/*
		* if any answers were saved (local or session), then let's fill the form with the saved answers.
		* hasAnswers() returns either "local", "session", or false
		*/
		var fillFrom = hasAnswers();
		//if no answers were saved, we can't refill the form so let's just  get out of the function with "return"
		if (!fillFrom) return;
		/*
		* if we get to this point, then we know we have answers saved that will be used to refill the form
		* var "confirmed" will be used to have the user confirm the refilling of the answers (false by default) 
		*/
		var confirmed=false;
		//this is the message the user will see to confirm refilling the form
		var msg="It appears you have already started with the quiz. Would you like to continue from where you left off? (" + fillFrom + ")";
		//let's get all the questions
		var questions = document.getElementById("quiz").getElementsByTagName("input");
		//let's loop all the questions
		for (var i=0; i < questions.length; ++i)  {
			/*
			* if refilling is not confirm by the user, let's delete the answers and get out of this function
			* confirm() is a built-in JS method that displays a dialog box with the specified message, along with an OK and a Cancel button. The method returns true if the user clicks on "OK", else it returns false.
			*/
			if (!confirmed && !confirm(msg)) {
				deleteAnswers();
				return;	
			}
			/*
			* if we get to this point, then the user has confirmed refilling, let's set the var "confirmed" to true.
			*/
			confirmed=true;
			//if we're refilling from the session...
			if (fillFrom == "session") {
				/*
				* we need the || "" for IE, which returns null if the key is not found.
				* for the current question in the loop's iteration, set the corresponding value from the session 
				*/
				questions[i].value=sessionStorage.getItem(prefix+questions[i].id) || "";
				//We need the || "" for IE, which returns null if the key is not found.
			} 
			//else, we're refilling from the local storage...
			else {
				/*
				* again, we need the || "" for IE, which returns null if the key is not found.
				* for the current question in the loop's iteration, set the corresponding value from the local storage
				*/
				questions[i].value=localStorage.getItem(prefix+questions[i].id) || "";
				
				//let's also save the answer to the session
				sessionStorage.setItem(prefix+questions[i].id,questions[i].value);
			}
		}
		//after all the refilling is done, update the measures
		updateMeasures();
	}
---- C O D E   O M I T T E D ----

Challenge Solution:

html5-storage/Solutions/saving-quiz-challenge.html
<!DOCTYPE HTML>
---- C O D E   O M I T T E D ----
	var dateMask = "yyyy-mm-dd H:MM:ss";
	function addLoadEvents() {
		document.getElementById('quiz').addEventListener("change",function() {
			updateMeasures();
		}, false);
		var questions = document.getElementById("quiz").getElementsByTagName("input");
		for (var i=0; i < questions.length; ++i)  {
			questions[i].addEventListener("change",function() {
				var now=new Date();
				sessionStorage.setItem(prefix+this.id,this.value);
				document.getElementById("dateLastSaved").innerHTML=now.format(dateMask);
				sessionStorage.setItem(prefix+"dateLastSaved",now.format(dateMask));
			},false);
		}
		document.getElementById("save").addEventListener("click",saveAnswers,false);
		refill();
	}
	
	function saveAnswers() {
		var questions = document.getElementById("quiz").getElementsByTagName("input");
		var now=new Date();
		for (var i=0; i < questions.length; ++i)  {
			localStorage.setItem(prefix+questions[i].id,questions[i].value);
		}
		localStorage.setItem(prefix+"dateLastSaved",now.format(dateMask));
	}
	
	function refill() {
		var fillFrom = hasAnswers();
		if (!fillFrom) return;
		var now;
---- C O D E   O M I T T E D ----
		if (fillFrom == "session") {
			now = sessionStorage.getItem(prefix+"dateLastSaved");
		} else {
			now = localStorage.getItem(prefix+"dateLastSaved");
			sessionStorage.setItem(prefix+"dateLastSaved",now);
		}
		
		document.getElementById("dateLastSaved").innerHTML=now;
		updateMeasures();
	}
---- C O D E   O M I T T E D ----
<small>Answers last saved: <output id="dateLastSaved">not saved</output></small>
</body>
</html>
Next