<?xml version="1.0" encoding="UTF-8"?>
<quiz>
<question type="category">
  <category>
    <text>$course$/QCM de NSI/Première/Événements et formulaires</text>
  </category>
  <info format="html">
    <text><![CDATA[<p>Événements DOM (clic, saisie, soumission), gestion des<br/>
événements en JavaScript, balises de formulaire HTML<br/>
(<code>&lt;form&gt;</code>, <code>&lt;input&gt;</code>, <code>&lt;button&gt;</code>, <code>&lt;select&gt;</code>), méthodes<br/>
HTTP GET et POST, validation côté client.</p>]]></text>
  </info>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q01 : Événement</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'un <strong>événement</strong> dans le contexte<br/>
d'une page web ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Les éléments de la page <strong>déclenchent</strong> des<br/>
événements (clic, saisie, soumission) ; les<br/>
gestionnaires associés les <strong>écoutent</strong> et y<br/>
réagissent.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une modification CSS entièrement automatique</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une modification CSS<br/>
relève de la mise en<br/>
forme. Un évènement,<br/>
en JavaScript, est un<br/>
signal émis par le<br/>
navigateur ou l'utilisateur,<br/>
auquel le code peut<br/>
réagir.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un fichier média</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un fichier média (image,<br/>
son, vidéo) est une<br/>
ressource statique,<br/>
tandis qu'un évènement<br/>
est un signal dynamique<br/>
déclenché lors de<br/>
l'utilisation de la page.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une erreur de programmation</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un bug n'est pas un événement DOM.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une action de l'utilisateur ou du navigateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : les événements rendent la<br/>
page <strong>interactive</strong>. JavaScript permet<br/>
d'y réagir.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q02 : Événement de clic</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel est le nom de l'événement déclenché quand<br/>
l'utilisateur <strong>clique</strong> sur un élément ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Événements souris : <code>click</code>, <code>dblclick</code>,<br/>
<code>mousedown</code>, <code>mouseup</code>, <code>mousemove</code>,<br/>
<code>mouseenter</code>, <code>mouseleave</code>. Idem au clavier :<br/>
<code>keydown</code>, <code>keyup</code>, <code>keypress</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>mouseDown</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est un <strong>autre</strong> événement (pression<br/>
du bouton, sans relâcher).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>onclick</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est l'attribut/propriété d'écoute, pas<br/>
le nom de l'événement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>click</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>click</code> est le nom<br/>
standard. Pour l'écouter :<br/>
<code>el.addEventListener("click", ...)</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>tap</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est un événement tactile, distinct.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q03 : Balise form</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle balise HTML délimite un <strong>formulaire</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le formulaire envoie ses données vers<br/>
<code>action</code> quand l'utilisateur soumet (par<br/>
clic sur <code>&lt;button type="submit"&gt;</code> ou en<br/>
validant via Entrée).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>&lt;send&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>&lt;form&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>&lt;form&gt;</code> regroupe les<br/>
champs et permet de les soumettre<br/>
ensemble. Attributs clés : <code>action</code><br/>
(URL), <code>method</code> (GET/POST).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>&lt;input&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>&lt;input&gt;</code> est un <strong>champ</strong> de<br/>
formulaire, pas un conteneur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>&lt;formulaire&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q04 : Champ texte</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle balise crée un <strong>champ de saisie</strong> texte ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Types courants d'<code>&lt;input&gt;</code> : <code>text</code>,<br/>
<code>password</code>, <code>email</code>, <code>number</code>, <code>date</code>,<br/>
<code>checkbox</code>, <code>radio</code>, <code>submit</code>, <code>file</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>&lt;textbox name="champ"&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>&lt;text size="20"&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>&lt;input type="text"&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>&lt;input&gt;</code> est polyvalente,<br/>
<code>type</code> détermine son apparence et son<br/>
comportement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>&lt;entry&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q05 : Bouton</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment créer un <strong>bouton</strong> « Envoyer » qui<br/>
soumet le formulaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Trois types de bouton : <code>submit</code><br/>
(soumission, par défaut dans <code>&lt;form&gt;</code>),<br/>
<code>reset</code> (réinitialise les champs), <code>button</code><br/>
(générique, à manipuler en JS).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>&lt;button type="submit"&gt;Envoyer&lt;/button&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>&lt;button&gt;</code> est plus<br/>
flexible (peut contenir du HTML, des<br/>
icônes). <code>&lt;input type="submit"&gt;</code> est<br/>
historique mais valide.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>&lt;a&gt;Envoyer&lt;/a&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>&lt;a&gt;</code> est un <strong>lien</strong>, pas un<br/>
bouton de soumission.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>&lt;button type="button"&gt;Envoyer&lt;/button&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>type="button"</code> crée un bouton<br/>
inerte qui ne soumet <strong>pas</strong> le<br/>
formulaire ; il faut <code>type="submit"</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>&lt;submit&gt;Envoyer&lt;/submit&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante ; <code>submit</code><br/>
est une valeur de l'attribut <code>type</code>, pas<br/>
une balise.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q06 : Liste déroulante</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle balise crée une <strong>liste déroulante</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Variantes : <code>&lt;datalist&gt;</code> (suggestions sur un<br/>
champ texte), <code>multiple</code> sur <code>&lt;select&gt;</code><br/>
(sélection multiple).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>&lt;list&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>&lt;select&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>&lt;select&gt;</code> est le<br/>
conteneur, chaque choix étant une<br/>
<code>&lt;option value="..."&gt;texte&lt;/option&gt;</code><br/>
placée à l'intérieur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>&lt;dropdown&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>&lt;combo&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q07 : Étiquette</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>À quoi sert la balise <code>&lt;label&gt;</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Bonne pratique d'accessibilité : tout champ doit<br/>
avoir un <code>&lt;label&gt;</code> associé. Sans label, les<br/>
lecteurs d'écran ne peuvent pas annoncer<br/>
correctement le champ.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Associer une étiquette à un champ de formulaire</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : améliore l'<strong>accessibilité</strong><br/>
et l'ergonomie. Lier via<br/>
<code>&lt;label for="nomChamp"&gt;...&lt;/label&gt;</code> et<br/>
<code>&lt;input id="nomChamp"&gt;</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À mettre du texte en gras</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est <code>&lt;strong&gt;</code> ou <code>&lt;b&gt;</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À créer un titre</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : ce serait <code>&lt;h1&gt;</code>...<code>&lt;h6&gt;</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À étiqueter une variable interne du code JavaScript</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Une variable JavaScript<br/>
n'a pas d'étiquette<br/>
accessible aux lecteurs<br/>
d'écran. La balise<br/>
<code>&lt;label&gt;</code> agit sur la<br/>
structure du formulaire<br/>
HTML, pas sur le code.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q08 : Soumission</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel événement se déclenche quand un<br/>
<strong>formulaire est soumis</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour empêcher la soumission par défaut<br/>
(par exemple pour valider en JS) :<br/>
<code>event.preventDefault()</code> dans le<br/>
gestionnaire.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>send</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : événement inexistant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>submit</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : événement <code>submit</code><br/>
déclenché sur le <code>&lt;form&gt;</code>. À écouter pour<br/>
intercepter la soumission, par exemple pour<br/>
vérifier les champs avant l'envoi.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>change</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est un autre événement (changement de<br/>
valeur d'un champ).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>click</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le clic sur le bouton déclenche click,<br/>
mais l'événement de soumission est<br/>
<code>submit</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q09 : GET ou POST ?</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle méthode HTTP utilise-t-on pour<br/>
<strong>envoyer un mot de passe</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Règle pratique : GET pour récupérer des<br/>
données (recherche, lecture), POST pour<br/>
modifier l'état du serveur (création, envoi<br/>
de formulaire).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune des deux, HTTP ne convenant pas aux données sensibles</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pour transmettre un mot<br/>
de passe, on choisit<br/>
systématiquement la<br/>
méthode POST (avec HTTPS),<br/>
qui place les données dans<br/>
le corps de la requête<br/>
plutôt que dans l'URL.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>POST, les données voyageant dans le corps de la requête</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : avec POST, rien ne<br/>
transite par l'URL. Pour les données<br/>
sensibles, utiliser POST + HTTPS.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>GET, parce que la requête est plus rapide à envoyer</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : GET met les données dans l'URL,<br/>
ce qui est <strong>visible</strong> et logué dans<br/>
l'historique. À éviter pour les données<br/>
sensibles.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>GET, à condition de masquer le champ avec <code>type="password"</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>type="password"</code> masque seulement les<br/>
caractères à l'écran. Avec GET, le mot de passe<br/>
partirait quand même dans l'URL, visible dans<br/>
l'historique.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q10 : Formulaire complet</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Lequel de ces fragments est un <strong>formulaire valide</strong> demandant un nom et l'envoyant en<br/>
POST ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Attribut <strong><code>name</code></strong> essentiel : c'est sous<br/>
ce nom que la donnée arrive côté serveur.<br/>
Sans <code>name</code>, le champ n'est <strong>pas envoyé</strong>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>&lt;form action="/save" method="POST"&gt;
  &lt;label for="nom"&gt;Nom :&lt;/label&gt;
  &lt;input id="nom" type="text"&gt;
  &lt;button type="submit"&gt;Envoyer&lt;/button&gt;
&lt;/form&gt;</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : il manque l'attribut <code>name</code> sur<br/>
le champ. Sans <code>name</code>, la donnée saisie<br/>
n'est <strong>pas envoyée</strong> au serveur, même si<br/>
le formulaire se soumet sans erreur<br/>
apparente.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>&lt;form action="/save"&gt;
  &lt;label for="nom"&gt;Nom :&lt;/label&gt;
  &lt;input id="nom" name="nom" type="text"&gt;
  &lt;button type="submit"&gt;Envoyer&lt;/button&gt;
&lt;/form&gt;</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : sans attribut <code>method</code>, le<br/>
formulaire est envoyé avec la méthode par<br/>
défaut, <strong>GET</strong> (données visibles dans<br/>
l'URL), et non en POST comme demandé.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<pre><code>&lt;form action="/save" method="POST"&gt;
  Nom : &lt;input name="nom" type="text"&gt;
  &lt;input type="button" value="Envoyer"&gt;
&lt;/form&gt;</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>type="button"</code> crée un bouton<br/>
inerte qui ne déclenche <strong>pas</strong> la<br/>
soumission. Il faut <code>type="submit"</code> (ou<br/>
un <code>&lt;button&gt;</code> dont le type par défaut est<br/>
submit).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<pre><code>&lt;form action="/save" method="POST"&gt;
  &lt;label for="nom"&gt;Nom :&lt;/label&gt;
  &lt;input id="nom" name="nom" type="text"&gt;
  &lt;button type="submit"&gt;Envoyer&lt;/button&gt;
&lt;/form&gt;</code></pre>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>&lt;form&gt;</code> avec action et<br/>
method, <code>&lt;label&gt;</code> lié à <code>&lt;input&gt;</code> par<br/>
<code>for</code>/<code>id</code>, <code>name</code> (essentiel pour<br/>
identifier la donnée envoyée), bouton<br/>
submit.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q11 : Gestionnaire d'événement</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel code attache la fonction <code>handleClick</code> au<br/>
clic sur le bouton <code>btn</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Avantage d'<code>addEventListener</code> sur<br/>
<code>btn.onclick = handleClick</code> : on peut attacher<br/>
<strong>plusieurs</strong> gestionnaires au même événement.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>btn.onclick(handleClick)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>onclick</code> est une <strong>propriété</strong>,<br/>
pas une méthode. Il faut écrire<br/>
<code>btn.onclick = handleClick</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>btn.click(handleClick)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>btn.click()</code> <strong>déclenche</strong> le<br/>
clic, ne l'écoute pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>btn.addEventListener("click", handleClick)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : forme moderne et<br/>
recommandée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>btn.attachEvent("onclick", handleClick)</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>attachEvent</code> est l'ancienne API<br/>
propriétaire d'Internet Explorer,<br/>
abandonnée ; le standard est<br/>
<code>addEventListener</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q12 : Lire la valeur d'un champ</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment récupérer la valeur tapée dans<br/>
<code>&lt;input id="nom"&gt;</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Pour modifier aussi : <code>el.value =<br/>
"nouveau"</code>. Pour les cases à cocher et les<br/>
boutons radio : <code>el.checked</code> (booléen).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>document.getElementById("nom").text</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est <code>value</code>, pas <code>text</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>document.getElementById("nom").innerHTML</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>innerHTML</code> est pour le contenu<br/>
HTML d'éléments génériques, pas pour les<br/>
champs de formulaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>document.getElementById("nom").content</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : propriété inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>document.getElementById("nom").value</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>value</code> est la propriété<br/>
standard pour les champs de formulaire<br/>
(<code>&lt;input&gt;</code>, <code>&lt;select&gt;</code>, <code>&lt;textarea&gt;</code>).</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q13 : preventDefault</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>À quoi sert <code>event.preventDefault()</code> dans un<br/>
gestionnaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Cas typique : valider un formulaire en JS<br/>
avant de le soumettre.<br/>
<pre><code>form.addEventListener("submit", e =&gt; {
  if (!valider()) e.preventDefault();
});</code></pre></p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À empêcher tous les événements futurs sur la page</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : seul le comportement par défaut<br/>
de l'événement <strong>courant</strong> est annulé,<br/>
les événements suivants restent actifs.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Empêcher le comportement par défaut du navigateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : très utile pour<br/>
intercepter une soumission ou un clic<br/>
sur un lien (<code>&lt;a&gt;</code>) afin de gérer<br/>
l'action en JavaScript.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À fermer la page courante après l'événement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>La fermeture d'une page<br/>
se demande via <code>window.close()</code>.<br/>
La méthode <code>preventDefault</code><br/>
ne ferme rien : elle annule<br/>
uniquement l'action par<br/>
défaut associée à un<br/>
évènement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>À effacer les messages affichés dans la console</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'effacement de la<br/>
console se fait avec<br/>
<code>console.clear()</code>. La<br/>
méthode <code>preventDefault</code><br/>
n'agit que sur l'évènement<br/>
en cours, pas sur les<br/>
outils du navigateur.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q14 : Validation HTML5</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Comment indiquer qu'un champ est<br/>
<strong>obligatoire</strong> dans le HTML ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Autres attributs de validation HTML5 :<br/>
<code>min</code>, <code>max</code>, <code>minlength</code>, <code>maxlength</code>,<br/>
<code>type="email"</code>, etc.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec <code>mandatory="true"</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : attribut inexistant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Avec l'attribut <code>required</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>&lt;input required&gt;</code> active<br/>
la validation native du navigateur, qui<br/>
empêche la soumission si le champ est<br/>
vide, avec un message standard<br/>
automatique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Avec l'attribut <code>must-fill</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : attribut inexistant.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Il faut une fonction JavaScript</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible mais HTML5 offre des<br/>
validations natives plus simples.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q15 : Type d'input adapté</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel <strong>type</strong> d'<code>&lt;input&gt;</code> est le plus adapté<br/>
pour un champ « Âge » ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Choisir le bon <code>type</code> améliore l'ergonomie<br/>
(clavier mobile adapté), accessibilité et<br/>
validation. Ne pas négliger ces<br/>
« petits détails ».</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>type="number"</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : restreint à des nombres,<br/>
affiche des flèches haut/bas, ouvre un<br/>
clavier numérique sur mobile.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>type="text"</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible mais peu pratique. L'utilisateur<br/>
pourrait taper du texte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>type="email"</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : pour un courriel.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>type="age"</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : type inexistant.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q16 : Cible de l'événement</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans un gestionnaire d'événement, comment<br/>
accéder à l'<strong>élément</strong> sur lequel l'événement<br/>
a eu lieu ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p><code>event.target</code> désigne l'élément sur lequel<br/>
l'événement s'est produit : un même<br/>
gestionnaire peut ainsi servir à plusieurs<br/>
boutons et savoir lequel a été cliqué.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>event.dom</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : propriété inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>this.element</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>this.element</code> n'existe pas.<br/>
L'élément sur lequel l'événement a eu<br/>
lieu s'obtient avec <code>event.target</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>event.target</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : référence l'élément<br/>
ayant déclenché l'événement. Permet de<br/>
partager un même gestionnaire entre<br/>
plusieurs éléments.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>event.element</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : propriété inexistante.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q17 : Attribut name</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Pourquoi l'attribut <code>name</code> est-il important<br/>
pour un <code>&lt;input&gt;</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Distinction triple : <code>id</code> (unique, pour CSS<br/>
et JS), <code>class</code> (pour CSS et JS, partagé),<br/>
<code>name</code> (pour la soumission du formulaire).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour le validateur HTML automatique du navigateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Indirectement, mais le rôle principal est<br/>
autre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour le nom affiché</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le rôle de <code>&lt;label&gt;</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Il identifie la donnée envoyée au serveur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : sans <code>name</code>, le champ<br/>
n'est <strong>pas envoyé</strong> au serveur. Le<br/>
serveur reçoit <code>nom=Alice&amp;age=17</code> à<br/>
partir des <code>name</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Pour la couleur du champ</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est CSS.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q18 : Zone de texte</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle balise crée une <strong>zone de texte multiligne</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Particularité : <code>&lt;textarea&gt;</code> n'est pas<br/>
auto-fermante, et son contenu initial<br/>
est entre les balises (pas un attribut<br/>
<code>value</code>).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>&lt;paragraph contenteditable&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible mais usage avancé, pas un<br/>
formulaire classique.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>&lt;textarea&gt;contenu initial&lt;/textarea&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : balise dédiée. Attributs<br/>
utiles : <code>rows</code>, <code>cols</code>, <code>placeholder</code>,<br/>
<code>maxlength</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>&lt;text&gt;multiligne&lt;/text&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : balise inexistante.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>&lt;input type="text" multiline&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>multiline</code> n'existe pas comme<br/>
attribut de <code>&lt;input&gt;</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q19 : Événement input vs change</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle est la différence entre les événements<br/>
<code>input</code> et <code>change</code> sur un <code>&lt;input type="text"&gt;</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Choix selon le besoin : aperçu en direct →<br/>
<code>input</code> ; validation à la fin → <code>change</code> ;<br/>
soumission complète → <code>submit</code> (sur le<br/>
formulaire).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>input</code> à chaque touche, <code>change</code> à la fin</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>input</code> est plus<br/>
réactif (auto-complétion en temps réel),<br/>
<code>change</code> plus économe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>change</code> plante systématiquement toujours</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'évènement <code>change</code><br/>
fonctionne parfaitement<br/>
et n'a aucune raison<br/>
structurelle d'échouer.<br/>
Il sert simplement à<br/>
réagir lorsque la<br/>
nouvelle valeur est<br/>
confirmée par l'utilisateur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : différence de fréquence.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>input</code> n'existe pas</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : événement standard.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q20 : Requête HTTP</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quand on soumet un formulaire en POST vers<br/>
<code>/save</code>, que se passe-t-il <strong>côté navigateur</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le serveur traite les données reçues<br/>
(calcul, enregistrement) et renvoie une<br/>
nouvelle page, que le navigateur affiche à<br/>
la place du formulaire.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le navigateur ouvre carrément un autre site</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le navigateur ne quitte<br/>
pas le domaine courant<br/>
de sa propre initiative.<br/>
Il envoie simplement<br/>
une requête vers l'URL<br/>
indiquée par l'attribut<br/>
<code>action</code> du formulaire.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le formulaire reste affiché tel quel, sans requête réseau</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Pas par défaut : une requête part et la<br/>
page <strong>change</strong> pour afficher la réponse.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Une requête POST part vers <code>/save</code>, puis la réponse s'affiche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est le mécanisme<br/>
fondamental du formulaire. Le navigateur<br/>
envoie la requête, puis affiche la page<br/>
renvoyée par le serveur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Rien, tant qu'un script JavaScript n'envoie pas les données</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la soumission est native, aucun<br/>
JavaScript n'est nécessaire pour qu'un<br/>
formulaire envoie ses données.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q21 : Validation client vs serveur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Faut-il valider les données d'un formulaire<br/>
<strong>côté client</strong> (JavaScript), <strong>côté serveur</strong><br/>
ou les deux ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Mantra de sécurité : « Never trust user<br/>
input. » La validation côté client améliore<br/>
l'expérience, mais la validation côté<br/>
serveur est <strong>non négociable</strong>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune des deux : faire confiance</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : recette pour les bugs et failles.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Les deux, pour l'ergonomie et la sécurité</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : règle d'or. Toute<br/>
donnée venant du client est suspecte<br/>
jusqu'à validation par le serveur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Côté serveur uniquement</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible mais peu ergonomique :<br/>
l'utilisateur doit attendre la réponse<br/>
du serveur pour voir une erreur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Côté client uniquement, car plus rapide</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : la validation client peut être<br/>
contournée (l'utilisateur peut<br/>
désactiver JS, modifier le HTML,<br/>
envoyer une requête falsifiée). Pas de<br/>
sécurité.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q22 : Un paragraphe qui réagit au survol</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Une page contient <code>&lt;p id="zone"&gt;Survolez-moi&lt;/p&gt;</code> et le script :</p>
<pre><code>const zone = document.getElementById("zone");
zone.addEventListener("mouseover", () =&gt; {
  zone.textContent = "Dedans";
});
zone.addEventListener("mouseout", () =&gt; {
  zone.textContent = "Dehors";
});</code></pre>
<p>L'utilisateur amène le pointeur sur le paragraphe, clique deux<br/>
fois dessus, puis éloigne le pointeur. Qu'affiche alors le<br/>
paragraphe ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Chaque événement a son gestionnaire : <code>mouseover</code> à l'arrivée<br/>
du pointeur sur l'élément, <code>mouseout</code> à son départ, <code>click</code> au<br/>
clic. Un clic ne déclenche donc ni <code>mouseover</code> ni <code>mouseout</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>Dehors</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'arrivée du pointeur déclenche<br/>
<code>mouseover</code> (texte <code>Dedans</code>), les clics ne déclenchent<br/>
aucun de ces deux gestionnaires, et le départ du<br/>
pointeur déclenche <code>mouseout</code>, qui écrit <code>Dehors</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>Dedans</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les clics ne figent pas le texte. Quand le<br/>
pointeur quitte le paragraphe, l'événement <code>mouseout</code><br/>
se produit et son gestionnaire écrit <code>Dehors</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>Survolez-moi</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le texte initial ne revient pas tout seul.<br/>
Chaque gestionnaire remplace le contenu du paragraphe,<br/>
et le dernier exécuté, celui de <code>mouseout</code>, écrit<br/>
<code>Dehors</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>DedansDehors</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : affecter <code>textContent</code> remplace tout le texte<br/>
du paragraphe, sans rien ajouter à la suite. Le dernier<br/>
gestionnaire exécuté ne laisse que <code>Dehors</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q23 : Bug formulaire</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Mon formulaire en POST envoie au serveur, mais<br/>
le champ « nom » est <strong>vide</strong> côté serveur.<br/>
Quelle est la cause la plus probable ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Réflexe de débogage : ouvrir l'onglet<br/>
Network des outils développeur, regarder la<br/>
requête envoyée et son contenu (« Form<br/>
Data »).</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>L'attribut <code>name</code> manque sur l'<code>&lt;input&gt;</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : c'est le piège classique.<br/>
<code>&lt;input id="nom"&gt;</code> ne suffit pas ; il<br/>
faut <code>&lt;input name="nom"&gt;</code> (l'<code>id</code> n'est<br/>
pas envoyé).</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le bouton submit est cassé</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible mais peu probable si la requête<br/>
arrive au serveur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le serveur est en panne</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Possible mais cela donnerait une autre<br/>
erreur.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le navigateur n'autorise pas la méthode POST</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : POST est standard.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q24 : Un mot de passe envoyé sans chiffrement</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Le formulaire de connexion d'un site commence par :</p>
<pre><code>&lt;form action="http://exemple.fr/connexion" method="post"&gt;</code></pre>
<p>L'adresse commence par <code>http://</code> et non par <code>https://</code>. Que<br/>
risque l'utilisateur qui envoie son mot de passe ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Deux choix distincts : GET ou POST décide où voyagent les<br/>
paramètres (URL ou corps de la requête) ; HTTP ou HTTPS<br/>
décide si la transmission est chiffrée. Un mot de passe<br/>
exige POST <strong>et</strong> HTTPS.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le mot de passe circule en clair et peut être lu s'il est intercepté</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : POST place les données dans le corps<br/>
de la requête, mais sans HTTPS ce corps n'est pas<br/>
chiffré. Quiconque intercepte la communication, par<br/>
exemple sur un Wi-Fi public, lit le mot de passe.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucun risque : la méthode POST chiffre les données envoyées</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : POST évite seulement que les données<br/>
apparaissent dans l'URL. Le chiffrement est assuré<br/>
par HTTPS, pas par le choix de la méthode.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le mot de passe apparaît dans l'URL et dans l'historique du navigateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est le cas avec GET. Ici, <code>method="post"</code><br/>
place les données dans le corps de la requête, qui<br/>
circule toutefois en clair.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le serveur refuse la requête, car POST exige une adresse <code>https://</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : rien n'impose HTTPS pour une requête POST.<br/>
Le serveur reçoit bien le mot de passe, mais la<br/>
transmission n'est pas protégée.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q25 : Synthèse</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Parmi les affirmations suivantes, laquelle<br/>
est <strong>fausse</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Mnémonique sécurité : « Never trust user<br/>
input + always use HTTPS pour les données<br/>
sensibles ».</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La méthode HTTP GET est préférable pour transmettre un mot de passe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Faux (donc bonne réponse) : GET met les<br/>
données dans l'URL (visibles, loguées).<br/>
Pour un mot de passe, utiliser POST sur<br/>
HTTPS.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Toute donnée client doit être revalidée côté serveur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : règle d'or de sécurité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un événement DOM peut être écouté avec <code>addEventListener</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Cette affirmation est<br/>
exacte : <code>addEventListener</code><br/>
est la méthode standard<br/>
pour attacher un<br/>
gestionnaire à un<br/>
évènement. Ce n'est<br/>
donc pas la mauvaise<br/>
affirmation recherchée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>L'attribut <code>name</code> d'un champ est essentiel pour la soumission au serveur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Vrai : sans <code>name</code>, pas envoyé.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q26 : Type d'input pour une adresse e-mail</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel attribut <code>type</code> choisir pour un champ destiné à<br/>
la saisie d'une adresse électronique ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Choisir le bon type apporte un triple bénéfice :<br/>
validation native du navigateur, clavier adapté<br/>
sur mobile, et meilleure information aux<br/>
technologies d'assistance. Quelques types utiles :<br/>
<code>email</code>, <code>tel</code>, <code>url</code>, <code>number</code>, <code>date</code>, <code>color</code>,<br/>
<code>password</code>.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>type="contact"</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>contact</code> n'est pas un type d'input<br/>
valide. La liste exhaustive des types est<br/>
fixée par le standard HTML.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>type="email"</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : ce type indique au navigateur<br/>
qu'il s'agit d'une adresse électronique. Cela<br/>
déclenche une validation de base (présence<br/>
d'un <code>@</code>), affiche un clavier adapté sur<br/>
mobile et améliore l'accessibilité.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>type="text"</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : un champ texte fonctionne, mais<br/>
n'apporte aucune validation automatique. On<br/>
perd les vérifications de format et le clavier<br/>
spécialisé sur mobile.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>type="address"</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun type <code>address</code> n'est défini par<br/>
le standard HTML. Le type spécifique aux<br/>
adresses électroniques est <code>email</code>.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q27 : Validation côté navigateur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel attribut HTML$5$ rend un champ de formulaire<br/>
<strong>obligatoire</strong>, en empêchant la soumission tant<br/>
qu'il est vide ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Autres attributs de validation native :<br/>
<code>minlength</code>/<code>maxlength</code> (longueur de la chaîne),<br/>
<code>min</code>/<code>max</code> (valeur numérique ou date). La<br/>
validation côté navigateur n'exempte pas d'une<br/>
revalidation côté serveur.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>obligatoire</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les attributs HTML sont en anglais.<br/>
Le bon attribut est <code>required</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>empty=false</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucune syntaxe de ce type n'existe en<br/>
HTML. L'attribut <code>required</code> se passe de<br/>
valeur : sa simple présence suffit.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>required</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : ajouter <code>required</code> à un champ<br/>
empêche le navigateur de soumettre le<br/>
formulaire tant qu'il est vide. Un message<br/>
d'erreur s'affiche automatiquement.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>mandatory</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : aucun attribut <code>mandatory</code> n'est<br/>
défini dans le standard HTML. C'est <code>required</code><br/>
qui joue ce rôle.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q28 : Ce qu'est un cookie</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Qu'est-ce qu'un <strong>cookie</strong> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le protocole HTTP ne garde aucun souvenir d'une<br/>
requête à l'autre. Pour reconnaître un visiteur, le<br/>
serveur lui confie un cookie : le navigateur le<br/>
mémorise et le joint à toutes ses requêtes vers ce<br/>
site. Connexion maintenue, panier, langue choisie :<br/>
tout cela passe par des cookies.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un petit texte déposé par le serveur, gardé par le navigateur et renvoyé à chaque requête vers le site</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>C'est le mécanisme qui permet au serveur de<br/>
reconnaître un navigateur d'une requête à<br/>
l'autre.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un programme que le serveur fait exécuter au navigateur à chaque visite pour reconnaître l'ordinateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un cookie ne contient pas de code et ne s'exécute<br/>
pas ; c'est une donnée, stockée côté client.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un fichier conservé sur le serveur qui contient l'historique complet de chaque visiteur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le cookie est rangé chez le client, dans le<br/>
navigateur ; le serveur ne garde que ce que le<br/>
navigateur lui renvoie.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Une image gardée dans le cache du navigateur pour accélérer l'affichage des pages déjà vues</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le cache stocke des ressources de pages ; un<br/>
cookie porte une information d'identification ou<br/>
de préférence, pas une image.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q29 : Connecté le lendemain sans ressaisir le mot de passe</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Sur un site, vous cochez « rester connecté »,<br/>
fermez le navigateur et revenez le lendemain : vous<br/>
êtes toujours identifié. Où l'information a-t-elle<br/>
été conservée ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le navigateur stocke le cookie sur le disque, avec<br/>
une date d'expiration. Tant qu'elle n'est pas<br/>
passée, chaque requête vers le site l'emporte, et le<br/>
serveur retrouve la session associée. Se déconnecter<br/>
revient à faire effacer ce cookie.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Dans une variable JavaScript de la page, qui survit à la fermeture du navigateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les variables d'un script disparaissent dès que<br/>
la page est fermée.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Dans un cookie gardé par le navigateur et renvoyé au serveur à la nouvelle visite</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le serveur y a inscrit un jeton de session ; en<br/>
le recevant, il reconnaît votre compte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Dans le code HTML de la page, modifié par le serveur pour y inscrire votre nom</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le HTML reçu est reconstruit à chaque requête ; il<br/>
ne persiste pas sur votre machine.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Nulle part : le serveur reconnaît votre ordinateur grâce à son adresse IP</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>L'adresse IP change souvent et est partagée par<br/>
plusieurs appareils d'un même réseau : elle ne<br/>
peut pas identifier un compte.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q30 : Mémoriser une préférence : chez le client ou sur le serveur</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Un site propose un choix de langue. Deux solutions :<br/>
(A) enregistrer la langue dans un cookie ; (B)<br/>
l'enregistrer dans la base de données du serveur,<br/>
associée au compte de l'utilisateur. Laquelle<br/>
retrouve la langue choisie quand l'utilisateur se<br/>
connecte depuis un autre ordinateur ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Ce qui est mémorisé dans le client (cookie, stockage<br/>
du navigateur) reste sur cette machine. Ce qui est<br/>
mémorisé par le serveur suit le compte. Le choix<br/>
dépend de l'usage : un cookie suffit pour un<br/>
visiteur anonyme, la base du serveur s'impose pour<br/>
un utilisateur identifié.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La solution A seule, car le cookie accompagne l'utilisateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le cookie reste dans le navigateur où il a été<br/>
déposé ; un autre ordinateur n'en a aucune copie.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Les deux, car le navigateur transmet ses cookies au nouvel ordinateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Rien ne transfère les cookies d'une machine à<br/>
l'autre ; chaque navigateur a les siens.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La solution B seule, car la préférence est stockée côté serveur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Quelle que soit la machine, une fois connecté,<br/>
l'utilisateur retrouve ce que le serveur a<br/>
mémorisé pour son compte.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune des deux : une préférence ne se mémorise que pendant la visite</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Les deux solutions survivent à la fin de la<br/>
visite ; seule la seconde survit au changement de<br/>
machine.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q31 : Le trajet d'un cookie entre deux requêtes</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Première requête vers <code>boutique.fr</code> : le serveur<br/>
répond avec l'en-tête <code>Set-Cookie: panier=42</code>.<br/>
Quelques secondes plus tard, le navigateur demande<br/>
une autre page du même site. Que contient cette<br/>
deuxième requête ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Deux en-têtes se répondent : <code>Set-Cookie</code> dans la<br/>
réponse du serveur dépose la valeur, <code>Cookie</code> dans<br/>
les requêtes suivantes du navigateur la renvoie. Le<br/>
serveur retrouve ainsi le panier numéro $42$ sans<br/>
que l'utilisateur ait rien ressaisi.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un en-tête <code>Cookie: panier=42</code>, ajouté automatiquement par le navigateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le navigateur joint à chaque requête vers<br/>
<code>boutique.fr</code> les cookies que ce site lui a<br/>
confiés.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Rien de particulier : c'est au serveur de redemander la valeur du panier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Le serveur n'a aucun moyen de « redemander » :<br/>
HTTP est sans mémoire, c'est le client qui<br/>
renvoie l'information.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Un en-tête <code>Set-Cookie: panier=42</code>, renvoyé tel quel au serveur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p><code>Set-Cookie</code> est un en-tête de réponse, du serveur<br/>
vers le navigateur ; dans l'autre sens, l'en-tête<br/>
s'appelle <code>Cookie</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le cookie <code>panier=42</code>, envoyé aussi à tous les autres sites visités ensuite</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Un cookie n'est renvoyé qu'au site qui l'a<br/>
déposé ; les autres sites ne le voient pas.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q32 : L'événement déclenché par l'envoi</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quel événement se produit sur un élément <code>form</code> lorsque<br/>
l'utilisateur clique sur son bouton d'envoi ou appuie sur Entrée<br/>
dans un champ ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Écouter <code>submit</code> sur le formulaire couvre tous les moyens d'envoi,<br/>
bouton comme touche Entrée.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p><code>submit</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>submit</code> est émis par le formulaire lui-même,<br/>
quel que soit le moyen de l'envoyer.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>click</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>click</code> est émis par le bouton, pas par le formulaire,<br/>
et la touche Entrée ne le déclenche pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>send</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cet événement n'existe pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>input</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>input</code> est émis à chaque modification d'un champ.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q33 : Une valeur lue trop tôt</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Ce script affiche toujours une chaîne vide au clic. Pourquoi ?<br/>
<pre><code>const nom = document.getElementById("nom").value;
document.getElementById("btn").addEventListener("click", function () {
    alert("Bonjour " + nom);
});</code></pre></p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Une valeur de formulaire change avec l'utilisateur : elle se lit au<br/>
moment de l'événement, pas une fois pour toutes au chargement.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>La valeur est lue au chargement, avant la saisie</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>nom</code> reçoit la valeur du champ au moment où le<br/>
script s'exécute, c'est-à-dire vide. Lire <code>.value</code> à l'intérieur<br/>
de la fonction donne la saisie du moment.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p><code>alert</code> ne peut pas afficher une variable, seulement un texte fixe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>alert</code> affiche n'importe quelle chaîne.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le champ <code>nom</code> n'a pas d'attribut <code>name</code>, donc pas de valeur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>name</code> sert à l'envoi, pas à la lecture de <code>.value</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le gestionnaire doit être attaché au champ et non au bouton</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le bouton est une cible correcte ; le problème est le<br/>
moment de la lecture.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q34 : Savoir quelle touche a été pressée</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Dans un gestionnaire de l'événement <code>keydown</code>, comment savoir<br/>
quelle touche l'utilisateur a enfoncée ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Le paramètre <code>event</code> d'un gestionnaire décrit ce qui s'est passé :<br/>
touche pressée, position de la souris, élément visé.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>En lisant <code>event.key</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : l'objet événement reçu en paramètre porte la<br/>
touche dans <code>key</code>, par exemple <code>"Enter"</code> ou <code>"a"</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>En lisant <code>event.value</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>value</code> est une propriété des champs de saisie, pas de<br/>
l'événement clavier.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>En comparant le texte du champ avant et après la frappe</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : c'est possible mais peu fiable, et inutile puisque<br/>
l'événement donne la touche.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>En appelant <code>keyboard.last()</code></p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : cette fonction n'existe pas.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q35 : Texte indicatif ou valeur préremplie</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Quelle différence entre <code>&lt;input placeholder="Votre nom"&gt;</code> et<br/>
<code>&lt;input value="Votre nom"&gt;</code> ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>Un <code>placeholder</code> aide l'utilisateur sans rien envoyer ; une <code>value</code><br/>
est une donnée, parfois envoyée par erreur si on l'oublie.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Le premier affiche une indication grisée, le second préremplit le champ</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : <code>placeholder</code> n'est pas une valeur, elle n'est<br/>
pas envoyée ; <code>value</code> est le contenu réel du champ, envoyé tel<br/>
quel si l'utilisateur ne le change pas.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Aucune, les deux attributs étant synonymes et envoyés tous deux</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : l'un guide, l'autre remplit ; seul <code>value</code> est transmis.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le premier est obligatoire, le second facultatif pour le navigateur</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les deux sont facultatifs ; l'obligation de saisie vient<br/>
de <code>required</code>.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le premier concerne les champs texte, le second les boutons</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : les deux s'appliquent aux champs de saisie.</p>]]></text>
    </feedback>
  </answer>
</question>

<question type="multichoice">
  <name>
    <text>Événements et formulaires — Q36 : Un champ numérique borné</text>
  </name>
  <questiontext format="html">
    <text><![CDATA[<p>Que garantit <code>&lt;input type="number" min="0" max="20" name="note"&gt;</code><br/>
lors de l'envoi du formulaire ?</p>]]></text>
  </questiontext>
  <generalfeedback format="html">
    <text><![CDATA[<p>La validation côté client améliore l'expérience ; la validation côté<br/>
serveur garantit la sécurité. Les deux sont nécessaires.</p>]]></text>
  </generalfeedback>
  <defaultgrade>1.0</defaultgrade>
  <penalty>0.0</penalty>
  <hidden>0</hidden>
  <single>true</single>
  <shuffleanswers>true</shuffleanswers>
  <answernumbering>abc</answernumbering>
  <answer fraction="100" format="html">
    <text><![CDATA[<p>Un blocage par le navigateur hors de $[0, 20]$, le serveur devant revérifier</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Bonne réponse : la vérification du navigateur protège contre les<br/>
erreurs de saisie, pas contre une requête fabriquée à la main.<br/>
Le serveur reste responsable de la validation.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Le serveur ne peut recevoir que des valeurs entre $0$ et $20$, garanties</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : une requête envoyée sans passer par le formulaire peut<br/>
contenir n'importe quoi.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>La valeur est automatiquement arrondie à l'entier le plus proche</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : <code>min</code> et <code>max</code> bornent, ils n'arrondissent pas ; <code>step</code><br/>
règle les valeurs permises.</p>]]></text>
    </feedback>
  </answer>
  <answer fraction="0" format="html">
    <text><![CDATA[<p>Rien, ces attributs ne servant qu'à l'affichage du champ</p>]]></text>
    <feedback format="html">
      <text><![CDATA[<p>Erreur : le navigateur les utilise bien pour bloquer l'envoi<br/>
d'une valeur hors bornes.</p>]]></text>
    </feedback>
  </answer>
</question>

</quiz>
