Aller au contenu principal

TP3

Consignes

  • Lisez toutes les instructions et la grille de correction avant de commencer

  • Vous DEVEZ faire au moins les migrations et les commits demandés mais vous pouvez en faire plus sans problème, tant que vous les documentez correctement

  • L'utilisation de l'IAG pour créer partiellement ou totalement des éléments du travail entraînera automatiquement un zéro et un plagiat

  • Il faut télécharger ce fichier zip

Surlignage et filtre dans la vue Index de TrainerCertification

1. Surlignage

  1. Ajoutez le code JavaScript nécessaire pour surligner les rangées (<tr>) dont le nom du Trainer contient la chaîne de caractères qui est entrée dans la boîte de texte.

    1. La recherche de texte doit ignorer la casse (minuscule ou majuscule).
    2. Lorsqu'on ajoute des caractères et qu'on les retire tous, le surlignage doit se retirer de toutes les lignes.
info

Il y a plusieurs façons possibles de résoudre ce problème, mais c'est une bonne idée d'ajouter un id sur <tbody> ou bien un attribut class sur le <td> ou le <a> qui contient le nom du trainer afin de pouvoir les obtenir dans votre code JavaScript.

info

Le nom de la fonction à coder se nomme highlightByName(). La balise input contient déjà le code nécessaire pour appeler cette fonction à chaque fois qu'un caractère est ajouté ou retiré dans la boîte de texte. Ce comportement se fait grâce au oninput.

info

Vous pouvez simplement utiliser la propriété de style backgroundColor pour faire le surlignage

alt text

2. Filtrage par date

  1. Ajoutez le code javascript nécessaire pour filtrer les données en fonction de la date. Vous ne devez PAS faire de requête au serveur pour obtenir les dates filtrées. Ceci doit être fait uniquement en javascript.

    1. Il faut seulement afficher les rangées avec une date égale ou supérieure à la date entrée dans le champ date.

    2. Le filtrage s'effectue lorsque l'on clique sur le bouton "Filtrer".

info

Encore une fois, il y a plusieurs façons possibles de résoudre ce problème, mais c'est une bonne idée d'ajouter un id sur <tbody> ou bien un attribut class sur le <td> qui contient la date de la certification pour facilement les obtenir dans votre code JavaScript.

info

Le nom de la fonction à coder se nomme filterByDate(). La balise input contient déjà le code nécessaire pour appeler cette fonction lorsqu'on clique sur le bouton Filter

info

Pour vous aider avec la comparaison de dates, il est possible de créer un objet de date à partir d'une date en utilisant new Date(dateString) et un élément de type input possède la propriété valueAsDate

alt text
attention

Il est possible de filtrer et de surligner en même temps.

Système de filtrage des Trainers sur la page d'accueil

Mise en contexte

Dans cette section, vous devrez compléter le système de filtrage des Trainers sur la page d'accueil afin de permettre à l'utilisateur d'afficher uniquement les Trainers correspondant aux critères sélectionnés. Pour ce faire, vous devrez compléter l'action Filter de TrainerController et la méthode GetAllAsync de TrainerService. Ici, le filtrage est effectué du côté serveur.

attention

Avant d'obtenir un résultat complet et fonctionnel, il y aura plusieurs étapes à compléter.

  1. Modifiez l'action Filter du TrainerController afin quelle retourne la vue Index et les trainers filtrés. L'action Filter reçoit la liste des filtres en paramètre. Utilisez la méthode GetAllAsync avec ces filtres pour obtenir les trainers qui respectent les critères.

  2. Modifiez la méthode GetAllAsync du service TrainerService pour prendre en compte les paramètres de pagination de TrainerSearchViewModelFilter. Lisez les commentaires dans le code pour plus de détails.

  3. Dans la même méthode, il faut également ajouter des Where pour filtrer selon chacun des critères de recherche de TrainerSearchViewModelFilter (il y a 5 filtres à appliquer)

    • Pour le filtre par nom, il faut accepter un résultat si le nom OU le prénom contient la chaîne de caractères entrée dans le filtre
  4. Il faut également remplir les SelectList dans la même méthode (GetAllAsync) pour afficher les choix à l'utilisateur.

  5. Pour le SelectList de certification centers, il faut obtenir le CertificationCenter (une simple string) de toutes les certifications et enlever les doublons, car il est possible que plusieurs certifications aient le même CertificationCenter.

info

Cette fois-ci le filtrage est effectué sur le serveur en effectuant une nouvelle requête dans la BD.

astuce

Voici comment on peut faire une requête pour une condition optionnelle dans Linq et ne filtrer que lorsque l'on sélectionne une valeur dans le filtre.


.Where(x => filter.SelectedCategoryId == null || x.CategoryId == filter.SelectedCategoryId )

attention

C'est le moment de tester, ajouter des commentaires et faire votre commit et votre push

Affichez le détail d'un Trainer dans la page Trainer/Index

  1. Écrivez du javascript en utilisant jQuery pour ajouter la classe show à l’élément enfant aside lorsqu'on survole le card d’un entraîneur.
  2. Écrivez du javascript en utilisant jQuery pour retirer la classe show à l’élément enfant aside lorsqu'on ne survole plus le card.
info

Comme aside est un enfant de card, si l'utilisateur bouge sa souris à l'extérieur de la photo de l'entraîneur vers le aside, la souris est toujours techniquement au-dessus de card et ça ne cause pas d'événement onmouseout. Ça tombe bien, c'est exactement ce que l'on veut!

Image Reference
attention

C'est le moment de tester, ajouter des commentaires et faire votre commit et votre push

Faire fonctionner la pagination

Pour faire fonctionner la pagination, nous allons utiliser plusieurs propriétés importantes présente dans la propriété Items du ViewModel que reçoit la vue Trainer/Index.

  • La première contient l'index de la page actuellement sélectionnée : PageIndex. (Notez que cette propriété contient la même valeur que selectedPageIndex qui est affichée dans le formulaire. Vous pouvez donc utiliser une ou l'autre pour gérer la pagination. Nous rendrons toutefois le input selectedPageIndex hidden plus tard, pour le moment il est visible uniquement pour les tests).

  • La deuxième contient le nombre de pages au total : TotalPages

  • La troisième contient un booléen qui est à true s'il y a une page précédente : HasPreviousPage

  • La quatrième contient un booléen qui est à true s'il y a une page suivante : HasNextPage

  1. Modifiez le code (complètement en bas de la vue Index) pour que toutes les pages disponibles soient affichées dans la pagination. Assurez-vous que le li de la page sélectionnée ait la bonne classe.

  2. Ajoutez la logique pour que Previous et Next s'affichent seulement lorsqu'il le faut.

À chaque fois que nous allons cliquer sur un élément de la liste de pagination:

Image Reference

Il faudra changer la valeur de l'élément <input> correspondant au SelectedPageIndex, puis soumettre de nouveau le formulaire.

  1. Ajoutez le JavaScript/Jquery dans la vue. Utilisez les attributs data-page-id qui sont déjà présents sur les éléments de navigation pour savoir quelle page est sélectionnée. Voici quelques indications pour vous aider:

    • Exécutez une fonction JS lorsqu'un élément de pagination est cliqué.
    • Obtenez la valeur du data-page-id correspondant à l'élément sur lequel l'utilisateur a cliqué.
    • Obtenez l'élément qui contient l'information du SelectedPageIndex dans le formulaire (libre à vous d'ajouter une classe pour vous aider à l'obtenir plus facilement).
    • Modifiez sa valeur (attention aux cas particuliers Previous et Next).
    • Soumettez de nouveau le formulaire (pour cela on peut simplement utiliser la méthode submit() sur l'élément jQuery correspondant au formulaire).
  2. Une fois que votre navigation fonctionne bien, mettez le SelectedPageIndex (l'élément mentionné dans le point précédent) en type="hidden" et supprimez le libellé (label associé).

Image Reference
attention

C'est le moment de tester, ajouter des commentaires et faire votre commit et votre push

Générez les vues et le contrôleur (RecordController) du modèle Record

danger

Au moment de générer le contrôleur, il faut le nommer RecordController et non pas RecordsController (Donc, pas de s!). C'est important car les liens existants et les fichiers de traduction utilisent tous Record et non pas Records!

info

Si vous avez une erreur, assurez-vous d'utiliser la dernière version de toutes les librairies dans votre projet 8.0.X. Pendant la génération, le système met automatiquement à jour la version de la librairie Microsoft.VisualStudio.Web.CodeGeneration.Design qui utilise une version différente. Au moment d'écrire ces lignes, la version des librairies est maintenant 8.0.28, sauf pour Microsoft.VisualStudio.Web.CodeGeneration.Design qui est à 8.0.23.

attention

La génération de contrôleur utilise parfois des @ dans son code et ça cause des erreurs! Vous pouvez simplement remplacer les @ par un nom de variable différent, comme x.

astuce

La génération de contrôleur utilise des [bind] pour les actions post de Create et Edit. À moins que vous soyez déjà familier avec leur utilisation, vous pouvez simplement les retirer.

  1. Générez un contrôleur MVC avec ses vues pour le modèle Record. (Un lien vers cette vue existe déjà dans la barre de navigation)

  2. Créez un ViewModel (RecordViewModel) qui contiendra un propriété Record ainsi que les SelectList correspondants aux éléments <select> des formulaires dans les vues (disciplines et trainers). Dans le contrôleur, remplacez l'utilisation des ViewData par ce ViewModel.

attention

Il existe déjà des fichiers .resx pour le view model RecordViewModel. Si vous utilisez un autre nom ou utilisez d'autres view models, il faudra s'assurer de faire fonctionner la traduction.

  1. Dans les vues Create et Edit, remplacez les labels Trainer_Id par Trainer et Discipline_Id par Discipline

  2. Dans toutes les vues, lorsque vous affichez Trainer :

    • Affichez le nom complet du Trainer
  3. Dans toutes les vues, lorsque vous affichez Discipline :

    • Affichez le nom de la Discipline
  4. Créez un service pour gérer la création des ViewModels et les interactions avec le DbContext. Attention, pour avoir tous les points vous devez utiliser la classe générique ServiceBaseEF<>.

  5. Utilisez le service dans le contrôleur. Une fois que vous avez terminé, le contrôleur ne devra plus utiliser directement JulieProDBContext.

attention

C'est le moment de tester, ajouter des commentaires et faire votre commit et votre push

Ajoutez une vue pour voir les Records d'un Trainer

  1. Ajoutez une action TrainerIndex à votre contrôleur RecordController qui permet de voir les Records d'un Trainer, l'action recevra le trainerId en argument.
  2. Ajoutez également une vue TrainerIndex pour afficher les informations. Assurez-vous qu'elle affiche les mêmes éléments que l'exemple ci-dessous.
    • Dans la page d'accueil, il existe déjà une icône trophée sur le aside du Trainer qui vous permettra d'afficher cette page.
Image Reference
  1. S'il n'y a pas de record associé, la vue devra afficher cela. Pour ajouter un émoji, appuyez sur les touches "Window" et ";" du clavier.
Image Reference
attention

C'est le moment de tester, ajouter des commentaires et faire votre commit et votre push

Modifiez la vue Index du contrôleur Record

Retournez voir votre laboratoire de la séance 19, nous allons utiliser DataTable pour améliorer la vue Index.

  1. Changez le code pour afficher la Table avec DataTable. Si ça ne marche pas allez voir les erreurs dans la console (assurez-vous de charger DataTable après jQuery dans le code).
Image Reference
  1. Remplacez la pagination par du scrolling vertical, allez voir la documentation pour trouver le bon type de scrolling. Mettez la valeur du paramètre scrollY à 400px pour voir d'avantage de lignes.
Image Reference
  1. Dans votre code HTML, ajoutez un footer (<tfoot></tfoot>) à la table avec une rangée et le bon nombre de colonnes, mais sans contenu textuel.

  2. À l'aide des fonctionnalités offertes par DataTables, ajoutez une recherche par sélection pour les colonnes Discipline et Trainer, allez voir la documentation pour vous aider.

info

Pour cibler des colonnes, la méthode column() peut avoir une liste d'indices en argument, ex : column([4,6])

Image Reference
  1. La fonctionnalité suivante n'est pas évaluée et est difficile à réaliser, elle est seulement donnée pour ceux qui aiment les défis 💪. On veut que seulement les valeurs filtrées soient disponibles dans les listes de sélection.
info

Il n'est pas nécessaire d'afficher le texte --All-- dans la sélection, cet élément ne fait pas partie de la question et la case sera vide dans votre cas.

Image Reference
attention

C'est le moment de tester, ajouter des commentaires et faire votre commit et votre push

Terminez de mettre en place i18n

Ce qui est déjà fait :

  • Les packages NuGet sont installés
  • Les vues sont déjà traduites!
  • Les modèles aussi!
  • L'injection du IViewLocalizer est aussi déjà présente

Ce qu’il faut faire :

  • Il faut configurer i18n dans Program.cs. Les fichiers de traduction resx se trouvent dans le répertoire ** /i18n/ **
  • Il faut ajouter une fonction SetLanguage au HomeController
  • Il manque le commutateur de langue dans le _Layout. Utilisez une vue partielle et nommez-la _SelectLanguage
  • Finalement, il faut gérer la culture correctement en ajoutant les librairies nécessaires et en modifiant la vue partielle _ValidationScriptsPartial. (VOIR: Séance 24 et son laboratoire) (Assurez-vous que vous pouvez modifier une entrée avec un nombre avec une décimale en français et en anglais sans problème)
attention

C'est le moment de tester, ajouter des commentaires et faire votre commit et votre push

Vérification de la traduction

  1. Assurez-vous que vos nouvelles pages (Records) sont toutes bien traduites
    • Les resx sont généralement déjà là, utilisez-les
    • N'oubliez pas de faire la traduction pour le No records
    • On ne vous demande pas de faire la traduction du DataTable
    • Il manque la traduction des messages d’erreur. Assurez-vous de faire la traduction pour les cas suivants:
      • Une valeur de Amount invalide (Out of Range) (Modèle Record)
      • Un champ Unit manquant (champ vide) (Modèle Record)
      • Vous pouvez en faire plus, mais ce ne sera pas évalué. La traduction du message "must be a number" est assez complexe, alors ce n'est pas conseillé d'essayer de le traduire! Image Reference
attention

C'est le moment de tester, ajouter des commentaires et faire votre commit et votre push

Grille de correction

TâcheNb Points
Filtre et surlignage des TrainerCertifications5
Faire fonctionner le filtre de Trainer5
Afficher le détail d'un Trainer1
Faire fonctionner la pagination5
Ajouter RecordController7
Ajouter une vue pour les records d'un entraîneur3
Modifier la vue pour l'Index des records (dataTable js)4
Terminer de mettre en place i18n3
Traduire le contenu ajouté1
Commits avec textes pertinents1
Total/35