Créer un comparateur « drug checker » simplifié en js

Création d’un comparateur de produits en js

Le terme de comparateur est ici un peu trompeur, en fait l’idée est de donner à l’utilisateur la possibilité, à partir d’une page produit, de connaître les interactions avec d’autres produits.  On part donc du principe qu’on est déjà dans une page produit. Dans celle-ci, on va afficher un groupe de champ qui nous servira de comparateur. Un premier champ select avec tous les produits à comparer. Selon la sélection de l’utilisateur, on va afficher dans les champs suivants les informations correspondantes.

Voici le rendu de mon exemple :

champ dynamique

On a donc un menu déroulant, puis trois cases vides. Dans le code, ce sont des div et non des input texte. En dehors du cadre central on affiche des « familles » de produits par couleur, puis des « catégories » par des picto. Ces éléments sont juste esthétiques. La div centrale « interactions » récupère plutôt des informations sous forme de texte.

Afin de pouvoir classifier ces informations on place notre liste de produits dans un fichier json.

Le but est donc que l’utilisateur puisse, à partir d’un produit de la liste, savoir à quelle famille il appartient, quelles sont ses interactions avec le produit principal de la page, puis ses spécificités.

La construction de mon comparateur

Voici mon html

<div class="checker-inputs">
<div>
<label for="dci" class="flex j-center a-center">| DCI | </label>
<select id="dci" name="dci"></select>
</div>
<div>
<label for="family" class="flex j-center a-center">| Famille|</label>
<div id="family" class="">
<span class="color"></span>
</div>
</div>
<div>
<label for="interactions" class="flex j-center a-center">| Interactions|</label>
<div id="interactions" class=""></div>
</div>
<div>
<label for="cat" class="flex j-center a-center">| CAT**|</label>
<div id="cat" class="">
<span class="icon"></span>
</div>
</div>
</div>

On a un premier champ select, le reste ce sont des div stylisées comme des input texte.

Un fichier json

Pour regrouper la liste d’information, on pourrait tout à fait utiliser un fichier js, tout insérer dans une variable et travailler à partir de là. Ici j’utilise plus simplement un fichier à part, en json. Le but sera ensuite de récupérer toutes ces informations via notre js, et de l’insérer dans les différents champs.

Le fichier je l’appelle « interaction.json » et se compose de la manière suivante :

[{

"DCI": "Antidépresseurs tricyliques",
"Famille": "antidepresseurs",
"Interaction": "Sub. du CYP2D6",
"CAT": "diminuer"
},{
"DCI": "Amlodipine",
"Famille": "antihypertenseurs",
"Interaction": "Inhib. du CYP3A",
"CAT": "precaution"
}
,{
"DCI": "Aprépitant",
"Famille": "autres",
"Interaction": "Inhib. du CYP3A",
"CAT": "precaution"
}
]

Je n’en mets ici qu’un extrait. A l’intérieur, on définit plusieurs types ou catégories : dans mon exemple, ce sera « DCI » , « famille », « Interaction », « CAT ». Ces éléments permettent de classifier les informations et de les récupérer plus facilement.

La fonction js pour tout récupérer et insérer

Ensuite, dans un fichier js dédié, voici le code utilisé. Ce dernier est commenté pour mieux comprendre. En fait ici j’appelle le fichier json. Selon le choix de l’utilisateur, j’insère toutes les données « famille », « interactions » et « cat » correspondantes au produit choisi. Ensuite, je fais en sorte que l’élements choisi soit mis en exergue en front pour le distinguer plus facilement (voir le gif)

let dropdown = $('#dci');
let input1 = $('#family');
let input2 = $('#interactions');
let input3 = $('#cat');


dropdown.empty();//je vide le champ select
dropdown.append('<option selected="true" class="reset">Choisir un médoc</option>');//j'insère dynamiquement une option par défaut
const url = 'http://localhost/cerdelga-select/interaction.json'; // je définis l'url de mon fichier json
$.getJSON(url, function(data) {//je récupère les données
$.each(data, function (key, entry) {//pour chaque entrée..
dropdown.append($('<option></option>').attr('value', entry.DCI).text(entry.DCI));//j'insère depuis le fichier json les données de ma catégorie DCI à l'intérieur de l'attribut "value"
});
$('#dci').change(function() {//pour chaque selection de l'utilisateur
var i = this.selectedIndex; // je définis l'index du choix
i = i - 1;


input1.removeClass().addClass(data[i].Famille);//dans ma div #family je supprime la classe s'il y en a une, et j'ajoute la classe liée à ma catégorie famille
input2.text(data[i].Interaction);// dans ma div #interaction, j'insère les infos de ma catégorie interaction
input3.removeClass().addClass(data[i].CAT);//dans ma div #cat je supprime la classe s'il y en a une, et j'ajoute la classe liée à ma catégorie CAT


var elem = $(this).parent().next().find('div').attr('class');//depuis le champ select #dci, je remonte d'un cran dans le DOM, je cible l'élement suivant, à l'intérieur je cible la div, et prend la classe


$('p[data-rel = '+elem+']').removeClass().addClass('lighten').siblings().removeClass().addClass('darken');//ici je mets en exergue la catégorie correspondante
var car = $(this).parent().siblings().find('#cat').attr('class');//je récupère la classe de la div #cat
$('.checker-cat p[data-rel = '+car+']').removeClass().addClass('lighten').siblings().removeClass().addClass('darken');//pareil, je mets en exergue les élements CAT correspondants


});
});





Utiliser un plugin js pour l’autocomplétion : easy-autocomplete

Si la liste des produits comporte des dizaines d’option, il faudra à un moment passer à l’auto-complétion, afin d’éviter une liste à rallonge qui dépasse même le cadre de l’écran.

Voici donc une autre manière de faire. Je mets ici mon html, quelque peu modifié

  <div class="checker-inputs">
<div>
<label for="dci" class="flex j-center a-center">| DCI | </label>
<!-- <select id="dci" name="dci" autocomplete></select> -->
<input id="dci" name="dci">
</div>
<div>
<label for="family" class="flex j-center a-center">| Famille|</label>
<div id="family" class="">
<span class="color"></span>
</div>
</div>
<div>
<label for="interactions" class="flex j-center a-center">| Interactions|</label>
<input type="text" id="interactions" type="text" class="">
</div>
<div>
<label for="cat" class="flex j-center a-center">| CAT**|</label>
<div id="cat" class="">
<span class="icon"></span>
</div>
</div>
</div>

Ici, le premier champ est un select, le champ « interactions » est un input de type texte, les deux autres sont des div simples.

Dans cet exemple, je vais utiliser easy-autocomplete. Ce plugin d’auto-complétion est très bien fait et propose plein d’options, pour tout type de projet.

Dans mon header, j’appelle donc le fichier css puis dans le footer, le script easy-complete.

<!--balise head-->
<link rel="stylesheet" href="css/easy-autocomplete.css">

<!--footer-->
<script src="js/jquery.easy-autocomplete.js"></script>

Le résultat sera exactement le même, sauf qu’à la place d’une liste sans fin, le select va nous afficher tous les termes correspondants aux premières lettre tapées. Le plugin permet aussi de remplir automatiquement les champs vides en fonction du choix utilisateur. Veuillez vous reporter à la page d’exemple du plugin, d’où j’ai tiré l’essentiel du code.

Voici la fonction js :

var options = {
adjustWidth: false,

url: "http://localhost/interaction.json",

getValue: "DCI",//on récupère chaque entrée du fichier json grâce à la fonction getValue du plugin

list: {
match: {
enabled: true
},
sort:{
enabled: true // rangement par ordre alphabétique

},
maxNumberOfElements: 10, // max
onSelectItemEvent: function() {// on récupère les données de chaque entrée qu'on insère dans les div correspondantes
var famille = $("#dci").getSelectedItemData().Famille;
var interaction = $("#dci").getSelectedItemData().Interaction;
var cat = $("#dci").getSelectedItemData().CAT;

$("#family").removeClass().addClass(famille).trigger("change");// comme dans le précédent exemple,
$("#interactions").val(interaction).trigger("change");
$("#cat").removeClass().addClass(cat).trigger("change");
}
}
};

$("#dci").easyAutocomplete(options);

Le code en action

Voici un exemple reprenant tous les élements décrits plus haut

See the Pen
EasyAutoComplete js and dynamic select fields
by blindDev (@yuyazz)
on CodePen.