Ce TP optionnel, fait suite au TP précédents en proposant d'ajouter une fonctionnalité de filtrage des films retournés par l'API web. Le filtrage sera réalisé à l'aide de mots-clés avec suggestion de ceux-ci.
Les notes des TP seront obtenues à partir de vos dépôts Git, vous devrez donc prendre grand soin de la qualité de ces dépôts et de leurs « commits ».
De manière similaire, les descriptions de vos « commits » devront être claires et informatives, afin de permettre l'évaluation de la progression de votre travail.
Dans la suite du TP, vous allez mettre en place l'interface permettant à l'utilisateur de sélectionner des mots-clés permettant de filtrer la liste des films.
La gestion des mots-clés permettant le filtrage de la liste des films suppose que l'interface de gestion du filtrage propose deux modes d'interaction à l'utilisateur :
La structure de l'interface de sélection des mots-clés permettant le filtrage de la liste de films est centralisée dans l'élément HTML « fieldset.filters », comme illustré dans la maquette suivante :
Elle se compose de quatre parties :
Par défaut, au chargement de la page, seul le bouton et la liste des mots-clés (vide) sont visibles.
Dans le cadre de la gestion des filtres, l'utilisateur va régulièrement changer l'affichage de la zone de filtrage en basculant du mode de sélection des filtres à celui de présentation et inversement. Pour vous faciliter la gestion de ce point, vous allez réaliser une fonction permettant de gérer l'affichage de la zone de filtrage.
Vous ajouterez une fonction setFiltersDisplay(filtersElt, isSelectionMode)
dont le rôle sera d'afficher ou de cacher les éléments de l'interface en fonction du mode défini par le paramètre isSelectionMode
.
Le paramètre filtersElt
contiendra l'élément DOM représentant l'interface de filtrage des films (« fieldset.filters »).
Si le paramètre isSelectionMode
est vrai, alors le bouton et la liste des mots-clés doivent être cachés et la recherche et les propositions doivent être affichés.
Si le paramètre isSelectionMode
est faux, alors le bouton et la liste des mots-clés doivent être affichés et la recherche et les propositions doivent être cachés.
Pour cacher un élément HTML grâce au DOM, vous lui ajouterez la classe CSS « hidden » et vous lui supprimerez cette même classe CSS « hidden » pour l'afficher. Pour vous simplifier la manipulation des classes CSS, vous utiliserez la propriété classList
, et en particulier sa méthode toggle()
.
setFiltersDisplay(filtersElt, isSelectionMode)
.
Vous ajouterez la fonction setFiltersEltsEvents()
permettant d'initialiser les gestionnaires d'événements de la zone de filtrage.
Pour commencer vous enregistrerez un gestionnaire d'événements sur le bouton, permettant de basculer vers l'affichage de sélection lors du clic de la souris.
Le bouton étant caché lors du mode de sélection, nous ne pouvons pas l'utiliser pour quitter le mode de sélection. Vous allez utiliser une astuce courante qui consiste à détecter le clic à l'extérieur de la zone de gestion du filtrage pour fermer le mode de sélection.
Vous ajouterez un gestionnaire d'événements sur l'ensemble de la page au clic de la souris. Dans la fonction de rappel associée, vous testerez si la cible du clic est bien contenue dans l'élément DOM de gestion du filtrage (« fieldset.filters »), et, si non, vous quitterez l'affichage du mode de sélection.
setFiltersEltsEvents()
.
Maintenant que l'utilisateur peut afficher l'interface de recherche de mots-clés, vous allez préparer la requête HTTP pour obtenir la liste des propositions de mots-clés correspondant à la recherche.
Vous ajouterez la fonction getAllKeywords(abortController, text)
qui réalisera la requête HTTP vers l'API web pour obtenir la liste des mots-clés contenant le texte passé en paramètre text
. La fonction retournera la promesse d'un objet JavaScript contenant deux propriétés :
collection
, la collection de mots-clés retournée par l'API web
pagination
les informations de pagination de la collection.
getAllKeywords(abortController, text)
.
Vous ajouterez une fonction handleKeywordsSearch(filtersElt, text)
dont le rôle sera :
Cette fonction sera invoquée lors de chaque émission d'un événement « keyup » par le champ de recherche. L'enregistrement de l'écouteur d'événement sera réalisé dans la fonction setFiltersEltsEvents()
.
handleKeywordsSearch(filtersElt, text)
.
setFiltersEltsEvents()
.
Vous ajouterez la fonction createPropositionButtonDom(filtersElt, keyword)
, qui retournera un élément DOM button
de type « button
», avec une classe CSS « proposition
» et contenant le nom extrait du mot-clé passé en paramètre (keyword
, contenant les propriétés uuid
et name
).
Vous ajouterez aussi la fonction updatePropositionsList(filtersElt, data)
, qui pour chaque élément de la collection obtenue de la réponse HTTP de l'API web pour la recherche de mots-clés, ajoutera un bouton, créé à l'aide de la fonction précédente, à l'élément DOM contenant la liste des propositions.
Cette fonction remplira l'élément DOM affichant la liste des propositions de mots-clés, les éléments DOM affichant une proposition de mot-clé seront obtenus par l'invocation de la fonction createPropositionButtonDom()
.
Lorsque la collection transmise dans le paramètre data
est paginée, vous ajouterez des points de suspension à la fin de votre liste. Afin de ne pas modifier les éléments DOM précédemment ajoutés, vous utiliserez la méthode createTextNode
pour créer l'élément DOM affichant les points de suspension.
createPropositionButtonDom(filtersElt, keyword)
.
updatePropositionsList(filtersElt, data)
.
Lorsque l'utilisateur clique sur le bouton d'ajout d'un mot-clé, il doit ensuite sélectionner le champ de saisie. Il est courant, lorsque l'on affiche un élément d'interaction, de placer le focus de l'application sur cet élément à l'aide de la méthode focus(). Dans notre cas, comme nous n'effaçons jamais le contenu du champ de saisie, nous allons présélectionner le texte à l'aide de la méthode select() pour que l'utilisateur puisse facilement le remplacer au besoin.
Dans la fonction setFiltersDisplay()
, vous invoquerez la méthode select()
sur le champ de saisie si l'affichage est en mode de sélection.
setFiltersDisplay()
.
Vous commencerez par créer la fonction createFilterButtonDom(keyword)
qui retournera un élément DOM button
de type « button
», avec un classe CSS « filter
». La valeur du bouton sera initialisée avec l'UUID du mot-clé passé en paramètre et son contenu recevra une icône Material Symbol close
suivie du nom du mot-clé.
Ensuite, dans la fonction createPropositionButtonDom()
, vous ajouterez un gestionnaire de clics de souris, dont la fonction de rappel aura pour objectif :
createFilterButtonDom()
et de l'ajouter à la liste des filtres
updateMoviesElt()
createFilterButtonDom(keyword)
.
Pour le moment, lorsque l'utilisateur ajoute un mot-clé à la liste des filtres, la collection des films est mise à jour, mais elle n'est pas filtrée.
Pour palier ce problème, vous créerez la fonction appendFiltersToQuery(urlSearchParams)
, qui extraira la liste des éléments DOM des filtres de la liste (« .filters__list »). La valeur de chaque filtre, associée au nom de paramètre d'URL « keywords.uuid[] », sera ajoutée aux paramètres d'URL urlSearchParams
.
Cette nouvelle fonction pourra ensuite être invoquée depuis la fonction updateMoviesElt()
afin d'enrichir les paramètres de la requête HTTP d'obtention de la liste de films.
appendFiltersToQuery(urlSearchParams)
.
Pour finir, vous ajouterez sur les boutons de filtres un gestionnaire de clics pour lequel la fonction de rappel supprimera le bouton et mettra à jour la liste de film.