Aller au contenu

Un mot pour Fahmio

Tu écris. Tu continues.

Un problème, une idée — assez pour qu’on comprenne, puis tu retournes à ta copie.

On lit. Tu n’as rien d’autre à faire.

Où veux-tu aller ?

↑ ↓ pour parcourir · Entrée pour ouvrir · Échap pour fermer

Fahmio
Fahmio
Bac Tunisie
WB-JWeb et TIC

Partie B complète sur un seul site — HTML, CSS, JavaScript puis PHP : suivre id, name, classes et données envoyées d’un fichier à l’autre

Idée directrice

Depuis 2024, la partie web de l’épreuve Sciences de l’informatique étudie un seul site, couche par couche : le code HTML d’une page, sa feuille de style, son script JavaScript et le script PHP qui reçoit le formulaire, en quatre exercices enchaînés (8 points en 2025). Chaque exercice ressemble à ceux de WB-E, WB-F, WB-G et WB-H, mais les questions se répondent : un id sert au CSS (#) et au JavaScript, un name devient une clé de $_POST, un champ calculé par le script est ce que le PHP reçoit dans $_POST. Réussir la partie B, c’est suivre une même donnée à travers les quatre fichiers.

Ce qui aide à reconnaître la démarche

« Partie B : Programmation Web (8 points) » ; « Le site est composé des pages … » ; « Indiquer devant chaque rôle le numéro de la ligne contenant le code HTML qui lui correspond » ; « écrire dans la colonne « Code CSS » le code CSS adéquat à chaque mise en forme demandée » ; « En se référant aux codes des fichiers … et suite au clic sur le bouton … »

Besoin d’un point de départ ? Voir la méthode
  • Lire tout le site avant de répondre : noter pour chaque champ son id (JavaScript, sélecteur #), son name (clé des données reçues par le PHP) et sa value.
  • HTML : nommer la balise ou l’attribut du rôle, puis sa ligne ; insertion : link dans head, legend après fieldset, reset à côté du submit, footer avant </body>.
  • CSS : choisir le sélecteur d’après l’attribut présent (class → point, id → dièse, balise, descendant « nav a »), puis les couples propriété : valeur de la liste.
  • JavaScript : tracer en tableau (une ligne par tour) en gardant les types — value est une chaîne, parseFloat ou Number avant d’additionner.
  • PHP : relier chaque clé reçue à un name, se rappeler ce qui n’est pas envoyé (span, champ sans name, case non cochée), choisir fetch_row ou fetch_array selon l’accès (indice ou nom) et affected_rows après INSERT, UPDATE ou DELETE, puis dérouler les echo sur les extraits de tables.
Les pièges à vérifier dans ta démarche

Répondre à un exercice sans regarder les autres fichiers ; viser #cout et .cout au hasard ; confondre readonly (envoyé) et disabled (non envoyé) ; croire qu’une option sans value envoie une chaîne vide ; additionner des value sans conversion ; attendre du PHP la valeur d’un span ; oublier la clé primaire composée quand le même formulaire est envoyé deux fois.

Sujet principal

Partie B — Programmation web (8 points), dans l’esprit des sessions 2024–2025

7 questionsFigure fournieCorrigé masqué

Le site de l’atelier VéloCité est composé des pages reparation.html, atelier.css, atelier.js et reparation.php. La page reparation.html permet à un technicien d’enregistrer une réparation dans la base de données « velocite ». La figure 1 montre la page juste après son chargement.

Figure 2 — code HTML de reparation.html (les lignes en pointillés sont à compléter) :

 1 <!DOCTYPE html>
 2 <html lang="fr">
 3 <head>
 4   <meta charset="utf-8">
 5   <title>VéloCité - Atelier</title>
 6   ………………………………………
 7   <script src="atelier.js"></script>
 8 </head>
 9 <body onload="inconnue()">
10   <header>
11     <h1>VéloCité : atelier de réparation</h1>
12     <nav>
13       <a href="index.html">Accueil</a>
14       <a href="stock.html">Stock des pièces</a>
15     </nav>
16   </header>
17   <form id="f" name="f" action="reparation.php" method="post" onsubmit="return verifier()">
18     <fieldset>
19       ………………………………………
20       <label>N° du vélo :</label>
21       <input type="number" id="velo" name="idVelo" min="101"><br>
22       <label>Date :</label>
23       <input type="date" id="date" name="dateRep"><br>
24       <label>Panne :</label>
25       <select id="panne" name="panne">
26         <option value="">Choisir une panne</option>
27         <option>Chaîne cassée</option>
28         <option>Pneu crevé</option>
29         <option>Frein avant</option>
30         <option>Batterie</option>
31       </select><br>
32       <label>Pièces changées :</label>
33       <input type="checkbox" name="piece[]" value="12.500" onclick="calculer()">Chaîne
34       <input type="checkbox" name="piece[]" value="9.000" onclick="calculer()">Pneu
35       <input type="checkbox" name="piece[]" value="15.000" onclick="calculer()">Plaquettes
36       <input type="checkbox" name="piece[]" value="95.000" onclick="calculer()">Batterie<br>
37       <label>Main-d'œuvre :</label>
38       <input type="range" id="mo" name="mo" min="0" max="30" step="5" onchange="calculer()">
39       <span id="valMo"></span> D<br>
40       <label>Coût total :</label>
41       <input type="text" id="cout" name="cout" readonly> D<br>
42       <textarea id="remarque" name="remarque" rows="3" cols="30" placeholder="Remarque du technicien"></textarea><br>
43       <input type="submit" value="Enregistrer">
44       ………………………………………
45     </fieldset>
46   </form>
47   ………………………………………
48 </body>
49 </html>

Figure 3 — code de atelier.js :

 1 function calculer()
 2 {
 3   const pieces = document.getElementsByName("piece[]")
 4   let s = 0
 5   for (let i = 0; i < pieces.length; i++)
 6     if (pieces[i].checked)
 7       s = s + parseFloat(pieces[i].value)
 8   let mo = document.getElementById("mo").value
 9   document.getElementById("valMo").innerHTML = mo
10   s = s + Number(mo)
11   document.getElementById("cout").value = s.toFixed(3)
12 }
13 function inconnue()
14 {
15   const pieces = document.getElementsByName("piece[]")
16   for (let i = 0; i < pieces.length; i++)
17     pieces[i].checked = false
18   document.getElementById("mo").value = 10
19   calculer()
20 }
21 function verifier()
22 {
23   const v = document.getElementById("velo").value
24   if (v == "" || isNaN(v))
25   { alert("Numéro de vélo invalide")
26     return false }
27   if (document.getElementById("panne").selectedIndex == 0)
28   { alert("Choisir une panne")
29     return false }
30   if (Number(document.getElementById("cout").value) == 0)
31   { alert("Le coût ne peut pas être nul")
32     return false }
33   return true
34 }

Figure 4 — code de reparation.php :

 1 <?php
 2 $con = mysqli_connect("localhost", "root", "", "velocite") or die("Erreur B.D.");
 3 $velo = $_POST["idVelo"];
 4 $date = $_POST["dateRep"];
 5 $panne = $_POST["panne"];
 6 $cout = $_POST["cout"];
 7 $res1 = mysqli_query($con, "select codeModele from Velo where idVelo = $velo")
 8         or die("Requête erronée");
 9 if ($lig = mysqli_fetch_row($res1))
10 {
11   echo "Vélo $velo (modèle $lig[0])<br>";
12   $req = "insert into Reparation values ($velo, '$date', '$panne', $cout)";
13   $res2 = mysqli_query($con, $req);
14   if (mysqli_affected_rows($con) == 1)
15     echo "Réparation enregistrée : $panne, $cout D";
16   else
17     echo "Échec : " . mysqli_error($con);
18 }
19 else
20   echo "Le vélo $velo n'existe pas.";
21 mysqli_close($con);
22 ?>

Figure 5 — extraits des tables Velo et Reparation ; la clé primaire de Reparation est le couple (idVelo, dateRep).

Velo

idVelodateServicecodeModeleidStation
1012017-05-10M11
1022018-03-02M22
1032021-06-15M53
1042023-09-01M63
1052024-02-20M52
1062019-11-11M14

Reparation

idVelodateReppannecout
1012025-03-01Chaîne cassée18.000
1032025-08-12Batterie120.000
1042025-10-05Frein avant25.000
1012026-01-15Pneu crevé12.000
1052026-02-02Écran de bord85.000

N.B. : les fonctions mysqli_… admettent leurs équivalents mysql_… ; comme dans les sujets, une requête qui échoue fait retourner false à mysqli_query.

Exercice 1 — analyse et interprétation du code HTML (3 points)

1. Indiquer devant chaque rôle le numéro de la ligne contenant le code HTML qui lui correspond.

RôleN° de ligne
Spécifier l’encodage des caractères de la page web.
Lier un fichier de scripts externe à la page web.
Regrouper les liens de navigation de la page.
Créer une zone de saisie de texte sur plusieurs lignes.
Afficher une valeur que l’utilisateur ne peut pas modifier, mais qui est envoyée avec le formulaire.
Choisir une valeur numérique dans une plage à l’aide d’un curseur.

2. Pour chacune des affirmations suivantes, mettre une croix dans la case correspondant à la proposition correcte.

  1. L’attribut step="5" (ligne 38) signifie que : ☐ la valeur du curseur varie de 5 en 5 ☐ le curseur ne propose que 5 positions ☐ la valeur initiale du curseur est 5
  2. L’attribut placeholder (ligne 42) : ☐ définit le texte envoyé par défaut au serveur ☐ affiche un texte indicatif tant que la zone est vide, sans l’envoyer ☐ définit le titre de la zone de saisie
  3. L’option de la ligne 29, qui n’a pas d’attribut value, envoie au serveur lorsqu’elle est choisie : ☐ une chaîne vide ☐ le texte « Frein avant » ☐ son rang, 3
  4. L’attribut readonly (ligne 41) : ☐ empêche l’utilisateur de modifier le champ, dont la valeur est envoyée ☐ masque le champ dans la page ☐ empêche l’envoi de la valeur du champ

3. Pour compléter le code HTML, écrire devant chaque balise le numéro de la ligne dans laquelle elle doit être insérée.

BaliseN° de ligne
<input type="reset" value="Annuler">
<footer>VéloCité - atelier de Sfax</footer>
<legend>Nouvelle réparation</legend>
<link rel="stylesheet" href="atelier.css">

Exercice 2 — analyse et interprétation du code CSS (1,5 point)

En se basant sur les figures 1 et 2, écrire le contenu du fichier atelier.css correspondant à chaque mise en forme demandée, en utilisant les instructions fournies dans la liste suivante : legend | #cout | .cout | nav a | a nav | color : white | background-color : #1d6b8f | padding : 4px | margin : 4px | font-weight : bold | font-style : bold | text-align : right | width : 90px | text-decoration : none | text-decoration : underline | margin-right : 15px | border : none.

Mise en formeCode CSS
Le titre « Nouvelle réparation » du cadre doit avoir : un texte blanc ; un arrière-plan de couleur #1d6b8f ; une marge intérieure de 4 pixels.………… { ………… }
Le champ « Coût total » doit avoir : un texte en gras ; un texte aligné à droite ; une largeur de 90 pixels.………… { ………… }
Les liens du menu de navigation doivent avoir : un texte non souligné ; une marge extérieure droite de 15 pixels.………… { ………… }


Justifier le choix du sélecteur de la deuxième règle.

Exercice 3 — analyse et interprétation du code JavaScript (2 points)

1. Indiquer devant chaque rôle l’élément du langage JavaScript (figure 3) qui lui correspond.

RôleÉlément
Fonction qui convertit une chaîne en nombre réel.
Méthode qui écrit un nombre avec un nombre fixé de chiffres après la virgule.
Fonction qui teste si une valeur n’est pas un nombre.
Méthode qui retourne la liste des éléments ayant le même nom.
Propriété qui indique si une case est cochée ou non.
Propriété qui donne le rang de l’option choisie dans une liste déroulante.

2. Le technicien coche « Chaîne » puis « Plaquettes » et place le curseur sur 15. Compléter la trace de la boucle de calculer() lors de son dernier appel (une ligne par tour), puis donner le contenu de valMo et la valeur du champ cout.

3. Si la ligne 7 était s = s + pieces[i].value, que contiendrait s à la sortie de la boucle, pour le même exemple ? Expliquer.

4. a. À quel moment la fonction inconnue() est-elle exécutée ?
b. En s’aidant de la figure 1, en déduire son rôle.

5. Le technicien saisit le vélo 104, choisit « Frein avant », ne coche aucune pièce, place le curseur sur 0 et clique sur « Enregistrer ». Quelle valeur retourne verifier() et quel message est affiché ? Le formulaire est-il envoyé ?

Exercice 4 — analyse et interprétation du code PHP (1,5 point)

Le technicien saisit le vélo 104, la date 2026-03-20, choisit « Frein avant », coche « Plaquettes », laisse la main-d’œuvre à 10 et clique sur « Enregistrer ».

1. Compléter le tableau suivant.

Variable (figure 4)Ligne du champ (figure 2)Valeur reçue
$velo (ligne 3) | |
$date (ligne 4) | |
$panne (ligne 5) | |
$cout (ligne 6) | |

2. Pour chacune des affirmations suivantes, mettre une croix dans la case correspondant à la proposition correcte.

  1. L’instruction de la ligne 9 peut être remplacée par : ☐ if ($lig = mysqli_fetch_array($res1)) ☐ if ($lig = mysqli_affected_rows($res1)) ☐ if ($lig = mysqli_num_rows($res1))
  2. L’instruction de la ligne 14 peut être remplacée par ($res2 étant le résultat de la ligne 13) : ☐ if (mysqli_num_rows($res2) == 1) ☐ if ($res2) ☐ if (mysqli_fetch_row($res2))
  3. Pour récupérer la main-d’œuvre, un élève ajoute au script l’instruction $mo = $_POST["valMo"];. Cette instruction : ☐ récupère la valeur de la main-d’œuvre ☐ ne récupère rien : un span n’est pas envoyé, il fallait lire la clé "mo" ☐ récupère le texte « 10 D »

3. Donner l’affichage produit par reparation.php pour cet exemple. Que se passe-t-il si le technicien envoie une seconde fois le même formulaire ?

Voir la correction commentéeAprès avoir posé votre démarche

Exercice 1.1 Idée : nommer d’abord la balise ou l’attribut qui réalise le rôle, puis chercher sa ligne.

RôleCodeLigne
Spécifier l’encodage des caractères de la page web.<meta charset="utf-8">4
Lier un fichier de scripts externe à la page web.<script src="atelier.js">7
Regrouper les liens de navigation de la page.<nav>12
Créer une zone de saisie de texte sur plusieurs lignes.<textarea>42
Afficher une valeur que l’utilisateur ne peut pas modifier, mais qui est envoyée avec le formulaire.readonly41
Choisir une valeur numérique dans une plage à l’aide d’un curseur.<input type="range">38

Exercice 1.2 Idée : chaque attribut a un effet précis sur l’affichage ou sur l’envoi.

  • 1. La valeur du curseur varie de 5 en 5 : de 0 à 30, elle prend les 7 valeurs 0, 5, 10, 15, 20, 25, 30.
  • 2. Un texte indicatif affiché tant que la zone est vide, sans être envoyé (sans saisie, remarque est envoyée vide).
  • 3. Le texte « Frein avant » : sans attribut value, une option a pour valeur son texte (ce n’est pas son rang, 3).
  • 4. L’utilisateur ne peut pas modifier le champ, dont la valeur est envoyée : readonly bloque la saisie, pas l’envoi (disabled, lui, empêcherait l’envoi).

Exercice 1.3 Idée : link va dans head ; legend suit immédiatement fieldset ; le bouton reset accompagne le bouton submit ; footer ferme le body.

BaliseLigne
<input type="reset" value="Annuler">44
<footer>VéloCité - atelier de Sfax</footer>47
<legend>Nouvelle réparation</legend>19
<link rel="stylesheet" href="atelier.css">6

Exercice 2 Idée : le sélecteur se lit sur l’attribut réellement présent dans le HTML, puis chaque demande correspond à un couple propriété : valeur de la liste.

legend { color : white ; background-color : #1d6b8f ; padding : 4px ; }
#cout { font-weight : bold ; text-align : right ; width : 90px ; }
nav a { text-decoration : none ; margin-right : 15px ; }

Le champ Coût total porte id="cout" (ligne 41) et aucune classe : on le vise par le sélecteur d’identifiant #cout, pas .cout. Le titre du cadre est la balise <legend> ; nav a (espace = descendant) vise les liens situés dans nav, alors que a nav viserait un nav contenu dans un lien. Marge intérieure = padding ; gras = font-weight (font-style règle l’italique) ; non souligné = text-decoration : none.

Exercice 3.1

RôleÉlément
Fonction qui convertit une chaîne en nombre réel.parseFloat()
Méthode qui écrit un nombre avec un nombre fixé de chiffres après la virgule.toFixed()
Fonction qui teste si une valeur n’est pas un nombre.isNaN()
Méthode qui retourne la liste des éléments ayant le même nom.getElementsByName()
Propriété qui indique si une case est cochée ou non.checked
Propriété qui donne le rang de l’option choisie dans une liste déroulante.selectedIndex

Exercice 3.2 Idée : dérouler la boucle case par case ; seules les cases cochées ajoutent leur value, convertie par parseFloat.

iPiècepieces[i].checkeds en fin de tour
0Chaînetrue12.5
1Pneufalse12.5
2Plaquettestrue27.5
3Batteriefalse27.5


Puis mo = "15" : valMo affiche 15 ; s = 27.5 + 15 = 42.5, et le champ cout reçoit s.toFixed(3) = "42.500".

Exercice 3.3 value est une chaîne : sans parseFloat, + concatène. s passe de 0 à 0 + "12.500" = "012.500", puis à "012.500" + "15.000" = "012.50015.000" : une chaîne, et non le nombre 27.5.

Exercice 3.4 a. Au chargement de la page, grâce à onload="inconnue()" (ligne 9).
b. inconnue() initialise la zone de calcul : elle décoche les quatre pièces, place le curseur de main-d’œuvre sur 10, puis appelle calculer(), qui affiche 10 à côté du curseur et 10.000 dans le coût total — l’état visible sur la figure 1.

Exercice 3.5 Le numéro 104 est valide et l’option choisie a le rang 3 (≠ 0). Aucune pièce et une main-d’œuvre nulle donnent un coût "0.000" : Number("0.000") vaut 0 (ligne 30). verifier() affiche « Le coût ne peut pas être nul » et retourne false : grâce à return verifier() (ligne 17 de reparation.html), le formulaire n’est pas envoyé.

Exercice 4.1 Idée : chaque clé est le name d’un champ ; la valeur est celle du champ au moment de l’envoi.

VariableLigne du champValeur reçue
$velo | 21 (name="idVelo") | "104"
$date | 23 (name="dateRep") | "2026-03-20"
$panne | 25 (name="panne") | "Frein avant" (texte de l’option, qui n’a pas de value)
$cout | 41 (name="cout") | "25.000" (15.000 + 10, calculé par calculer() ; readonly n’empêche pas l’envoi)

Exercice 4.2 Idée : se demander ce que renvoie chaque fonction et sur quoi elle agit.

  • 1. if ($lig = mysqli_fetch_array($res1)) : fetch_array donne aussi l’indice 0, donc $lig[0] (ligne 11) fonctionne toujours. affected_rows prend la connexion, pas un résultat ; avec num_rows, $lig vaudrait un nombre et le modèle ne serait pas affiché.
  • 2. if ($res2) : l’insertion d’une seule ligne réussit si et seulement si mysqli_query retourne true, c’est-à-dire si $res2 est vrai. num_rows et fetch_row ne s’appliquent qu’au résultat d’un SELECT.
  • 3. Elle ne récupère rien : le span valMo (ligne 39) n’est pas un champ (clé indéfinie) ; la main-d’œuvre est envoyée par le curseur, sous la clé "mo".

Exercice 4.3 Le vélo 104 existe (modèle M6) et la réparation (104, 2026-03-20) n’est pas encore enregistrée : l’insertion touche une ligne. Affichage :

Vélo 104 (modèle M6)

Réparation enregistrée : Frein avant, 25.000 D

Au second envoi, la première ligne s’affiche de nouveau, mais l’insertion viole la clé primaire (idVelo, dateRep) : le couple (104, 2026-03-20) existe déjà. mysqli_query retourne false, mysqli_affected_rows vaut −1 et le script affiche « Échec : » suivi du message de MySQL signalant une entrée en double pour la clé primaire. La base n’est pas modifiée.

Changer d’énoncé, garder le raisonnement

Choisis un seul transfert après le sujet principal. Qu’est-ce qui change ? Quel résultat ou quelle méthode peux-tu réutiliser ? Les autres exercices restent disponibles pour une prochaine séance.

Variantes rencontrées : partie B de 8 points en quatre exercices sur un même site (principale 2025 : EvaluationManif.html, mesStyles.css, mesScripts.js, Evaluation.php ; contrôle 2025 : Statistiques_Interventions.html, mesStyles.css, mesScripts.js, Statistiques_Types.php) ; 2ᵉ partie « Programmation Web » d’un exercice de 13 points sur le site d’une base (principale 2024 : index.html, mesStyles.css, controles.js, details.php ; contrôle 2024 : index.html, mesStyles.css, mesControles.js, commenter.php) ; partie B de 7 à 7,5 points (principale et contrôle 2026 : intervention.html ou invention.html, mesControles.js, un script PHP). Chaque couche isolée se travaille dans WB-E (HTML), WB-F (CSS), WB-G (JavaScript) et WB-H (PHP) ; ici, l’enjeu est la cohérence d’un fichier à l’autre.

Relier ce raisonnement au bac

Choisis une filière pour voir les sujets qui étayent ce scénario.