Ajout de la possibilité de chercher séparément (ou pas) chacun des mots saisis.

This commit is contained in:
Fabrice PENHOËT 2022-02-21 16:56:19 +01:00
parent a7ca9c2e1a
commit 7d85e375c5
4 changed files with 49 additions and 11 deletions

View File

@ -1,6 +1,6 @@
{
"name": "freedatas2html",
"version": "1.4.0",
"version": "1.5.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": {

View File

@ -17,6 +17,7 @@ export class SearchEngine implements Filters
{
accentOff: true,
caseOff: true,
separatedWords: true, // doit-on chercher l'expression en entier ou chacun des mots ?
specialCharsOff: true,
specialCharsWhiteList: "",
}
@ -128,9 +129,9 @@ export class SearchEngine implements Filters
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
// Suppression de tous les caractères "spéciaux", c'est-à-dire n'étant ni une lettre, ni un chiffre, ni un espace
// ! 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;
const validChars="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 "+this.searchMode.specialCharsWhiteList;
let validString="";
for(const letter of finalString)
{
@ -145,18 +146,36 @@ export class SearchEngine implements Filters
public dataIsOk(data: {[index: string]:string}) : boolean
{
const realSearch=this.searchPreProcessing(this._inputValue.trim());
// Pas de valeur sélectionnée = pas de filtre sur ce champ
// Pas de valeur saisie = pas de filtre sur ce champ
if(realSearch.length === 0)
return true;
// Sinon, on cherche la valeur saisie dans tous les champs définis :
// L'expression saisie doit-elle être séparée en plusieurs "mots" ?
let searchedWords: string[]=[];
if(this.searchMode.separatedWords)
searchedWords=realSearch.split(" ");
else
searchedWords[0]=realSearch;
// Chacun des "mots" doit être trouvé au moins une fois :
let nbFound=0;
for(const word of searchedWords)
{
for(let field in data)
{
if(this._fields2Search.indexOf(field) !== -1)
{
if(this.searchPreProcessing(data[field]).indexOf(realSearch) !== -1)
if(this.searchPreProcessing(data[field]).indexOf(word.trim()) !== -1)
{
nbFound++;
break; // ! sinon, on peut trouver +sieurs fois le même "mot" dans les différents champs.
}
}
}
}
if(nbFound < searchedWords.length) // tous les mots doivent être trouvés
return false;
else
return true;
}
}
return false;
}
}

View File

@ -85,6 +85,7 @@ export interface SearchModeSettings
{
accentOff: boolean;
caseOff: boolean;
separatedWords: boolean;
specialCharsOff: boolean;
specialCharsWhiteList: string;
}

View File

@ -305,6 +305,24 @@ describe("Test du moteur de recherche.", () =>
expect(mySearch.dataIsOk({ "Famille": "Halogène" })).toBeFalse();
});
it("Si demandé doit cherché l'expression en entier et non chacun des mots séparément.", async () =>
{
// Cas normal, ok si tous les mots sont trouvés séparément :
searchInput.value="gaz noble";
searchInput.dispatchEvent(new Event("input"));
expect(mySearch.dataIsOk({ "Famille": "le gaz est noble" })).toBeTrue();
expect(mySearch.dataIsOk({ "Famille": "noble est le gaz" })).toBeTrue();
expect(mySearch.dataIsOk({ "Famille": "gaz", "Symbole":"noble" })).toBeTrue();
// Il faut trouvé au moins une fois l'expression entière dans un des champs :
mySearch.searchMode.separatedWords=false;
searchInput.dispatchEvent(new Event("input"));
expect(mySearch.dataIsOk({ "Famille": "gaz noble" })).toBeTrue();
expect(mySearch.dataIsOk({ "Famille": "gaz noble", "Symbole":"He" })).toBeTrue();
expect(mySearch.dataIsOk({ "Famille": "le gaz est noble" })).toBeFalse();
expect(mySearch.dataIsOk({ "Famille": "gaz", "Symbole":"noble" })).toBeFalse();
});
});
});