Ajout possibilité ou non de rendre le moteur de recherche sensible à la casse, aux accents ou encore à ignorer ou pas certains caractères spéciaux.
This commit is contained in:
parent
ce1356f10a
commit
a7ca9c2e1a
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "freedatas2html",
|
||||
"version": "1.3.2",
|
||||
"version": "1.4.0",
|
||||
"description": "Conversion and display of data in different formats (CSV, JSON, HTML) with the possibility of filtering, classifying and paginating the results.",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
@ -1,5 +1,5 @@
|
||||
const errors=require("./errors.js");
|
||||
import { DOMElement, Filters } from "./interfaces";
|
||||
import { DOMElement, Filters, SearchModeSettings } from "./interfaces";
|
||||
import { FreeDatas2HTML } from "./FreeDatas2HTML";
|
||||
|
||||
export class SearchEngine implements Filters
|
||||
@ -13,6 +13,13 @@ export class SearchEngine implements Filters
|
||||
public placeholder: string="";
|
||||
public automaticSearch: boolean=false;
|
||||
private _inputValue: string="";
|
||||
public searchMode:SearchModeSettings= // par défaut, recherche lâche, mais peut devenir stricte en passant tout à false
|
||||
{
|
||||
accentOff: true,
|
||||
caseOff: true,
|
||||
specialCharsOff: true,
|
||||
specialCharsWhiteList: "",
|
||||
}
|
||||
|
||||
// Injection de la classe principale, mais uniquement si des données ont été importées
|
||||
constructor(converter: FreeDatas2HTML, elt: DOMElement, fields?: number[])
|
||||
@ -111,9 +118,33 @@ export class SearchEngine implements Filters
|
||||
});
|
||||
}
|
||||
|
||||
// Pré-traitement des chaînes de caractères à comparer, suivant le mode de recherche
|
||||
private searchPreProcessing(searchElement: string) : string
|
||||
{
|
||||
let finalString=searchElement;
|
||||
if(this.searchMode.accentOff) // caractères accentués remplacés (exemple : "é" -> "e")
|
||||
finalString=finalString.normalize("NFD").replace(/[\u0300-\u036f]/g, ""); // cf. https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript
|
||||
if(this.searchMode.caseOff)
|
||||
finalString=finalString.toLowerCase();
|
||||
if(this.searchMode.specialCharsOff)
|
||||
{
|
||||
// Suppression de tous les caractères "spéciaux", c'est-à-dire n'étant ni une lettre, ni un chiffre
|
||||
// ! Doit être exécuté après "accentOff", sans quoi les caractères accentués seront supprimés avant d'être remplacés
|
||||
const validChars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"+this.searchMode.specialCharsWhiteList;
|
||||
let validString="";
|
||||
for(const letter of finalString)
|
||||
{
|
||||
if(validChars.indexOf(letter) !== -1)
|
||||
validString+=letter;
|
||||
}
|
||||
finalString=validString;
|
||||
}
|
||||
return finalString;
|
||||
}
|
||||
|
||||
public dataIsOk(data: {[index: string]:string}) : boolean
|
||||
{
|
||||
const realSearch=this._inputValue.trim().toLowerCase();
|
||||
const realSearch=this.searchPreProcessing(this._inputValue.trim());
|
||||
// Pas de valeur sélectionnée = pas de filtre sur ce champ
|
||||
if(realSearch.length === 0)
|
||||
return true;
|
||||
@ -122,8 +153,7 @@ export class SearchEngine implements Filters
|
||||
{
|
||||
if(this._fields2Search.indexOf(field) !== -1)
|
||||
{
|
||||
// Attention, recherche insensible à la casse, mais aux accents, etc.
|
||||
if(data[field].toLowerCase().indexOf(realSearch) !== -1)
|
||||
if(this.searchPreProcessing(data[field]).indexOf(realSearch) !== -1)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -81,6 +81,13 @@ export interface RemoteSources extends RemoteSourceSettings
|
||||
{
|
||||
getFetchSettings() : {};
|
||||
}
|
||||
export interface SearchModeSettings
|
||||
{
|
||||
accentOff: boolean;
|
||||
caseOff: boolean;
|
||||
specialCharsOff: boolean;
|
||||
specialCharsWhiteList: string;
|
||||
}
|
||||
export interface Selectors extends Filters
|
||||
{
|
||||
datasFieldNb: number;
|
||||
|
@ -239,9 +239,9 @@ describe("Test du moteur de recherche.", () =>
|
||||
|
||||
it("Doit retourner false, si une donnée testée ne correspond pas à la valeur cherchée.", async () =>
|
||||
{
|
||||
searchInput.value="Halogène";
|
||||
searchInput.value="Hallogène";
|
||||
searchInput.dispatchEvent(new Event("input"));
|
||||
expect(mySearch.dataIsOk({ "Famille": "Halogene" })).toBeFalse();// sensible aux accents
|
||||
expect(mySearch.dataIsOk({ "Famille": "Halogène" })).toBeFalse();
|
||||
});
|
||||
|
||||
it("Doit retourner true, si la valeur recherchée est trouvée dans la donnée recherchée, sans prendre en compte la casse, ni les espaces entourant la saisie.", () =>
|
||||
@ -254,15 +254,57 @@ describe("Test du moteur de recherche.", () =>
|
||||
searchInput.value="gène";
|
||||
searchInput.dispatchEvent(new Event("input"));
|
||||
expect(mySearch.dataIsOk({ "Famille": "Halogène" })).toBeTrue();
|
||||
// Insensible à casse :
|
||||
searchInput.value="halo";
|
||||
searchInput.dispatchEvent(new Event("input"));
|
||||
expect(mySearch.dataIsOk({ "Famille": "Halogène" })).toBeTrue();
|
||||
// Espace entourant la saisie ignorés :
|
||||
searchInput.value=" halo ";
|
||||
searchInput.dispatchEvent(new Event("input"));
|
||||
expect(mySearch.dataIsOk({ "Famille": "Halogène" })).toBeTrue();
|
||||
// Par défaut, la recherche doit être tolérante à la casse, à la présence ou non d'accent et ignorer les caractères n'étant ni des lettres, ni des chiffres
|
||||
searchInput.value="Halogene";
|
||||
searchInput.dispatchEvent(new Event("input"));
|
||||
expect(mySearch.dataIsOk({ "Famille": "Halogène" })).toBeTrue();
|
||||
searchInput.value="halogène";
|
||||
searchInput.dispatchEvent(new Event("input"));
|
||||
expect(mySearch.dataIsOk({ "Famille": "Halogène" })).toBeTrue();
|
||||
searchInput.value="#Halogène";
|
||||
searchInput.dispatchEvent(new Event("input"));
|
||||
expect(mySearch.dataIsOk({ "Famille": "Halogène" })).toBeTrue();
|
||||
});
|
||||
|
||||
it("Si demandé doit traiter les données avant de les comparer de manière à prendre en compte les accents, majuscules ou caractères spéciaux.", () =>
|
||||
{
|
||||
// Sensible à casse :
|
||||
mySearch.searchMode.caseOff=false;
|
||||
searchInput.value="halogène";
|
||||
searchInput.dispatchEvent(new Event("input"));
|
||||
expect(mySearch.dataIsOk({ "Famille": "Halogène" })).toBeFalse();
|
||||
searchInput.value="Halogène";
|
||||
searchInput.dispatchEvent(new Event("input"));
|
||||
expect(mySearch.dataIsOk({ "Famille": "halogène" })).toBeFalse();
|
||||
// Sensible aux accents :
|
||||
mySearch.searchMode.accentOff=false;
|
||||
searchInput.value="Halogene";
|
||||
searchInput.dispatchEvent(new Event("input"));
|
||||
expect(mySearch.dataIsOk({ "Famille": "Halogène" })).toBeFalse();
|
||||
searchInput.value="Halogène";
|
||||
searchInput.dispatchEvent(new Event("input"));
|
||||
expect(mySearch.dataIsOk({ "Famille": "Halogene" })).toBeFalse();
|
||||
// Prise en compte des caractères spéciaux :
|
||||
mySearch.searchMode.specialCharsOff=false;
|
||||
searchInput.value="Halogène^";
|
||||
searchInput.dispatchEvent(new Event("input"));
|
||||
expect(mySearch.dataIsOk({ "Famille": "Halogène" })).toBeFalse();
|
||||
searchInput.value="Halogène";
|
||||
searchInput.dispatchEvent(new Event("input"));
|
||||
expect(mySearch.dataIsOk({ "Famille": "Ha+logène" })).toBeFalse();
|
||||
// Ignore les caractères spéciaux, sauf ceux en liste blanche :
|
||||
mySearch.searchMode.specialCharsOff=true;
|
||||
mySearch.searchMode.specialCharsWhiteList="^+";
|
||||
expect(mySearch.dataIsOk({ "Famille": "Ha+logène" })).toBeFalse();
|
||||
searchInput.value="Halogène^";
|
||||
searchInput.dispatchEvent(new Event("input"));
|
||||
expect(mySearch.dataIsOk({ "Famille": "Halogène" })).toBeFalse();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user