Nouvelle version avec possibilité de liste de filtre permettant de sélectionner plusieurs valeurs.
This commit is contained in:
parent
6532c04ca1
commit
7a4992a243
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "freedatas2html",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.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": {
|
||||
|
144
src/Selector.ts
144
src/Selector.ts
@ -8,10 +8,11 @@ export class Selector implements Selectors
|
||||
private _converter: FreeDatas2HTML;
|
||||
private _datasFieldNb: number;
|
||||
private _datasViewElt: DOMElement={ id: "", eltDOM: undefined };
|
||||
private _selectedValue: number|undefined=undefined;
|
||||
private _selectedValues: number[]=[];
|
||||
private _separator: string|undefined;
|
||||
private _values: string[]=[];
|
||||
private _name: string="";
|
||||
public isMultiple: boolean=false;// permet à l'utilisateur de sélectionner plusieurs valeurs dans la liste.
|
||||
|
||||
// Injection de la classe principale, mais uniquement si des données ont été importées.
|
||||
// Le champ duquel le sélecteur tire ses données doit exister.
|
||||
@ -29,6 +30,8 @@ export class Selector implements Selectors
|
||||
// Pas de trim(), car l'espace peut être le séparateur :
|
||||
if(separator !== undefined && separator !== "")
|
||||
this._separator=separator;
|
||||
this._name=this._converter.fields[this._datasFieldNb];
|
||||
this.setValues();
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,9 +55,9 @@ export class Selector implements Selectors
|
||||
return this._name;
|
||||
}
|
||||
|
||||
get selectedValue() : number|undefined
|
||||
get selectedValues() : number[]
|
||||
{
|
||||
return this._selectedValue;
|
||||
return this._selectedValues;
|
||||
}
|
||||
|
||||
get separator() : string|undefined
|
||||
@ -67,11 +70,10 @@ export class Selector implements Selectors
|
||||
return this._values;
|
||||
}
|
||||
|
||||
// Création du <select> dans le DOM correspondant au filtre
|
||||
public filter2HTML(label:string="") : void
|
||||
// Dédoublonnage et classement des valeurs disponibles pour le champ du sélecteur
|
||||
private setValues() :void
|
||||
{
|
||||
this._name=this._converter.fields![this._datasFieldNb]; // "!", car l'existence du champ est testé par le constructeur.
|
||||
for (let row of this._converter.datas)
|
||||
for (const row of this._converter.datas)
|
||||
{
|
||||
let checkedValue;
|
||||
if(this._separator === undefined)
|
||||
@ -83,7 +85,7 @@ export class Selector implements Selectors
|
||||
else
|
||||
{
|
||||
let checkedValues=row[this._name].split(this._separator);
|
||||
for(let value of checkedValues)
|
||||
for(const value of checkedValues)
|
||||
{
|
||||
checkedValue=value.trim();
|
||||
if(checkedValue !== "" && this._values.indexOf(checkedValue) === -1)
|
||||
@ -101,66 +103,96 @@ export class Selector implements Selectors
|
||||
this._values.sort(this._converter.getSortingFunctionForField(this._datasFieldNb)!.sort); // sans le "!" : TS2532: Object is possibly 'undefined' ???
|
||||
else
|
||||
this._values.sort(compare());
|
||||
|
||||
// Création et injection du SELECT dans le DOM :
|
||||
label=(label === "") ? this._name : label;
|
||||
let selectorsHTML="<label for='freeDatas2HTML_"+this._datasViewElt.id+"'>"+label+" :</label><select name='freeDatas2HTML_"+this._datasViewElt.id+"' id='freeDatas2HTML_"+this._datasViewElt.id+"'><option value='0'>----</option>"; // l'option zéro permet d'actualiser l'affichage en ignorant ce filtre.
|
||||
for(let i=0; i< this._values.length; i++)
|
||||
selectorsHTML+="<option value='"+(i+1)+"'>"+this._values[i]+"</option>";
|
||||
selectorsHTML+="</select>";
|
||||
this. _datasViewElt.eltDOM!.innerHTML=selectorsHTML;// "!", car l'existence de "eltDOM" est testé par le constructeur.
|
||||
|
||||
// Actualisation de l'affichage lorsqu'une valeur est sélectionnée :
|
||||
const selectElement=document.getElementById("freeDatas2HTML_"+this._datasViewElt.id) as HTMLInputElement, mySelector=this;
|
||||
selectElement.addEventListener("change", function(e)
|
||||
{
|
||||
if(selectElement.value === "0")
|
||||
mySelector._selectedValue=undefined;
|
||||
else
|
||||
mySelector._selectedValue=parseInt(selectElement.value,10)-1;
|
||||
mySelector._converter.refreshView();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Création du <select> dans le DOM correspondant au filtre
|
||||
public filter2HTML(label:string="") : void
|
||||
{
|
||||
label=(label === "") ? this._name : label;
|
||||
const multipleAttr=(this.isMultiple)? " multiple" :"";
|
||||
let selectorsHTML="<label for='freeDatas2HTML_"+this._datasViewElt.id+"'>"+label+" :</label><select name='freeDatas2HTML_"+this._datasViewElt.id+"' id='freeDatas2HTML_"+this._datasViewElt.id+"'"+multipleAttr+"><option value='0'>----</option>"; // l'option zéro permet d'actualiser l'affichage en ignorant ce filtre.
|
||||
for(let i=0; i< this._values.length; i++)
|
||||
selectorsHTML+="<option value='"+(i+1)+"'>"+this._values[i]+"</option>";
|
||||
selectorsHTML+="</select>";
|
||||
this. _datasViewElt.eltDOM!.innerHTML=selectorsHTML;// "!", car l'existence de "eltDOM" est testé par le constructeur.
|
||||
// Actualisation de l'affichage lorsqu'une valeur est sélectionnée :
|
||||
const selectElement=document.getElementById("freeDatas2HTML_"+this._datasViewElt.id) as HTMLSelectElement, mySelector=this;
|
||||
selectElement.addEventListener("change", function(e)
|
||||
{
|
||||
mySelector._selectedValues=[];
|
||||
if(mySelector.isMultiple)
|
||||
{
|
||||
for(let i=0; i < selectElement.selectedOptions.length; i++)
|
||||
{
|
||||
const selectedValue=parseInt(selectElement.selectedOptions[i].value,10);
|
||||
if(selectedValue === 0) // = annulation de ce filtre
|
||||
{
|
||||
mySelector._selectedValues=[];
|
||||
break;
|
||||
}
|
||||
else
|
||||
mySelector._selectedValues.push(selectedValue-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
let selectedValue=parseInt(selectElement.value,10);
|
||||
if(selectedValue === 0) // = annulation de ce filtre
|
||||
mySelector._selectedValues=[];
|
||||
else
|
||||
mySelector._selectedValues[0]=selectedValue-1;
|
||||
}
|
||||
mySelector._converter.refreshView();
|
||||
});
|
||||
}
|
||||
|
||||
public dataIsOk(data: {[index: string]:string}) : boolean
|
||||
{
|
||||
// Permet de vérifier que filter2HTML() a été préalablement appelée :
|
||||
if(this._name === "")
|
||||
throw new Error(errors.filterCheckIsOkFail);
|
||||
const checkIsValid=(selector : Selector, data: {[index: string]:string}, checkedValue:string) : boolean =>
|
||||
{
|
||||
if(selector._separator === undefined)
|
||||
{
|
||||
if(data[selector._name].trim() !== checkedValue)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
let find=false;
|
||||
let checkedValues=data[selector._name].split(selector._separator);
|
||||
for(let value of checkedValues)
|
||||
{
|
||||
if(value.trim() === checkedValue)
|
||||
{
|
||||
find=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return find;
|
||||
}
|
||||
};
|
||||
|
||||
// Pas de valeur sélectionnée = pas de filtre sur ce champ
|
||||
if(this._selectedValue === undefined)
|
||||
// Pas de valeur sélectionnée = pas de filtre sur ce champ, donc tout passe :
|
||||
if(this._selectedValues.length === 0)
|
||||
return true;
|
||||
|
||||
if(this._values[this._selectedValue] === undefined) // théoriquement impossible, mais cela vient du client...
|
||||
throw new Error(errors.selectorSelectedIndexNotFound);
|
||||
|
||||
// Si le champ est absent pour un enregistrement, il est refusé
|
||||
// Un enregistrement n'ayant pas le champ du filtre sera refusé :
|
||||
if(data[this._name] === undefined)
|
||||
return false;
|
||||
|
||||
const selectedValueTxt=this._values[this._selectedValue];
|
||||
if(this._separator === undefined)
|
||||
// Si plusieurs options sont sélectionnées dans une liste multiple,
|
||||
// il suffit qu'une soit trouvée pour que l'enregistrement soit valide.
|
||||
let find=false;
|
||||
for(const value of this._selectedValues)
|
||||
{
|
||||
if(data[this._name].trim() !== selectedValueTxt)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
let find=false;
|
||||
let checkedValues=data[this._name].split(this._separator);
|
||||
for(let value of checkedValues)
|
||||
{
|
||||
if(value.trim() === selectedValueTxt)
|
||||
{
|
||||
find=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return find;
|
||||
if(this._values[value] === undefined) // théoriquement impossible, mais cela vient du client...
|
||||
throw new Error(errors.selectorSelectedIndexNotFound);
|
||||
find=checkIsValid(this, data, this._values[value]);
|
||||
if(find)
|
||||
break;
|
||||
}
|
||||
return find;
|
||||
}
|
||||
}
|
@ -4,9 +4,10 @@ import { FreeDatas2HTML } from "./FreeDatas2HTML";
|
||||
var Selector = (function () {
|
||||
function Selector(converter, datasFieldNb, elt, separator) {
|
||||
this._datasViewElt = { id: "", eltDOM: undefined };
|
||||
this._selectedValue = undefined;
|
||||
this._selectedValues = [];
|
||||
this._values = [];
|
||||
this._name = "";
|
||||
this.isMultiple = false;
|
||||
if (converter.fields.length === 0 || converter.datas.length === 0)
|
||||
throw new Error(errors.filterNeedDatas);
|
||||
else if (!converter.checkFieldExist(Number(datasFieldNb)))
|
||||
@ -17,6 +18,8 @@ var Selector = (function () {
|
||||
this._datasFieldNb = datasFieldNb;
|
||||
if (separator !== undefined && separator !== "")
|
||||
this._separator = separator;
|
||||
this._name = this._converter.fields[this._datasFieldNb];
|
||||
this.setValues();
|
||||
}
|
||||
}
|
||||
Object.defineProperty(Selector.prototype, "converter", {
|
||||
@ -47,9 +50,9 @@ var Selector = (function () {
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(Selector.prototype, "selectedValue", {
|
||||
Object.defineProperty(Selector.prototype, "selectedValues", {
|
||||
get: function () {
|
||||
return this._selectedValue;
|
||||
return this._selectedValues;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
@ -68,9 +71,7 @@ var Selector = (function () {
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Selector.prototype.filter2HTML = function (label) {
|
||||
if (label === void 0) { label = ""; }
|
||||
this._name = this._converter.fields[this._datasFieldNb];
|
||||
Selector.prototype.setValues = function () {
|
||||
for (var _i = 0, _a = this._converter.datas; _i < _a.length; _i++) {
|
||||
var row = _a[_i];
|
||||
var checkedValue = void 0;
|
||||
@ -96,50 +97,76 @@ var Selector = (function () {
|
||||
this._values.sort(this._converter.getSortingFunctionForField(this._datasFieldNb).sort);
|
||||
else
|
||||
this._values.sort(compare());
|
||||
label = (label === "") ? this._name : label;
|
||||
var selectorsHTML = "<label for='freeDatas2HTML_" + this._datasViewElt.id + "'>" + label + " :</label><select name='freeDatas2HTML_" + this._datasViewElt.id + "' id='freeDatas2HTML_" + this._datasViewElt.id + "'><option value='0'>----</option>";
|
||||
for (var i = 0; i < this._values.length; i++)
|
||||
selectorsHTML += "<option value='" + (i + 1) + "'>" + this._values[i] + "</option>";
|
||||
selectorsHTML += "</select>";
|
||||
this._datasViewElt.eltDOM.innerHTML = selectorsHTML;
|
||||
var selectElement_1 = document.getElementById("freeDatas2HTML_" + this._datasViewElt.id), mySelector_1 = this;
|
||||
selectElement_1.addEventListener("change", function (e) {
|
||||
if (selectElement_1.value === "0")
|
||||
mySelector_1._selectedValue = undefined;
|
||||
else
|
||||
mySelector_1._selectedValue = parseInt(selectElement_1.value, 10) - 1;
|
||||
mySelector_1._converter.refreshView();
|
||||
});
|
||||
}
|
||||
};
|
||||
Selector.prototype.dataIsOk = function (data) {
|
||||
if (this._name === "")
|
||||
throw new Error(errors.filterCheckIsOkFail);
|
||||
if (this._selectedValue === undefined)
|
||||
return true;
|
||||
if (this._values[this._selectedValue] === undefined)
|
||||
throw new Error(errors.selectorSelectedIndexNotFound);
|
||||
if (data[this._name] === undefined)
|
||||
return false;
|
||||
var selectedValueTxt = this._values[this._selectedValue];
|
||||
if (this._separator === undefined) {
|
||||
if (data[this._name].trim() !== selectedValueTxt)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
var find = false;
|
||||
var checkedValues = data[this._name].split(this._separator);
|
||||
for (var _i = 0, checkedValues_2 = checkedValues; _i < checkedValues_2.length; _i++) {
|
||||
var value = checkedValues_2[_i];
|
||||
if (value.trim() === selectedValueTxt) {
|
||||
find = true;
|
||||
break;
|
||||
Selector.prototype.filter2HTML = function (label) {
|
||||
if (label === void 0) { label = ""; }
|
||||
label = (label === "") ? this._name : label;
|
||||
var multipleAttr = (this.isMultiple) ? " multiple" : "";
|
||||
var selectorsHTML = "<label for='freeDatas2HTML_" + this._datasViewElt.id + "'>" + label + " :</label><select name='freeDatas2HTML_" + this._datasViewElt.id + "' id='freeDatas2HTML_" + this._datasViewElt.id + "'" + multipleAttr + "><option value='0'>----</option>";
|
||||
for (var i = 0; i < this._values.length; i++)
|
||||
selectorsHTML += "<option value='" + (i + 1) + "'>" + this._values[i] + "</option>";
|
||||
selectorsHTML += "</select>";
|
||||
this._datasViewElt.eltDOM.innerHTML = selectorsHTML;
|
||||
var selectElement = document.getElementById("freeDatas2HTML_" + this._datasViewElt.id), mySelector = this;
|
||||
selectElement.addEventListener("change", function (e) {
|
||||
mySelector._selectedValues = [];
|
||||
if (mySelector.isMultiple) {
|
||||
for (var i = 0; i < selectElement.selectedOptions.length; i++) {
|
||||
var selectedValue = parseInt(selectElement.selectedOptions[i].value, 10);
|
||||
if (selectedValue === 0) {
|
||||
mySelector._selectedValues = [];
|
||||
break;
|
||||
}
|
||||
else
|
||||
mySelector._selectedValues.push(selectedValue - 1);
|
||||
}
|
||||
}
|
||||
return find;
|
||||
else {
|
||||
var selectedValue = parseInt(selectElement.value, 10);
|
||||
if (selectedValue === 0)
|
||||
mySelector._selectedValues = [];
|
||||
else
|
||||
mySelector._selectedValues[0] = selectedValue - 1;
|
||||
}
|
||||
mySelector._converter.refreshView();
|
||||
});
|
||||
};
|
||||
Selector.prototype.dataIsOk = function (data) {
|
||||
var checkIsValid = function (selector, data, checkedValue) {
|
||||
if (selector._separator === undefined) {
|
||||
if (data[selector._name].trim() !== checkedValue)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
var find_1 = false;
|
||||
var checkedValues = data[selector._name].split(selector._separator);
|
||||
for (var _i = 0, checkedValues_2 = checkedValues; _i < checkedValues_2.length; _i++) {
|
||||
var value = checkedValues_2[_i];
|
||||
if (value.trim() === checkedValue) {
|
||||
find_1 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return find_1;
|
||||
}
|
||||
};
|
||||
if (this._selectedValues.length === 0)
|
||||
return true;
|
||||
if (data[this._name] === undefined)
|
||||
return false;
|
||||
var find = false;
|
||||
for (var _i = 0, _a = this._selectedValues; _i < _a.length; _i++) {
|
||||
var value = _a[_i];
|
||||
if (this._values[value] === undefined)
|
||||
throw new Error(errors.selectorSelectedIndexNotFound);
|
||||
find = checkIsValid(this, data, this._values[value]);
|
||||
if (find)
|
||||
break;
|
||||
}
|
||||
return find;
|
||||
};
|
||||
return Selector;
|
||||
}());
|
||||
|
@ -5,7 +5,6 @@ module.exports =
|
||||
converterFieldNotFound: "Le champ n'existe pas dans les données ou les données n'ont pas encore été chargées.",
|
||||
converterNeedDatasElt: "Merci de fournir un id valide pour l'élément où afficher les données.",
|
||||
converterRefreshFail: "Le nom des champs et l'élement du DOM receveur sont nécessaires à l'affichage des données.",
|
||||
filterCheckIsOkFail: "Le test est lancé sur un filtre incorrectement initialisé ou sur un attribut absent de la donnée à tester.",
|
||||
filterNeedDatas: "Le création d'un filtre nécessite la présence des données à filtrer.",
|
||||
pagination2HTMLFail: "Toutes les donnée nécessaires à la création des sélecteurs de pagination n'ont pas été fournies.",
|
||||
paginationNeedByfaultValueBeInOptions: "La valeur de pagination par défaut doit faire partie des options proposées.",
|
||||
|
@ -4,7 +4,6 @@ module.exports =
|
||||
converterFieldNotFound : "Le champ n'existe pas dans les données ou les données n'ont pas encore été chargées.",
|
||||
converterNeedDatasElt: "Merci de fournir un id valide pour l'élément où afficher les données.",
|
||||
converterRefreshFail: "Le nom des champs et l'élement du DOM receveur sont nécessaires à l'affichage des données.",
|
||||
filterCheckIsOkFail: "Le test est lancé sur un filtre incorrectement initialisé ou sur un attribut absent de la donnée à tester.",
|
||||
filterNeedDatas: "Le création d'un filtre nécessite la présence des données à filtrer.",
|
||||
pagination2HTMLFail : "Toutes les donnée nécessaires à la création des sélecteurs de pagination n'ont pas été fournies.",
|
||||
paginationNeedByfaultValueBeInOptions: "La valeur de pagination par défaut doit faire partie des options proposées.",
|
||||
|
@ -85,7 +85,7 @@ export interface Selectors extends Filters
|
||||
{
|
||||
datasFieldNb: number;
|
||||
name: string;
|
||||
selectedValue: number|undefined;
|
||||
selectedValues: number[];
|
||||
separator: string|undefined;
|
||||
values: string[];
|
||||
}
|
||||
|
@ -4,9 +4,7 @@ module.exports =
|
||||
selector1HTML: '<label for="freeDatas2HTML_selector1">Famille :</label><select name="freeDatas2HTML_selector1" id="freeDatas2HTML_selector1"><option value="0">----</option><option value="1">Actinide</option><option value="2">Gaz noble</option><option value="3">gaz rare</option><option value="4">Halogène</option><option value="5">Indéfinie</option><option value="6">Lanthanide</option><option value="7">Métal alcalin</option><option value="8">Métal alcalino-terreux</option><option value="9">Métal de transition</option><option value="10">Métal pauvre</option><option value="11">Métalloïde</option><option value="12">Non-métal</option></select>',
|
||||
selector2HTML: '<label for="freeDatas2HTML_selector2">Abondance des éléments dans la croûte terrestre (μg/k) :</label><select name="freeDatas2HTML_selector2" id="freeDatas2HTML_selector2"><option value="0">----</option><option value="1">> 1 et < 100 000</option><option value="2">> 100000</option><option value="3">≤ 1</option><option value="4">Inexistant</option><option value="5">Traces</option></select>',
|
||||
selector2HTMLWithLabel: '<label for="freeDatas2HTML_selector2">Abondance des éléments :</label><select name="freeDatas2HTML_selector2" id="freeDatas2HTML_selector2"><option value="0">----</option><option value="1">> 1 et < 100 000</option><option value="2">> 100000</option><option value="3">≤ 1</option><option value="4">Inexistant</option><option value="5">Traces</option></select>',
|
||||
selector1HTMLWithSeparator: '<label for="freeDatas2HTML_selector1">Étiquettes :</label><select name="freeDatas2HTML_selector1" id="freeDatas2HTML_selector1"><option value="0">----</option><option value="1">Exemple0</option><option value="2">Exemple1</option><option value="3">Exemple2</option><option value="4">Exemple3</option><option value="5">Exemple4</option><option value="6">Exemple5</option><option value="7">Exemple6</option><option value="8">Exemple7</option><option value="9">Exemple8</option><option value="10">Exemple9</option><option value="11">Exemple10</option></select>',
|
||||
selectorHTMLWithTrim: '<label for="freeDatas2HTML_selector1">Famille :</label><select name="freeDatas2HTML_selector1" id="freeDatas2HTML_selector1"><option value="0">----</option><option value="1">Gaz noble</option><option value="2">Métal alcalin</option><option value="3">Métal alcalino-terreux</option><option value="4">Métalloïde</option><option value="5">Non-métal</option></select>',
|
||||
selector1HTMLWithFunction: '<label for="freeDatas2HTML_selector1">Abondance des éléments dans la croûte terrestre (μg/k) :</label><select name="freeDatas2HTML_selector1" id="freeDatas2HTML_selector1"><option value="0">----</option><option value="1">Inexistant</option><option value="2">Traces</option><option value="3">≤ 1</option><option value="4">> 1 et < 100 000</option><option value="5">> 100000</option></select>',
|
||||
selector2HTMLWithMultiple: '<label for="freeDatas2HTML_selector2">Abondance des éléments dans la croûte terrestre (μg/k) :</label><select name="freeDatas2HTML_selector2" id="freeDatas2HTML_selector2" multiple=""><option value="0">----</option><option value="1">> 1 et < 100 000</option><option value="2">> 100000</option><option value="3">≤ 1</option><option value="4">Inexistant</option><option value="5">Traces</option></select>',
|
||||
selectorHTMLWithFakeItem: '<label for="freeDatas2HTML_selector1">Famille :</label><select name="freeDatas2HTML_selector1" id="freeDatas2HTML_selector1"><option value="0">----</option><option value="1">Actinide</option><option value="2">Gaz noble</option><option value="3">gaz rare</option><option value="4">Halogène</option><option value="5">Indéfinie</option><option value="6">Lanthanide</option><option value="7">Métal alcalin</option><option value="8">Métal alcalino-terreux</option><option value="9">Métal de transition</option><option value="10">Métal pauvre</option><option value="11">Métalloïde</option><option value="12">Non-métal</option><option value="13">Je suis un gros fake !</option></select>',
|
||||
sortingColumn1HTML: '<a href="#freeDatas2HTMLSorting0" id="freeDatas2HTMLSorting0">Z (numéro atomique)</a>',
|
||||
sortingColumn2HTML: '<a href="#freeDatas2HTMLSorting2" id="freeDatas2HTMLSorting2">Symbole</a>',
|
||||
|
@ -6,7 +6,7 @@ describe("Test des sélecteurs de données", () =>
|
||||
{
|
||||
let converter: FreeDatas2HTML;
|
||||
let selector: Selector;
|
||||
let selectElement : HTMLInputElement;
|
||||
let selectElement : HTMLSelectElement;
|
||||
|
||||
beforeEach( async () =>
|
||||
{
|
||||
@ -22,9 +22,9 @@ describe("Test des sélecteurs de données", () =>
|
||||
document.body.removeChild(document.getElementById("fixture"));
|
||||
});
|
||||
|
||||
describe("Test des données de configuration.", () =>
|
||||
describe("Test des données d'initialisation.", () =>
|
||||
{
|
||||
it("Doit générer une erreur, si initialisé sans avoir au préalable charger des données.", async () =>
|
||||
it("Doit générer une erreur, si initialisé sans avoir au préalable chargé des données.", async () =>
|
||||
{
|
||||
// Convertisseur non lancé :
|
||||
converter=new FreeDatas2HTML("CSV");
|
||||
@ -43,18 +43,71 @@ describe("Test des sélecteurs de données", () =>
|
||||
expect(() => { return new Selector(converter, 1.1, { id:"selector1" }); }).toThrowError(errors.selectorFieldNotFound);
|
||||
});
|
||||
|
||||
it("Doit générer une erreur, si aucune donnée n'a été trouvée dans le champ du filtre.", async () =>
|
||||
{
|
||||
converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datasEmptyField.csv" });
|
||||
await converter.run();
|
||||
expect(() => { return new Selector(converter, 3, { id:"selector1" });}).toThrowError(errors.selectorFieldIsEmpty);
|
||||
});
|
||||
|
||||
it("Si un séparateur vide est fourni pour un filtre, il doit être ignoré.", () =>
|
||||
{
|
||||
selector=new Selector(converter, 0, { id:"selector1" }, "");
|
||||
expect(selector.separator).toBeUndefined();
|
||||
});
|
||||
|
||||
it("Si toutes les paramètres sont valides, ils doivent être acceptés.", () =>
|
||||
it("Si toutes les paramètres sont valides, ils doivent être acceptés et les informations correctement récupérées.", () =>
|
||||
{
|
||||
expect(() => { selector=new Selector(converter, 2, { id:"selector1" }, ","); return true; }).not.toThrowError();
|
||||
expect(selector.datasFieldNb).toEqual(2);
|
||||
expect(() => { selector=new Selector(converter, 3, { id:"selector1" }, ","); return true; }).not.toThrowError();
|
||||
expect(selector.datasFieldNb).toEqual(3);
|
||||
expect(selector.datasViewElt).toEqual({ id:"selector1", eltDOM:document.getElementById("selector1") });
|
||||
expect(selector.separator).toEqual(",");
|
||||
expect(selector.name).toEqual("Famille");
|
||||
expect(selector.values).toEqual(["Actinide","Gaz noble","gaz rare","Halogène","Indéfinie","Lanthanide","Métal alcalin","Métal alcalino-terreux","Métal de transition","Métal pauvre","Métalloïde","Non-métal"]);
|
||||
});
|
||||
|
||||
it("Si des valeurs vides sont présentes dans un champ utilisé pour un filtre, elles doivent être ignorées.", async () =>
|
||||
{
|
||||
converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1-emtyinfield.csv" });
|
||||
await converter.run();
|
||||
selector=new Selector(converter, 3, { id:"selector1" }, "");
|
||||
expect(selector.values).toEqual(["Actinide","Gaz noble","gaz rare","Halogène","Indéfinie","Lanthanide","Métal alcalin","Métal alcalino-terreux","Métal de transition","Métal pauvre","Métalloïde","Non-métal"]);
|
||||
});
|
||||
|
||||
it("Si des espaces entourent certaines valeurs pour ce champ, ils doivent être supprimés.", async () =>
|
||||
{
|
||||
converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datasNeedTrim.csv" });
|
||||
await converter.run();
|
||||
selector=new Selector(converter, 3, { id:"selector1" }, "");
|
||||
expect(selector.values).toEqual(["Gaz noble","Métal alcalin","Métal alcalino-terreux","Métalloïde","Non-métal"]);
|
||||
});
|
||||
|
||||
it("Si un séparateur est fourni, les valeurs distinctes extraites de ce champ doivent le prendre en compte.", async () =>
|
||||
{
|
||||
converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1+tagsfield.csv" });
|
||||
await converter.run();
|
||||
selector=new Selector(converter, 5, { id:"selector1" }, "|");
|
||||
selector.filter2HTML();
|
||||
expect(selector.values).toEqual(["Exemple0","Exemple1","Exemple2","Exemple3","Exemple4","Exemple5","Exemple6","Exemple7","Exemple8","Exemple9","Exemple10"]);
|
||||
});
|
||||
|
||||
it("Si une fonction spécifique est fournie pour le champ utilisé pour ce filtre, elle doit être prise en compte.", () =>
|
||||
{
|
||||
const mySort=(a: any, b: any, order: "asc"|"desc"="asc") =>
|
||||
{
|
||||
const values=[ "> 100000", "> 1 et < 100 000", "≤ 1", "Traces", "Inexistant"];
|
||||
if(order === "desc")
|
||||
values.reverse();
|
||||
if(values.indexOf(a) > values.indexOf(b))
|
||||
return -1;
|
||||
else if(values.indexOf(a) < values.indexOf(b))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
};
|
||||
converter.datasSortingFunctions=[{ datasFieldNb: 4, sort:mySort }];
|
||||
selector=new Selector(converter, 4, { id:"selector1" });
|
||||
expect(selector.values).toEqual(["Inexistant","Traces","≤ 1","> 1 et < 100 000","> 100000"]);
|
||||
});
|
||||
});
|
||||
|
||||
@ -81,56 +134,13 @@ describe("Test des sélecteurs de données", () =>
|
||||
expect(document.getElementById("selector2").innerHTML).toEqual(fixtures.selector2HTMLWithLabel);
|
||||
});
|
||||
|
||||
it("Si des valeurs vides sont présentes dans une champ utilisé pour un sélecteur, elles doivent être ignorées.", async () =>
|
||||
it("Doit prendre en compte la possibilité de sélectionner plusieurs valeurs.", () =>
|
||||
{
|
||||
selector.converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1-emtyinfield.csv" });
|
||||
await selector.converter.run();
|
||||
selector=new Selector(converter, 4, { id:"selector2" });
|
||||
selector.isMultiple=true;
|
||||
selector.filter2HTML();
|
||||
expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTML);
|
||||
});
|
||||
|
||||
it("Si des espaces entourent certaines valeurs pour ce champ, ils doivent être supprimés.", async () =>
|
||||
{
|
||||
selector.converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datasNeedTrim.csv" });
|
||||
await selector.converter.run();
|
||||
selector.filter2HTML();
|
||||
expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selectorHTMLWithTrim);
|
||||
});
|
||||
|
||||
it("Si un séparateur est fourni, les valeurs distinctes extraites de ce champ doivent le prendre en compte.", async () =>
|
||||
{
|
||||
converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datas1+tagsfield.csv" });
|
||||
await converter.run();
|
||||
selector=new Selector(converter, 5, { id:"selector1" }, "|");
|
||||
selector.filter2HTML();
|
||||
expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTMLWithSeparator);
|
||||
});
|
||||
|
||||
it("Si une fonction spécifique est fournie pour le champ utilisé pour ce filtre, elle doit être prise en compte.", () =>
|
||||
{
|
||||
const mySort=(a: any, b: any, order: "asc"|"desc"="asc") =>
|
||||
{
|
||||
const values=[ "> 100000", "> 1 et < 100 000", "≤ 1", "Traces", "Inexistant"];
|
||||
if(order === "desc")
|
||||
values.reverse();
|
||||
if(values.indexOf(a) > values.indexOf(b))
|
||||
return -1;
|
||||
else if(values.indexOf(a) < values.indexOf(b))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
};
|
||||
converter.datasSortingFunctions=[{ datasFieldNb: 4, sort:mySort }];
|
||||
selector=new Selector(converter, 4, { id:"selector1" });
|
||||
selector.filter2HTML();
|
||||
expect(document.getElementById("selector1").innerHTML).toEqual(fixtures.selector1HTMLWithFunction);
|
||||
});
|
||||
|
||||
it("Doit générer une erreur, si aucune donnée n'a été trouvée pour créer le <SELECT>.", async () =>
|
||||
{
|
||||
selector.converter.parser.setRemoteSource({ url:"http://localhost:9876/datas/datasEmptyField.csv" });
|
||||
await selector.converter.run();
|
||||
expect(() => { return selector.filter2HTML(); }).toThrowError(errors.selectorFieldIsEmpty);
|
||||
expect(document.getElementById("selector2").innerHTML).toEqual(fixtures.selector2HTMLWithMultiple);
|
||||
// le 'multiple' ajouté est transformé en 'multiple=""' par le navigateur.
|
||||
});
|
||||
});
|
||||
|
||||
@ -140,28 +150,57 @@ describe("Test des sélecteurs de données", () =>
|
||||
{
|
||||
selector=new Selector(converter, 3, { id:"selector1" }); // filtre sur le champ "famille"
|
||||
selector.filter2HTML();
|
||||
selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement;
|
||||
selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLSelectElement;
|
||||
});
|
||||
|
||||
it("La manipulation d'un sélecteur doit enregistrer la valeur sélectionnée et appeler la fonction actualisant l'affichage.", () =>
|
||||
{
|
||||
spyOn(converter, "refreshView");
|
||||
|
||||
selectElement.value="4";
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
expect(selector.selectedValue).toEqual(3);
|
||||
selectElement.value="4";
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
expect(selector.selectedValues[0]).toEqual(3);
|
||||
expect(converter.refreshView).toHaveBeenCalledTimes(1);
|
||||
|
||||
selectElement.value="0"; // 0 = annulation de ce filtre, puisqu'aucune valeur choisie
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
expect(selector.selectedValue).toBeUndefined();
|
||||
// Pas de choix multiples, donc seul le dernier choix est gardé :
|
||||
selectElement.value="2";
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
expect(selector.selectedValues[0]).toEqual(1);
|
||||
expect(converter.refreshView).toHaveBeenCalledTimes(2);
|
||||
|
||||
selectElement.value="0"; // 0 = annulation de ce filtre, puisqu'aucune valeur choisie
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
expect(selector.selectedValues.length).toEqual(0);
|
||||
expect(converter.refreshView).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
it("Doit générer une erreur si une donnée est testée sur un sélecteur non affiché dans la page.", () =>
|
||||
it("Si plusieurs choix sont autorisés, toutes les valeurs doivent être enregistrées, l'affichage s'actualisant à chaque fois.", () =>
|
||||
{
|
||||
spyOn(converter, "refreshView");
|
||||
|
||||
selector=new Selector(converter, 3, { id:"selector1" });
|
||||
expect(() => { selector.dataIsOk({ "nom" : "oui" }); }).toThrowError(errors.filterCheckIsOkFail);
|
||||
selector.isMultiple=true;
|
||||
selector.filter2HTML();
|
||||
selectElement=document.getElementById("freeDatas2HTML_"+selector.datasViewElt.id) as HTMLSelectElement;
|
||||
|
||||
selectElement.options[4].selected=true;
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
expect(selector.selectedValues[0]).toEqual(3);
|
||||
expect(converter.refreshView).toHaveBeenCalledTimes(1);
|
||||
|
||||
// Le choix d'une nouvelle option ne supprime pas les précédents choix
|
||||
// Mais les valeurs sélectionnées sont toujours parcourues dans l'ordre du SELECT
|
||||
selectElement.options[3].selected=true;
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
expect(selector.selectedValues[0]).toEqual(2);
|
||||
expect(selector.selectedValues[1]).toEqual(3);
|
||||
expect(converter.refreshView).toHaveBeenCalledTimes(2);
|
||||
|
||||
// Le choix 0 annule les précédents choix
|
||||
selectElement.options[0].selected=true;
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
expect(selector.selectedValues.length).toEqual(0);
|
||||
expect(converter.refreshView).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
it("Doit toujours retourner true si aucune des valeurs du filtre n'est sélectionnée.", () =>
|
||||
@ -170,42 +209,68 @@ describe("Test des sélecteurs de données", () =>
|
||||
expect(selector.dataIsOk({ "nom" : "oui" })).toBeTrue();
|
||||
// Même comportement après un retour :
|
||||
selectElement.value="2";
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
selectElement.value="0";
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
expect(selector.dataIsOk({ "nom" : "oui" })).toBeTrue();
|
||||
});
|
||||
|
||||
it("Doit générer une erreur si la valeur sélectionnée n'est pas trouvé dans la liste des valeurs connues.", () =>
|
||||
{
|
||||
selectElement.innerHTML=fixtures.selectorHTMLWithFakeItem;
|
||||
selectElement.value="13";
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
expect(() => { selector.dataIsOk({ "nom" : "oui" }); }).toThrowError(errors.selectorSelectedIndexNotFound);
|
||||
});
|
||||
|
||||
it("Doit retourner false, si la donnée testée ne possède pas le champ sur lequel les données sont filtrées.", () =>
|
||||
{
|
||||
selectElement.value="2";
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
expect(selector.dataIsOk({ "nom" : "rémi sans famille" })).toBeFalse();
|
||||
});
|
||||
|
||||
it("Doit générer une erreur si la valeur sélectionnée n'est pas trouvée dans la liste des valeurs connues.", () =>
|
||||
{
|
||||
selectElement.innerHTML=fixtures.selectorHTMLWithFakeItem;
|
||||
selectElement.value="13";
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
expect(() => { selector.dataIsOk({ "Famille" : "nombreuse" }); }).toThrowError(errors.selectorSelectedIndexNotFound);
|
||||
});
|
||||
|
||||
it("Doit retourner false, si une donnée testée ne correspond pas à la valeur sélectionnée pour le filtre.", async () =>
|
||||
{
|
||||
selectElement.value="4"; // = Halogène
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
expect(selector.dataIsOk({ "Famille": "Hallo Eugène !" })).toBeFalse();
|
||||
});
|
||||
|
||||
it("Doit retourner true, si une donnée testée correspond à la valeur sélectionnée pour ce filtre.", () =>
|
||||
{
|
||||
selectElement.value="4";
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
expect(selector.dataIsOk({ "Famille": "Halogène" })).toBeTrue();
|
||||
// Y compris si entouré d'espaces :
|
||||
expect(selector.dataIsOk({ "Famille": " Halogène " })).toBeTrue();
|
||||
});
|
||||
|
||||
it("Doit retourner false, si une donnée testée ne correspond à aucune des valeurs sélectionnées dans un filtre multichoix.", async () =>
|
||||
{
|
||||
selector=new Selector(converter, 3, { id:"selector1" });
|
||||
selector.isMultiple=true;
|
||||
selector.filter2HTML();
|
||||
selectElement=document.getElementById("freeDatas2HTML_"+selector.datasViewElt.id) as HTMLSelectElement;
|
||||
selectElement.options[3].selected=true;// sélection = gaz rare
|
||||
selectElement.options[4].selected=true; // sélection = Halogène
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
expect(selector.dataIsOk({ "Famille": "Hallo Eugène !" })).toBeFalse();
|
||||
});
|
||||
|
||||
it("Doit retourner true, si une donnée testée correspond à au moins une des valeurs sélectionnées dans un filtre multichoix.", () =>
|
||||
{
|
||||
selector=new Selector(converter, 3, { id:"selector1" });
|
||||
selector.isMultiple=true;
|
||||
selector.filter2HTML();
|
||||
selectElement=document.getElementById("freeDatas2HTML_"+selector.datasViewElt.id) as HTMLSelectElement;
|
||||
selectElement.options[3].selected=true;// sélection = gaz rare
|
||||
selectElement.options[4].selected=true; // sélection = Halogène
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
expect(selector.dataIsOk({ "Famille": "Halogène" })).toBeTrue();
|
||||
// Y compris si entouré d'espaces :
|
||||
expect(selector.dataIsOk({ "Famille": " gaz rare " })).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Manipulation des sélecteurs avec séparateur.", () =>
|
||||
@ -216,27 +281,27 @@ describe("Test des sélecteurs de données", () =>
|
||||
await converter.run();
|
||||
selector=new Selector(converter, 5, { id:"selector1" }, "|"); // filtre sur le champ "Étiquettes"
|
||||
selector.filter2HTML();
|
||||
selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLInputElement;
|
||||
selectElement=document.getElementById("freeDatas2HTML_selector1") as HTMLSelectElement;;
|
||||
});
|
||||
|
||||
it("Doit retourner false, si la donnée testée ne possède pas le champ sur lequel les données sont filtrées.", () =>
|
||||
{
|
||||
selectElement.value="2";
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
expect(selector.dataIsOk({ "nom" : "oui" })).toBeFalse();
|
||||
});
|
||||
|
||||
it("Doit retourner false, si une donnée testée ne correspond pas à la valeur sélectionnée pour le filtre.", () =>
|
||||
{
|
||||
selectElement.value="4"; // = Exemple3
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
expect(selector.dataIsOk({ "Étiquettes": "Mauvais exemple" })).toBeFalse();
|
||||
});
|
||||
|
||||
it("Doit retourner true, si une donnée testée correspond pas à la valeur sélectionnée pour ce filtre.", () =>
|
||||
{
|
||||
selectElement.value="4";
|
||||
selectElement.dispatchEvent(new Event('change'));
|
||||
selectElement.dispatchEvent(new Event("change"));
|
||||
expect(selector.dataIsOk({ "Étiquettes": "Exemple3" })).toBeTrue();
|
||||
// Même quand elle n'est pas seule :
|
||||
expect(selector.dataIsOk({ "Étiquettes": "Exemple3|Exemple1|Exemple9" })).toBeTrue();
|
||||
|
Loading…
Reference in New Issue
Block a user