Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Share data across e-book pages

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?

like image 958
Baz Avatar asked Aug 24 '18 07:08

Baz


People also ask

Can you share EPUB files?

Select Settings in the menu. Check the 'Enable PDF uploading' box. This makes it possible to add both EPUB and PDF files. Send the EPUB file to your Android.

Can I share eBook from iBooks?

How to share a book in Apple Books with iCloud Family Sharing. If you're using iCloud Family Sharing, any family member can download any book that any other family member has purchased in Apple Books at no extra charge. It's the digital equivalent of handing a book you've purchased to someone else in your household.


2 Answers

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:

  • Epub.js - JavaScript library for rendering ePub documents in the browser;
  • Readium-js - EPUB processing engine written in Javascript

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?

The recommended solution from me

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.

like image 94
Bharata Avatar answered Oct 11 '22 21:10

Bharata


According to the specification, when rendition:layout is set to pre-paginated:

The given Rendition is pre-paginated. Reading Systems MUST produce exactly one page per spine itemref when rendering.

The way I understand it is that no, it is not valid to have multiple pages in the same file (if I remember correctly, it's only files that can be referenced in the spine/manifest). However, it might be invalid essentially for the purpose of <nav> stuff... Feel free to test extensively, but IMHO it's not worth it because...

...about storing data, the IDPF sets a lot of rules towards readers' compliance. However, I seriously doubt a reading system that denies scripting would have much success, since about any interactive behavior requires scripts. Especially since this format is primarily intended for educational purposes, where interactions are a great addition. Plus, the scripts might be disabled by the user (as per the doc), sure: browsers have that too, who uses it? Hence, localStorage. ;)

Lastly, as commented above, it's - indeed - not browser-rendered, but the context is really close to a Web browser, with some limitations. Practically, one could (should?) assume the reader is a browser, simply confined to the universe described by its application/oebps-package+xml package file with a fancy MIME type.

like image 34
Stock Overflaw Avatar answered Oct 11 '22 20:10

Stock Overflaw