jeudi 19 mars 2015

Comment créer un Quiz avec la technologies HTML5 (Responsive Web site)

PARTIE 1
HTML 

Voir la démo du quiz

Pré-requis: 
Quelques connaissances de base en HTML et en Javascript.

Ce tuto est destiné au personnes qui débutent en HTML5.
Vous pourrez créer un questionnaire à choix multiples et le mettre sur un site Web ! 
L'avantage de ce quiz c'est qu'il est « mobile-friendly ». Ce qui est très intéressant car aujourd'hui de plus en plus de personnes se se connectent à internet via leur mobile.
D'ailleurs Google mettra bientôt un label « mobile-friendly » près des liens dont les pages s’affichent correctement sur les navigateurs mobiles.

En gros pour qu'il y ai le logo « mobile-friendly » il faut que :


  • Les pages ne doivent pas utiliser la technologie Flash
  • Pour que l’utilisateur n'ait à zoomer les textes doivent être lisibles.
  • Les liens doivent être suffisamment éloignés les uns des autres...

Pour mener à bien ce projet il vous suffit d'avoir un editeur de texte comme Textpad, Wordpad, Notepad...

Mise en place du document HTML 
Ouvrez votre éditeur de texte et tapez: 

<!DOCTYPE HTML>
C'es une ligne de déclaration du type de document, qui indique au navigateur dans quel type de HTML la page a été écrite.

<!DOCTYPE HTML>
      <head>
      <title>MCQ en ligne</title>
       <link href="main.css" rel="stylesheet" type="text/css"/>
       <script src="jquery.js"></script>
       <script src="controller.js"></script>
      </head>
      <body>
       <div id="topbar">HTML5 MCQ Quiz</div>
       <div class="spacer"></div>
       <div id="navContent">
        <div id="game1"></div>
       <div id="game2"></div>
       </div>
      </body>
</html>
      
Ensuite :
<head> 
La balises "head "permet de fournir une description de votre site par le biais de mots ou textes décrivant votre site pour que les moteurs de recherche le reconnaissent et le référencent. Vous ouvrez la zone avec <head> et fermer avec </head>
Exemple :
<html>
<head>
</head>

</html>

<title>MCQ Quiz Sample</title>
C'est une ligne qui introduit le titre ou la description de la page. c'est ce qui apparait dans l'onglet de la page.

<link href="main.css" rel="stylesheet" type="text/css"/>

Cette ligne indique que votre page  va chercher un autre fichier appelé "main.css" pour trouver les  informations  sur la police, le fond, les couleurs, la taille du texte etc.

<script src="jquery.js"></script>
 Cette ligne appelle un fichier appelé "jquery.js" Qui est un fichier en javascipt.

<script src="controller.js"></script>

C'est une ligne qui appelle le fichier "controller.js" c'est un fichier en javascript qui permet de contrôler l'interactivité de quiz.

      <body>

La balise HTML"body" contient le corps du document html, c'est à dire toutes les informations visibles par l'internaute.

       <div id="topbar">HTML5 MCQ Quiz</div>

Cet balise :<div> ... </div> sert à structurer le document. Elle peut être accompagné d'un attribut comme :
id="..." : un identificateur global
class="..." : une liste de classes séparées par des espaces
style="..." : une information locale de style.

Le"topbar" introduit le titre de la page

<div class="spacer"></div>

"spacer" appel un espace

       <div id="navContent">
        <div id="game1"></div>
       <div id="game2"></div>
       </div>

Dans cette partie du code "navContent" contient les deux questions du quiz.


Vous pouvez maintenant Enregistrez le fichier sous index.html et l'ouvrir sur le navigateur de votre choix. Faire un clic doit sur le fichier index puis "ouvrir avec" : mozilla ou chrome...


PARTIE 2

Nous devons créer les fichiers suivants pour construire notre quiz:

- index.html. Qui est le fichier, la page principale ouverte par le navigateur.
- main.css, pour la feuilles de style (donnés sur la police, les couleurs etc)
- jquery.js, permettra d'améliorer le code en JavaScript
- controller.js, permet de contrôler le quiz
- activity.json, contient votre base de données avec les questions

pas besoin de logiciel spécial pour créer ces fichiers un simple éditeur de texte gratuit suffit.

Créer une base de données avec les questions.

Créez un fichier dans votre éditeur de texte nommé activity.json.
L'ouvrir et tapez les lignes suivante :

 {"quizlist":[
      {
      "question":"Brasilia est la capitale? ",
      "option1":"Du Brésil",
      "option2":"De l'Espagne",
      "option3":"Du Maroc"
      },
      {
      "question":"Quelle est la capitale de Lisbonne?",
      "option1":"Lisbonne",
      "option2":"Madrid",
      "option3":"Alger"
      },
      {
      "question":"comment je m'appelle?",
      "option1":"Elio",
      "option2":"Pedro",
      "option3":"Marco"
      }
      ]
      }

Chaque élément de la "quizlist" contient une question et trois options de réponse .
Nous allons écrire le test de manière à ce que ce soit toujours l'option 1 qui soit toujours la bonne réponse. Il faudra ensuite introduire l'apparition des questions en mode aléatoire (random). 

Si vous voulez changer ou ajouter des questions, ce est le seul fichier à modifier.
Vous pouvez ajouter autant de questions que vous voulez.

Enregistrez le fichier
PARTIE 3
Le CSS

Pour créer une feuille de style créez un fichier nomé "main.css" avec l'extension ".css" avec votre éditeur de texte.

html, body {
      margin: 0;
      padding: 0;
      background-image:url(carreBleu.png);
      font-family: Arial, Helvetica, sans-serif;
      }
Nous allons utiliser une image "carreBleu.png" comme arrière-plan de la page HTML. ( C'est est une petite image de 100x100 pixels qui se répète.  placer la dans votre dossier de projet.
Nous allons utiliser les polices Arial, Helvetica ou sans-serif.
La marge est à 0.
L'espacement vertical à 0 aussi.

#navContent{
      margin:auto;
      width:800px;
      height:400px;
      position:relative;
      overflow:hidden;
      }
#game1{
      margin:auto;
      width:800px;
      height:400px;
      right:0px;
      position:absolute;
      }
#game2{
      margin:auto;
      width:800px;
      height:400px;
      right:-800px;
      position:absolute;
      }

"navContent" contient Game1 et game2 , 
"margin: auto" il est aussi centré horizontalement sur la page .
width:800px et height:400px . Le quiz fait 800 pixels de large et 400 pixels de hauteur
overflow:hidden : Tout ce qui est en dehors  de cette zone sera caché.

" game2" commencera dehors de cette zone (à droite : -800px ) et sera donc donc sera caché.

"position:absolute" : son positionnement est relatif à l'élément parent positionné le plus proche au lieu d'être relatif à la fenêtre du navigateur

.questionText{
      font-size:18px;
      color:#FFF;
      }
.option{
      width:400px;
      height:30px;
      margin:15px;
      font-size:18px;
      color:#FFFFFF;
      padding:2px;
      padding-left:10px;
      border: 5px solid white;
      cursor:pointer;
      background-color:#3399FF;
      }
.option:hover{
      border:#FC0 solid 5px;
      color:#FC0;
      }

      font-size:18px;
      color:#FFF;
Ici vous avez la taille et la couleur du texte de la question ici blanc.

width:400px;  Largeur du texte
height:30px;  Hauteur du texte
margin:15px; Mage de 15 pixels
font-size:18px; Taille de la police
color:#FFFFFF; Couleur
padding:2px;  bordure à 2 pixels
padding-left:10px; bordure à gauche
border: 5px solid white; Cadre de 5 pixels blanc
cursor:pointer;
background-color:#3399FF;   Fond bleu


option:hover  Lorsque la sourie passe sur le texte :
border:#FC0 solid 5px;   le cadre change de couleur
color:#FC0;     le texte change de couleur aussi

#topbar{
      height:50px;
      margin:auto;
      margin-top:50px;
      color:#FFF;
      font-size:36px;
      font-family:Arial, Helvetica, sans-serif;
      width:800px;
      }
.spacer{
      height:30px;
      }

#topbar{    Paramètres du titre
height:50px; hauteur
margin:auto;  centrer horizontalement cet élément à l'intérieur de son conteneur
margin-top:50px; Marge par rapport au haut de la page
color:#FFF; Couleur du texte
font-size:36px; Taille de la police
font-family:Arial, Helvetica, sans-serif; 
width:800px; Taille du conteneur
      }

.spacer{
height:30px;
"spacer" ajoute simplement un espace de 30px entre le titre et le début du quiz

 .feedback1{
      width:150px;
      padding:5px;
      font-size:30px;
      color:#FFFFCC;
      background-color:#009900;
      font-family:Montserrat,Arial, Helvetica, sans-serif;
      text-align:center;
      }
           
.feedback2{
      width:150px;
      padding:5px;
      font-size:30px;
      color:#FFFFCC;
      background-color:#CC3300;
      font-family:Arial, Helvetica, sans-serif;
      text-align:center;
      }
"feedback1" et "feedback2"  donne les détaille du message qui apparaît si votre réponse est juste ou fausse.


PARTIE 4

Javascript
C'est la partie la plus difficile de la programmation. C'est aussi ce qui va rendre vie à votre quiz

Commencez par créez un un fichier appelé "controller.js" l'enregistrer et l'ouvrir.

$(document).ready(function () { 
    
    });

Permet l'exécution d'une fonction spécifique
$(document).ready(function(){ Ici ce trouve tout votre code   });
Les fonctions seront exécutés dans l'ordre d'apparition dans la page..

var questionNumber=0;
var questionBank=new Array();
var stage="#game1";
var stage2=new Object;
var questionLock=false;
var numberOfQuestions;
var score=0;
      

Une variable déclarée au début du script, avant toute les fonctions, sera globale. Elle est utilisée n'importe où dans le script .
Nous commençons par déclarer les différentes variables dont nous aurons besoin :

Les objets Array sont des constructeurs pour tableaux,  ils sont semblables à des listes.
Un objets "Array" est une série de variables . Par exemple, si a=["tiger","lion","panther"] alors a[0] c'est tiger, a[1] c'est lion et ainsi de suite.

‘stage’ et ‘stage2’ sont des objets qui vont servirent à désigner les contenu pour les questions actuelles et à venir.

Nous avons maintenant besoin d'aller chercher les données de notre fichier "activity.json"
$.getJSON('activity.json', function(data) {
    for(i=0; i<data.quizlist.length; i++){
      questionBank[i]=new Array;
      questionBank[i][0] = data.quizlist[i].question;
      questionBank[i][1] = data.quizlist[i].option1;
      questionBank[i][2] = data.quizlist[i].option2;
      questionBank[i][3] = data.quizlist[i].option3;
      }
      numberOfQuestions = questionBank.length;
      alert(questionBank);
})//getJSON

On utilise la commande "$.getJSON" pour lire le fichier "activity.json" 
"$.getJSON()"  Est un exemple de commande jquery.
Nous allons utiliser ces donnés pour construire un tableau appelé questionBank. On va utiliser un 
tableaux (Array) à deux dimensions.

Exemples :
Tableaux (Array) à une  dimensions.questionBank = ["cat","dog","fox"]; (questionBank[1]= "dog")

Tableaux (Array) à deux dimensions questionBank=[["cat", "dog", "fox"], ["lion", "tiger", "zebra"],[ "kangaroo", "koala", "wallaby"]]; (questionBank[1][2]= "zebra")

alert(questionBank) : fait apparaitre une fenètre (pop up) pour tester le code.

Affichage des questions


Trouver la ligne "alert(questionBank);" Supprimez-la et à sa place mettre "displayQuestion();"

Cela permet d'appeler la fonction pour afficher une question. Il peut être placé immédiatement après le code précédent qui se termine avec la ligne })//getJSON.
function displayQuestion(){
      var rnd=Math.random()*3; 
      rnd=Math.ceil(rnd);
      var q1;
      var q2;
      var q3;
     
   if(rnd==1){q1=questionBank[questionNumber][1]; q2=questionBank[questionNumber][2]; q3=questionBank[questionNumber][3];}1
      if(rnd==2){q2=questionBank[questionNumber][1]; q3=questionBank[questionNumber][2]; q1=questionBank[questionNumber][3];}
      if(rnd==3){q3=questionBank[questionNumber][1];q1=questionBank[questionNumber][2];q2=questionBank[questionNumber][3];}
    
    $(stage).append('<div class = "questionText">' + questionBank[questionNumber][0] + '</div><div id= "1" class="option">'+q1+'</div> <div id="2" class="option">'+q2+'</div> <div id="3" class="option">'+q3+'</div>');
    
    $('.pix').click(function(){
      if(questionLock==false){questionLock=true; 
      //correct answer
      if(this.id==rnd){
      $(stage).append('<div class="feedback1">CORRECT</div>');
      score++;
      }
      //wrong answer 
      if(this.id!=rnd){
      $(stage).append('<div class="feedback2">WRONG</div>');
      }
      //setTimeout(function(){changeQuestion()},1000);
      }})
      }//display question
Tout d'abord , nous allons déclarer une variable rnd  pour générer un nombre aléatoire entre 0 et 2.
Nous complétons ensuite ce numéro en utilisant Math.ceil() de sorte que nous nous retrouvons avec un nombre entier entre 1 et 3.

Nous allons utiliser ce nombre aléatoire pour choisir le rythme avec lequel les options seront affichées . Si "rnd" est égal à un, alors "q1" se réfère à la première option, est aussi la réponse.
Si "rnd" est égal à deux, alors q2 est la réponse et q1 et q3 sont les options fausses.

Nous allons ajouter du contenu au "stage" dont les références de "#game1".
 Nous ajoutons du contenu HTML à la page dynamique avec notre code.

$(stage).append('<div class = "questionText">' + questionBank[questionNumber][0] + '</div><div id= "1" class="option">'+q1+'</div> <div id="2" class="option">'+q2+'</div> <div id="3" class="option">'+q3+'</div>');
En ajoutant d'abord le texte de la question , puis en ajoutant les options et les informations de formatage.
Notez que chaque option se voit attribuer un Id de 1,2 ou 3. Nous allons utiliser cet Id pour vérifier la réponse.

$('.pix').click(function(){
      if(questionLock==false){questionLock=true; 
      //correct answer
      if(this.id==rnd){
      $(stage).append('<div class="feedback1">CORRECT</div>');
      score++;
      }
      //wrong answer 
      if(this.id!=rnd){
      $(stage).append('<div class="feedback2">WRONG</div>');
      }
      //setTimeout(function(){changeQuestion()},1000);
      }})
Dans cette partie du code on détecte un «clic» - mais permettra aussi de détecter une touche sur un appareil mobile . Il permet aussi de «bloquer» une question de telle sorte que , une fois répondu , elle ne peut êtreaffiché à nouveau.

Pour vérifier la réponse , on utilise la ligne : if(this.id==rnd){}
Dans ce cas ‘this’ est l'élément qui a été cliqué et "this.id" est le numéro d'identification.
si le numéro d'identification coïncide avec notre  variable "rnd", c'est la bonne réponse . Sinon , c'est la mauvaise réponse :
if(this.id!=rnd){}
En JavaScript, ! = Signifie  n'est pas égal à .

Si la réponse est juste , nous ajoutons un autre morceau de code HTML avec le message CORRECT
Si la réponse est fausse , le message WRONG apparait "feedback2"

La  ligne de code commençant par "setTimeout ( )" est desactivé pour l'instant. Les deux barres obliques ( // ) au début d'une ligne sont utilisées pour des commentaires , mais on peut également les utiliser pour désactiver temporairement un code

Transition entre les questions
Nous devons maintenant  voir comment passer à la question suivante. Une seconde après la réponse ai été sélectionné , puis déplacez cette question hors de l'écran vers la gauche tout en affichant  la nouvelle question dans l'écran de droite.


réactiver cette ligne de code en supprimant les doubles barres obliques :
setTimeout(function(){changeQuestion()},1000);

Cette ligne nous dit d'attendre 1000 millisecondes (une seconde) , puis exécuter la fonction "changeQuestion ( ) "

Voici cette fonction
function changeQuestion(){

 questionNumber++;

 if(stage=="#game1"){stage2="#game1";stage="#game2";}
 else{stage2="#game2"; stage="#game1";}

 if(questionNumber < numberOfQuestions){displayQuestion();}
 //else{displayFinalSlide();}

 $(stage2).animate({"right": "+=800px"} , "slow" , function() { $(stage2).css('right' , '-1800px'); $(stage2).empty(); });
 $(stage).animate({"right": "+=800px"},"slow", function() {questionLock=false;});
}//change question

questionNumber++;
La première chose est d'incrémenter la variable questionNumber de 1.

if(stage=="#game1"){stage2="#game1";stage="#game2";}
 else{stage2="#game2"; stage="#game1";}
Code pour passer d'un question à l'autre.

Nous allons toujours utiliser "stage" pour amener la nouvelle question et retiré l'ancienne

if(questionNumber < numberOfQuestions){displayQuestion();}
 //else{displayFinalSlide();}

Cette ligne vérifie si nous pouvons changer de question. La dernière partie est temporairement désactivée afin que nous puissions tester cette fonction .

$(stage2).animate({"right": "+=800px"} , "slow" , function() { $(stage2).css('right' , '-1800px'); $(stage2).empty(); });
 $(stage).animate({"right": "+=800px"},"slow", function() {questionLock=false;});
Nous utilisons ensuite un morceau de code de jQuery pour faire la transition animé des éléments de la page , donnant la direction , la vitesse et l'exécution d'une fonction lorsque la transition est terminée.

Lorsque les transitions sont fini , nous nous déplaçons "stage2" hors de l'écran vers la droite en modifiant les Propriétés CSS  "$(stage2).css('right' , '-800px'); "
Puis nous vidons son contenu ($(stage2).empty();)  et il va rester là en attendant la prochaine question.

Lorsque le "stage1" a achevé sa transition , nous enlevons le verrou "questionLock = false " de sorte que l'on puisse répondre à la question suivante.

Note de fin
On doit maintenant afficher une page avec le score lorsque le test est terminé .
Dans le code précédent supprimez des doubles barres obliques  devant  else{displayFinalSlide();}

function displayFinalSlide(){

 $(stage).append(" <div class='questionText' >You have finished the quiz!<br><br>Total questions: "+numberOfQuestions+"<br>Correct answers: "+score+"</div>");

}//display final slide

Nous allons ajouter un morceau de code pour afficher un message avec le résultat du quiz.

Pour que ça marche sur un smartphone.

Nous voulons que cela fonctionne jusqu'à une largeur d'environ 320 pixels qui est  la largeur d'un écran d'iPhone .
Nous allons reouvrir notre dossier CSS et rajouter ceci :

@media screen and (max-width:800px) {
 #topbar{margin-left:1%;margin-right:1%;width:96%;}
 #navContent{margin:1%;width:98%;} 
 #game1{margin:1%;width:98%;}
 #game2{margin:1%;width:98%;}
}

@media screen and (max-width:460px) {
 .option{width:80%;margin-top:5%;}
} 

Nous avons une largeur de page de 800 pixels , lorsque la largeur est inférieure à 800px ce qui est le cas d'un smartphone , nous changeons les règles avec des pourcentages. de sorte qu'il occupera 98% du de l'écran avec une marge de 1% de chaque côté.
Nous appliquons ça au titre aux questions etc.

Pour éviter les problèmes avec les téléphones Android , nous devons aller dans le fichier index.html et ajoutez cette ligne dans la section <head>
<meta name=viewport content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> 

Cela garantit qu'Android utilise bien la largeur de téléphone. Il empêche également le zoom avant et arrière.

Dépannage 
Lors du test en ligne, Chrome ne sera pas lire les fichiers ".json". Utilisez Firefox pour lancer le qcm en local.

Attention! Certains services d'hébergement Web ne reconnaissent toujours pas les fichiers en  .json