I want to have a quiz at the end of a chapter in my fixed layout epub3 e-book. This quiz will stretch across a number of pages and will be multiple choice in nature. Each question will consist of the question itself and four options, each with a radio button. At the end of the quiz, the user will click a button to reveal their overall result. To do this I will need to share information between pages. One way of doing this is for all the pages to be in one XHTML document and then I can store the answers the student gives for each question in a javascript variable. However, is it valid to have multiple pages of a fixed layout epub3 book in the same XHTML file?, as I am doing here:
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
<head>
<title>My Book</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<style>
p.pagebreak {
page-break-after:always;
}
</style>
</head>
<body>
<p>
Text on Page 1
</p>
<p class="pagebreak"></p>
<p>
Text on Page 2
</p>
<p class="pagebreak"></p>
<p>
Text on Page 3
</p>
</body>
</html>
It looked fine in iBooks.
Alternatively, if multiple pages are used, I could store the students' answers using window.sessionStorage
. However, I've no idea how many readers support storage. I would like the quiz to work for iBooks and also for Android and Windows Tablets and Desktops.
How would you advise I implement my quiz?
I think that you do not really understand how complex all this is to implement and to support using ePub. I would like to recommend you to read about ePub file format. See the latest version of ePub format specification too.
An ePub publication (inclusive ePub3) is delivered as a single file. This file is an unencrypted zipped archive containing a set of interrelated resources.
An example ePub file structure:
--ZIP Container--
mimetype
META-INF/
container.xml
OEBPS/
content.opf
chapter1.xhtml
ch1-pic.png
css/
style.css
myfont.otf
toc.ncx
Citate from your question: I would like the quiz to work for iBooks and also for Android and Windows Tablets and Desktops.
The browsers do not support a reading and a displaying from this type of files natively. If you want really to have this then you have to programm all this. It is for you not really necessary because we have already JavaScript libraries:
But do not forget: in both cases they have as a prerequisite a NodeJS server.
Then you have to think about all the resources for this process - it is really too much! Too much development work, to much resources, and too much energy wasting!
Because of all this nobody do it on this way.
Citate from your question: How would you advise I implement my quiz?
You can have all your questions for your quiz in one HTML file and you can save all the answers in array. I have prepared for you the demonstrations example:
var activePage = 0,
pages = document.querySelectorAll('.quiz-page'),
answers = [];
function goToNext(buttonObj)
{
var questions = document.getElementsByName('question' + activePage),
value = -1;
for(var i = 0; i < questions.length; i++)
if(questions[i].checked)
value = questions[i].value;
if(value < 0)
{
alert('Please choose one value!');
return;
}
else
// save the answer in array
answers[activePage] = value;
activePage++;
for(var i = 0; i < pages.length; i++)
pages[i].style.display = 'none';
if(activePage < pages.length)
pages[activePage].style.display = 'block';
else
{
buttonObj.style.display = 'none';
sendResultsToServer();
}
if(activePage == pages.length - 1)
buttonObj.value = 'Get Results';
}
function sendResultsToServer()
{
var strAllAnswers = answers.join(',');
console.log('Answers indexes (one on each page): ' + strAllAnswers);
//TODO: Send results to server using AJAX
//... your AJAX code ...
// Following example of code is for server side checking of results.
// If you want you could do this checking of results on the
// client side, but somebody could know all the correct
// results if you do it on the client side. Be careful!
var questions =
[
{
question: 'True or false: 3 + 3 = 6?',
answers: ['False','True'],
correctAnswer: 1
},
{
question: 'What sound does a dog make?',
answers: ['Meow','Mooo','Woof'],
correctAnswer: 2
},
{
question: 'Which from movie names below is a science fiction movie?',
answers: ['Star Wars','Planet of the Apes','Lion King','Shrek'],
correctAnswer: 1
},
];
var arAllAnswers = strAllAnswers.split(',');
var result = '<h3>Results</h3>';
for(var i = 0; i < questions.length; i++)
{
result += '<p><b>' + questions[i].question + '</b></p>';
result += 'Your answer was: ' + questions[i].answers[arAllAnswers[i]] + '<br>';
result += 'Correct answer is: ' + questions[i].answers[questions[i].correctAnswer];
}
var resultPage = document.querySelector('#result');
resultPage.innerHTML = result;
resultPage.style.display = 'block';
}
label{cursor:pointer}
<div class="quiz-page">
<p><b>Question 1 of 3.</b> True or false: 3 + 3 = 6?</p>
<label><input type="radio" name="question0" value="0">False</label><br>
<label><input type="radio" name="question0" value="1">True</label>
</div>
<div class="quiz-page" style="display:none">
<p><b>Question 2 of 3.</b> What sound does a dog make?</p>
<label><input type="radio" name="question1" value="0">Meow</label><br>
<label><input type="radio" name="question1" value="1">Mooo</label><br>
<label><input type="radio" name="question1" value="2">Woof</label>
</div>
<div class="quiz-page" style="display:none">
<p><b>Question 3 of 3.</b> Which from movie names below is a science fiction movie?</p>
<label><input type="radio" name="question2" value="0">Star Wars</label><br>
<label><input type="radio" name="question2" value="1">Planet of the Apes</label><br>
<label><input type="radio" name="question2" value="2">Lion King</label><br>
<label><input type="radio" name="question2" value="3">Shrek</label>
</div>
<div id="result" style="display:none"></div>
<br>
<input type="button" value="Next" onclick="goToNext(this)">
This code should work for iBooks, for Android, for Windows Tablets and for Desktops.