Comme l'illustre la figure ci-dessous, la boutique en ligne présente deux zones principales
- Celle de gauche (#boutique) contient les différents produits mis en vente par la boutique;
- celle de droite (#panier) correspond au panier construit par l'utilisateur.

Vous devrez utiliser les fichiers contenus dans l'archive fichiers-mini-projet-js2022.zip fournie. Cette archive contient :
- le fichier mini-projet-js-2022.html dont vous ne modifierez pas le contenu du body;
- le fichier style/style-projet2022.css et le dossier style/images qui ne devront pas être modifiés;
- le fichier scripts/projet2022.js. Il contient déjà du code qui vous est fourni. Vous le compléterez avec le code javascript que vous écrirez. Toutes les fonctions que vous écrirez dans ce fichier devront être doccumentées de manière similaire à ce qui est fait pour le code fourni;
- le dossier data qui contient les fichiers de données permettant la définition du catalogue regroupant tous les produits de la boutique. Plusieurs fichiers, d'extension
.js
sont fournis. Le fichier de données est chargé dans le header du document html, comme le script; - le dossier images contenant les images des produits proposés;
- et enfin, le fichier boutique_en_action.html représentant un exemple de contenu de page "en action" : ce fichier ne sera pas à fournir lors de votre rendu
Voici une description des fonctionnalités attendues
- Dans la boutique, l'utilisateur peut pour un article donné choisir la quantité qu'il souhaite acheter à l'aide du champ de saisie correspondant.
Cette quantité doit toujours être comprise entre 0 et 9.
Cette contrainte de validité est garantie lorsque l'on utilise les
flèches
mais doit être gérée si l'utilisateur saisit directement une valeur. - Il doit ensuite cliquer sur le bouton représentant un chariot de course pour mettre dans le panier cet article avec la quantité désirée. Le bouton de mise en panier est inactif tant que la quantité est 0, actif sinon. L'inactivité se traduit visuellement par une opacité de 0.25 du composant et par l'absence de réaction au clic; l'activité par une opacité à 1 et une mise en panier effective de l'article. Après la mise en panier le compteur de quantité est remis à 0.
- Lorsqu'il est mis en panier un article apparaît dans la zone du panier. Un même article n'apparaît toujours qu'une seule fois dans le panier, avec sa quantité totale commandée. Donc lorsqu'un article déjà dans le panier est à nouveau commandé, sa quantité est mise à jour dans le panier. Il n'est jamais autorisé de commander plus de 9 fois un même article, même en plusieurs fois. Donc la quantité d'un même article dans le panier ne peut jamais dépasser 9.
- En cliquant sur le bouton représentant une poubelle on supprime complètement un article du panier (quelle que soit la quantité). Le montant total des articles dans le panier apparaît dans la zone #total. Ce montant est mis à jour à chaque modification du panier, ajout ou suppression d'articles.
- Au-dessus du total se trouve une zone de texte qui permet de filtrer les produits de la boutique.
Seuls les produits dont le nom (champ
name
dans le catalogue, voir ci-dessous) contient la chaîne de caractères présente dans le filtre sont affichés. La saisie s'adapte à chaque caractère frappé par l'utilisateur.
Le travail que vous devez réaliser consiste à écrire le code javascript permettant de mettre en œuvre ce comportement.
Le contenu de la boutique est construit automatiquement au chargement de la page par rapport à des données définies dans un catalogue (différents catalogues doivent pouvoir être utilisés sans que cela ne nécessite de modifier le code qui permet le chargement de la boutique, plusieurs fichiers catalogues sont fournis dans ce but).
- chacun des fichiers de données (fournis dans le dossier data) définit une variable globale
catalog
(de type tableau javascript) qui contient des produits de la boutique.Vous pouvez compléter les exemples en définissant vos propres catalogues de produits.
- Chaque élément du tableau
catalog
est un produit représenté sous la forme d'un objet javascript (délimité par des accolades). - Chaque objet comportent 4 champs :
name
,description
,image
etprice
.
Si someProduct est une variable représentant un tel objet produit, alors la notation pointée permet d'accéder au champ correspondant :
const someProduct = catalog[0] // l'objet correspondant au premier produit est stocké dans 'someProduct' const txt = someProduct.description; // récupération de la description du produit (et rangement dans la variable 'txt') const someProduct2 = catalog[2] // l'objet correspondant au second produit est stocké dans 'someProduct' const productSrc = someProduct2.image; // récupération du champ 'image' du produit (et stockage dans la variable 'productSrc)
Il est conseillé de traiter les questions progressivement en respectant l'ordre suggéré.
- Etudiez le code HTML du document mini-projet-js-2022.html afin de bien en comprendre la structure et de repérer les différents éléments qui constituent la page, et notamment leurs
id
.Ce document utilise pour le moment une version incomplète du fichier scripts/project2022.js. En particulier les images des produits ne s'affichent pas encore. C'est normal. C'est votre travail dans ce projet de compléter ce fichier de script.
- Créer une nouvelle feuille de style nommée boutique.css dans le répertoire adéquat puis définissez les régles permettant de centrer le texte "Ma boutique en ligne" et d'ajouter une couleur d'arrière plan à la zone correspondant au panier
- Dans l'archive, vous est fourni le fichier boutique_en_action.html. Celui-ci est une copie statique (donc sans code javascript actif) du code HTML correspondant au contenu de la page
en action
. Ce contenu est donc un exemple de résultat produit par les actions du code javascript lorsqu'il est actif.Etudiez ce code HTML afin de comprendre ce que doit produire l'exécution de votre code javascript.
En particulier étudiez le code correspondant à chaque produit dans #boutique et chaque achat dans #panier.
Vous analyserez en particulier les id qui apparaissent dans les différents éléments: ils sont de la forme i-text et vous ferez le lien entre ce i et l'indice de l'article dans le catalogue. Vous remarquerez également l'égalité de cette valeur i lorsque le produit et l'achat correspondent (étudiez par exemple l'élément #0-product et #0-achat). - Afin d'en comprendre le fonctionnement, étudiez attentivement le code de la fonction createShop et les fonctions qu'elle utilise : createProduct, createBlock, createOrderControlBlock.
Comme vous le constatez la fonction createFigureBlock n'est pas implémentée correctement. Compléter son code afin qu'elle crée l'élémentfigure
inclus dans l'élémentdiv.produit
. L'élément créé doit donc correspondre à ce que l'on peut trouver dans la version statique du projet. - Le code fourni permet la création des éléments
div.controle
, en particulier grâce à la fonction createOrderControlBlock. (cependant ces contrôles sont pour le moment sans effet). Complétez donc le code existant pour mettre en place la gestion événementielle de saisie des quantités qui déclenchera un contrôle des valeurs via la fonctionverifQuantity
- Complétez maintenant le code de la fonction verifQuantity qui aura les missions suivantes :
- si l'utilisateur saisit "à la main" une valeur interdite, il faut annuler cette saisie, par exemple en la remplaçant par 0.
- Il vous faut aussi gérer l'aspect visuel du bouton de mise en panier selon que la quantité vaut 0 ou non. Vous pouvez simplement exploiter différentes valeurs de la propriété CSS opacity
- Toujours dans la fonction verifQuantity il faut maintenant gérer l'action déclenchée par le bouton de mise en panier (lorsque celui est actif).
La commande sera gérée dans la fonction orderProduct.
Mettez en place les gestionnaires d'événements correspondants pour que, lorsque l'aspect visuel du bouton change (voir question précédente) il soit possible ou non de commander
- Après avoir lu attentivement le code fourni et les commentaires de la fonction orderProduct rédigez sa documentation et compléter son code afin de gérer la remise à zero de la quantité du produit dans la zone #boutique une fois la mise au panier effectuée. Pensez à bien gérer tous les comportements attendus pour le bouton représentant le chariot une fois cette quantité remise à zéro.
- La fonction addProductToCart (qui est appelée par orderProduct) construit un élément div.achat
Inspirez-vous du code statique fourni pour réaliser cette fonction, vous penserez notamment à :
- la gestion des id de ces éléments
- ne pas ajouter d'éléments div.achat si le produit existe déjà dans le panier : il suffira donc de modifier la quantité
- garantir que la valeur de #montant est mise à jour.
- Gérer l'action des boutons de suppression du panier. Vous devez toujours maintenir la cohérence de #montant.
- Un événement
keyup
est émis à chaque fois que l'on relâche une touche dans un élémentinput
. Un gestionnaire d'événement a déjà été mis en place dans la fonctioninit()
.Faites le nécessaire en complétant le code le fonction filterDisplaidProducts pour que seuls les produits dont le name contient le texte présent dans #filter soient affichés dans la boutique. Le filtrage doit être modifié au fur et à mesure de la saisie des caractères dans #filter.
Etudiez la documentation de la fonction indexOf des chaînes de caractères. - (options : points BONUS) Vous pouvez de manière optionnelle compléter le comportement de la page avec d'autres fonctionnalités.
Dans ce cas vous les indiquerez dans le fichier lisezmoi.txt fourni avec votre archive. Voici quelques exemples d'extensions envisageables :
- compléter le fichier boutique.css en personalisant un peu plus le style de la page
- permettre la modification de la quantité d'un article dans le panier;
- ajouter un bouton qui permet de stocker localement sur le navigateur le panier en cours pour le retrouver lors du prochain chargement de la page, on peut alors utiliser la fonctionnalité "Web Storage". Après une recherche d'informations sur internet, utilisez l'objet localStorage et ses fonctions setItem et getItem pour mémoriser les articles du panier. Au chargement de la page (en supposant que le catalogue n'a pas changé) le panier est affiché dans l'état où il avait été laissé.
- etc.
- Rendez votre travail sous la forme d'une archive. Le nom de cette archive sera votreNom-projetJS.zip. Cette archive contiendra un répertoire dont le nom sera votre-nom-projet. Le contenu de ce répertoire sera organisé ainsi :
- un fichier lisezmoi.txt avec votre nom et prénom. Ce fichier mentionnera pour chacune des questions précédentes si elle a été traitée ou non et les éventuels problèmes de votre solution par rapport au cahier des charges demandé. Si vous avez ajouté des fonctionnalités, vous les détaillerez également dans ce fichier.
- les fichiers mentionnés en introduction.
Tous vos fichiers seront codés en UTF-8. Les noms des fichiers (y compris leurs extensions) seront en minuscules.