Si tout se passe bien, ce texte sera remplacé par un tableau de données extraites du fichier csv.
diff --git a/src/errors.js b/src/errors.js
index 50d8fb8..41d51c3 100644
--- a/src/errors.js
+++ b/src/errors.js
@@ -6,4 +6,5 @@ module.exports =
needNaturalNumber: "Merci de fournir un nombre entier supérieur ou égal à zéro pour désigner chaque colonne.",
needUrl: "Merci de fournir l'url du fichier CSV à parser.",
parserFail: "La lecture des données du fichier a échoué.",
+ selectorFieldNotFound: "Au moins une des colonnes devant servir à filtrer les données n'existe pas dans le fichier.",
};
\ No newline at end of file
diff --git a/src/firstExample.ts b/src/firstExample.ts
index 20a6892..c6f3928 100644
--- a/src/firstExample.ts
+++ b/src/firstExample.ts
@@ -6,6 +6,7 @@ const initialise = async () =>
{
let converter=new freeCSV2HTML();
converter.datasViewElt={ id:"datas" };
+ converter.datasSelectors=[{ colCSV:3, id:"filtre1"},{ colCSV:4, id:"filtre2"}];
converter.datasSourceUrl="http://localhost:8080/datas/elements-chimiques.csv";
await converter.run();
}
@@ -14,77 +15,4 @@ const initialise = async () =>
console.error(e);
}
}
-initialise();
-
-
- /*
- public async setDatasUrl(url: string) : Promise // pas de setter classique à cause asynchrone
- {
- const converter=this; // nécessaire pour éviter confusion avec this à l'intérieur de XMLHttpRequest
- await fetch(url).then(function(response)
- {
- if(response.ok)
- {
- converter._datasUrl=url;
- }
- })
- if(converter._datasUrl!=="")
- return true;
- else
- return false;
- }
-
- /*
- let req = new XMLHttpRequest();
- req.open("GET", url);
- req.addEventListener("load", function ()
- {
- if (req.status >= 200 && req.status < 400)
- {
- converter._datasUrl=url;
- return true;
- }
- else
- {
- console.error("Fichier non trouvé");
- return false;
- }
- });
- }*/
-
-
-/* Exemple d'appelle complet à papaparse :
- Papa.parse(url, {
- delimiter :"",
- newline: "",
- quoteChar:'"',// à proposer en option
- escapeChar:"",// idem
- header:true,
- transformHeader:"",
- dynamicTyping:false,
- preview:0,
- encoding:"",
- worker:true,
- comments:"",
- step:"",// prévoir en option pour très gros fichiers ?
- complete: function(results :any)
- {
- console.log(results.meta);
- console.log(results.data[35]);
- console.log(results.errors);
- },
- error:function(error :any)
- {
- console.log(error);
- },
- download: true,// nécessaire pour un accès via "http..."
- downloadRequestBody:false,
- skipEmptyLines: true,
- chunk:"",
- fastMode:"",
- beforeFirstChunk:"",
- withCredentials:false,
- transform: "", // à revoir
- delimitersToGuess:""
- });
- * // https://www.papaparse.com/docs#config*/
\ No newline at end of file
+initialise();
\ No newline at end of file
diff --git a/src/freeCSV2HTML.ts b/src/freeCSV2HTML.ts
index aa9216b..7400bdf 100644
--- a/src/freeCSV2HTML.ts
+++ b/src/freeCSV2HTML.ts
@@ -11,6 +11,8 @@ interface domElement
interface selectors extends domElement
{
colCSV: number;
+ name?: string;
+ values? : string[];
}
export class freeCSV2HTML
@@ -20,7 +22,6 @@ export class freeCSV2HTML
private _datasSourceUrl: string = "";
private _datasSelectors: selectors[] = [];
- // Données reçues ou générées suite parsage du fichier CSV :
public parseMeta: papaParseMeta|undefined = undefined;
public parseDatas: papaParseDatas[] = [];
public parseErrors: papaParseErrors[] = [];
@@ -38,7 +39,7 @@ export class freeCSV2HTML
}
}
- // Pas plus de tests car nombreux protocoles possibles pour l'url du fichier, pas uniquement http(s). À revoir.
+ // Pas plus de tests + poussés, car nombreux protocoles possibles pour l'url du fichier. À revoir.
set datasSourceUrl(url: string)
{
if(url.trim().length === 0)
@@ -47,35 +48,34 @@ export class freeCSV2HTML
this._datasSourceUrl=url.trim();
}
- // La validité du numéro de colonne ne peut être vérifée qu'après le parsage.
- set datasSelectors(selectors: selectors[])
+ set datasSelectors(selectionElts: selectors[])
{
let checkContainerExist: HTMLElement|null;
- for(let i = 0; i < selectors.length; i++)
+ for(let i = 0; i < selectionElts.length; i++)
{
- checkContainerExist=document.getElementById(selectors[i].id);
+ checkContainerExist=document.getElementById(selectionElts[i].id);
if(checkContainerExist === null)
- throw new Error(errors.elementNotFound+selectors[i].id);
- else if(Number.isInteger(selectors[i].colCSV) === false || selectors[i].colCSV < 0)
- throw new Error(errors.needNaturalNumber);
+ throw new Error(errors.elementNotFound+selectionElts[i].id);
+ else if(Number.isInteger( selectionElts[i].colCSV) === false || selectionElts[i].colCSV < 0)
+ throw new Error(errors.needNaturalNumber); // La validité réelle du numéro de colonne ne peut être vérifée qu'après le parsage.
else
- selectors[i].eltDOM=checkContainerExist;
+ selectionElts[i].eltDOM=checkContainerExist;
}
- this._datasSelectors=selectors;
+ this._datasSelectors= selectionElts;
}
public async parse(): Promise
{
- const converter=this; // nécessaire pour éviter confusion avec le "this" de la promise
+ const converter=this;
return new Promise((resolve,reject) =>
{
- if(this._datasSourceUrl !== "" )
+ if(converter._datasSourceUrl !== "" )
{
- Papa.parse(this._datasSourceUrl,
+ Papa.parse(converter._datasSourceUrl,
{
- quoteChar:'"', // à proposer en option ?
- header:true,
- complete: function(results :any)
+ quoteChar: '"',
+ header: true,
+ complete: function(results :any)
{
converter.parseMeta=results.meta;
converter.parseErrors=results.errors; // prévoir option bloquant la suite à la moindre erreur trouvée ?
@@ -87,11 +87,11 @@ export class freeCSV2HTML
reject(new Error(errors.parserFail));
},
download: true,
- skipEmptyLines: true, // à proposer en option ?
+ skipEmptyLines: true,
});
}
else
- resolve(new Error(errors.needUrl));
+ reject(new Error(errors.needUrl));
});
}
@@ -99,37 +99,106 @@ export class freeCSV2HTML
{
if (this._datasViewElt.eltDOM === undefined)
throw new Error(errors.needDatasElt);
-
- if(this._datasSourceUrl === "" )
+ else if(this._datasSourceUrl === "" )
throw new Error(errors.needUrl);
- if(await this.parse() === true)
+ await this.parse();
+
+ if(this.parseDatas.length === 0 || this.parseMeta === undefined || this.parseMeta.fields === undefined)
{
- if(this.parseDatas.length === 0 || this.parseMeta === undefined || this.parseMeta.fields === undefined)
- {
- this._datasViewElt.eltDOM.innerHTML=errors.datasNotFound;
- return false;
- }
- else
- {
- this.datasHTML="
";
- for (let i in this.parseMeta.fields)
- this.datasHTML+="
"+this.parseMeta.fields[i]+"
";
- this.datasHTML+="";
- for (let row in this.parseDatas)
- {
- this.datasHTML+="
";
- for(let field in this.parseDatas[row])
- {
- if( this.parseMeta.fields.indexOf(field) !== -1) // si les erreurs papaParse sont acceptées, il peut y avoir des données en trop : "__parsed_extra"
- this.datasHTML+="
";
+ for (let i in this.parseMeta.fields)
+ this.datasHTML+="
"+this.parseMeta.fields[i]+"
";
+ this.datasHTML+="";
+ for (let row in this.parseDatas)
+ {
+ this.datasHTML+="
";
+ for(let field in this.parseDatas[row])
+ {
+ if( this.parseMeta.fields.indexOf(field) !== -1) // si les erreurs papaParse sont acceptées, il peut y avoir des données en trop : "__parsed_extra"
+ this.datasHTML+="
"+this.parseDatas[row][field]+"
";
+ }
+ this.datasHTML+="
";
+ }
+ this.datasHTML+="
";
+ this._datasViewElt.eltDOM.innerHTML=this.datasHTML;
+
+ // Si demandé, création des listes permettant de filter les données
+ if(this._datasSelectors.length > 0)
+ {
+ // Les colonnes devant servir de filtre existent-elles dans le fichier ?
+ let selectorsHTML : string [] = [];
+ for(let i in this._datasSelectors)
+ {
+ if(this._datasSelectors[i].colCSV > (this.parseMeta.fields.length-1))
+ throw new Error(errors.selectorFieldNotFound);
+ else
+ {
+ let values=[], colName=this.parseMeta.fields[this._datasSelectors[i].colCSV];
+ for (let row in this.parseDatas)
+ {
+ if(values.indexOf(this.parseDatas[row][colName]) === -1)
+ values.push(this.parseDatas[row][colName]);
+ }
+ if(values.length > 0)
+ {
+ values.sort(); // revoir le problème des chiffres, dates, etc. https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
+ this._datasSelectors[i].name = colName;
+ this._datasSelectors[i].values=values;
+ selectorsHTML[i]="";
+ this._datasSelectors[i].eltDOM!.innerHTML=selectorsHTML[i];// je force avec "!", car l'existence de eltDOM a été testée par le setter.
+ }
+
+ // suite : https://stackoverflow.com/questions/19329978/change-selects-option-and-trigger-events-with-javascript
+ }
+ }
+ }
+ return true;
+ }
+
}
-}
\ No newline at end of file
+}
+/* Exemple d'appelle complet à papaparse :
+ Papa.parse(url, {
+ delimiter :"",
+ newline: "",
+ quoteChar:'"',// à proposer en option
+ escapeChar:"",// idem
+ header:true,
+ transformHeader:"",
+ dynamicTyping:false,
+ preview:0,
+ encoding:"",
+ worker:true,
+ comments:"",
+ step:"",// prévoir en option pour très gros fichiers ?
+ complete: function(results :any)
+ {
+ console.log(results.meta);
+ console.log(results.data[35]);
+ console.log(results.errors);
+ },
+ error:function(error :any)
+ {
+ console.log(error);
+ },
+ download: true,// nécessaire pour un accès via "http..."
+ downloadRequestBody:false,
+ skipEmptyLines: true,
+ chunk:"",
+ fastMode:"",
+ beforeFirstChunk:"",
+ withCredentials:false,
+ transform: "", // à revoir
+ delimitersToGuess:""
+ });
+ * // https://www.papaparse.com/docs#config*/
\ No newline at end of file
diff --git a/tests/fixtures.js b/tests/fixtures.js
index 4c11cd7..be7ab3a 100644
--- a/tests/fixtures.js
+++ b/tests/fixtures.js
@@ -2,4 +2,8 @@ module.exports =
{
datasViewEltHTML: '
',
datasHTML : '
Z (numéro atomique)
Élément
Symbole
Famille
Abondance des éléments dans la croûte terrestre (μg/k)
1
Hydrogène
H
Non-métal
> 100000
2
Hélium
He
Gaz noble
> 1 et < 100 000
3
Lithium
Li
Métal alcalin
> 1 et < 100 000
4
Béryllium
Be
Métal alcalino-terreux
> 1 et < 100 000
5
Bore
B
Métalloïde
> 1 et < 100 000
6
Carbone
C
Non-métal
> 100000
7
Azote
N
Non-métal
> 1 et < 100 000
8
Oxygène
O
Non-métal
> 100000
9
Fluor
F
Halogène
> 100000
10
Néon
Ne
Gaz noble
> 1 et < 100 000
11
Sodium
Na
Métal alcalin
> 100000
12
Magnésium
Mg
Métal alcalino-terreux
> 100000
13
Aluminium
Al
Métal pauvre
> 100000
14
Silicium
Si
Métalloïde
> 100000
15
Phosphore
P
Non-métal
> 100000
16
Soufre
S
Non-métal
> 100000
17
Chlore
Cl
Halogène
> 100000
18
Argon
Ar
Gaz noble
> 1 et < 100 000
19
Potassium
K
Métal alcalin
> 100000
20
Calcium
Ca
Métal alcalino-terreux
> 100000
21
Scandium
Sc
Métal de transition
> 1 et < 100 000
22
Titane
Ti
Métal de transition
> 100000
23
Vanadium
V
Métal de transition
> 100000
24
Chrome
Cr
Métal de transition
> 100000
25
Manganèse
Mn
Métal de transition
> 100000
26
Fer
Fe
Métal de transition
> 100000
27
Cobalt
Co
Métal de transition
> 1 et < 100 000
28
Nickel
Ni
Métal de transition
> 1 et < 100 000
29
Cuivre
Cu
Métal de transition
> 1 et < 100 000
30
Zinc
Zn
Métal pauvre
> 1 et < 100 000
31
Gallium
Ga
Métal pauvre
> 1 et < 100 000
32
Germanium
Ge
Métalloïde
> 1 et < 100 000
33
Arsenic
As
Métalloïde
> 1 et < 100 000
34
Sélénium
Se
Non-métal
> 1 et < 100 000
35
Brome
Br
Halogène
> 1 et < 100 000
36
Krypton
Kr
gaz rare
≤ 1
37
Rubidium
Rb
Métal alcalin
> 1 et < 100 000
38
Strontium
Sr
Métal alcalino-terreux
> 100000
39
Yttrium
Y
Métal de transition
> 1 et < 100 000
40
Zirconium
Zr
Métal de transition
> 100000
41
Niobium
Nb
Métal de transition
> 1 et < 100 000
42
Molybdène
Mo
Métal de transition
> 1 et < 100 000
43
Technétium
Tc
Métal de transition
Traces
44
Ruthénium
Ru
Métal de transition
≤ 1
45
Rhodium
Rh
Métal de transition
≤ 1
46
Palladium
Pd
Métal de transition
> 1 et < 100 000
47
Argent
Ag
Métal de transition
> 1 et < 100 000
48
Cadmium
Cd
Métal pauvre
> 1 et < 100 000
49
Indium
In
Métal pauvre
> 1 et < 100 000
50
Étain
Sn
Métal pauvre
> 1 et < 100 000
51
Antimoine
Sb
Métalloïde
> 1 et < 100 000
52
Tellure
Te
Métalloïde
≤ 1
53
Iode
I
Halogène
> 1 et < 100 000
54
Xénon
Xe
gaz rare
≤ 1
55
Césium
Cs
Métal alcalin
> 1 et < 100 000
56
Baryum
Ba
Métal alcalino-terreux
> 100000
57
Lanthane
La
Lanthanide
> 1 et < 100 000
58
Cérium
Ce
Lanthanide
> 1 et < 100 000
59
Praséodyme
Pr
Lanthanide
> 1 et < 100 000
60
Néodyme
Nd
Lanthanide
> 1 et < 100 000
61
Prométhium
Pm
Lanthanide
Traces
62
Samarium
Sm
Lanthanide
> 1 et < 100 000
63
Europium
Eu
Lanthanide
> 1 et < 100 000
64
Gadolinium
Gd
Lanthanide
> 1 et < 100 000
65
Terbium
Tb
Lanthanide
> 1 et < 100 000
66
Dysprosium
Dy
Lanthanide
> 1 et < 100 000
67
Holmium
Ho
Lanthanide
> 1 et < 100 000
68
Erbium
Er
Lanthanide
> 1 et < 100 000
69
Thulium
Tm
Lanthanide
> 1 et < 100 000
70
Ytterbium
Yb
Lanthanide
> 1 et < 100 000
71
Lutécium
Lu
Lanthanide
> 1 et < 100 000
72
Hafnium
Hf
Métal de transition
> 1 et < 100 000
73
Tantale
Ta
Métal de transition
> 1 et < 100 000
74
Tungstène
W
Métal de transition
> 1 et < 100 000
75
Rhénium
Re
Métal de transition
≤ 1
76
Osmium
Os
Métal de transition
> 1 et < 100 000
77
Iridium
Ir
Métal de transition
≤ 1
78
Platine
Pt
Métal de transition
> 1 et < 100 000
79
Or
Au
Métal de transition
> 1 et < 100 000
80
Mercure
Hg
Métal pauvre
> 1 et < 100 000
81
Thallium
Tl
Métal pauvre
> 1 et < 100 000
82
Plomb
Pb
Métal pauvre
> 1 et < 100 000
83
Bismuth
Bi
Métal pauvre
> 1 et < 100 000
84
Polonium
Po
Métal pauvre
≤ 1
85
Astate
At
Métalloïde
Traces
86
Radon
Rn
Gaz noble
≤ 1
87
Francium
Fr
Métal alcalin
Traces
88
Radium
Ra
Métal alcalino-terreux
≤ 1
89
Actinium
Ac
Actinide
≤ 1
90
Thorium
Th
Actinide
> 1 et < 100 000
91
Protactinium
Pa
Actinide
≤ 1
92
Uranium
U
Actinide
> 1 et < 100 000
93
Neptunium
Np
Actinide
Traces
94
Plutonium
Pu
Actinide
Traces
95
Américium
Am
Actinide
Inexistant
96
Curium
Cm
Actinide
Inexistant
97
Berkélium
Bk
Actinide
Inexistant
98
Californium
Cf
Actinide
Inexistant
99
Einsteinium
Es
Actinide
Inexistant
100
Fermium
Fm
Actinide
Inexistant
101
Mendélévium
Md
Actinide
Inexistant
102
Nobélium
No
Actinide
Inexistant
103
Lawrencium
Lr
Actinide
Inexistant
104
Rutherfordium
Rf
Métal de transition
Inexistant
105
Dubnium
Db
Métal de transition
Inexistant
106
Seaborgium
Sg
Métal de transition
Inexistant
107
Bohrium
Bh
Métal de transition
Inexistant
108
Hassium
Hs
Métal de transition
Inexistant
109
Meitnérium
Mt
Indéfinie
Inexistant
110
Darmstadtium
Ds
Indéfinie
Inexistant
111
Roentgenium
Rg
Indéfinie
Inexistant
112
Copernicium
Cn
Métal de transition
Inexistant
113
Nihonium
Nh
Indéfinie
Inexistant
114
Flérovium
Fl
Indéfinie
Inexistant
115
Moscovium
Mc
Indéfinie
Inexistant
116
Livermorium
Lv
Indéfinie
Inexistant
117
Tennesse
Ts
Indéfinie
Inexistant
118
Oganesson
Og
Indéfinie
Inexistant
',
-}
\ No newline at end of file
+ selector1HTML: '',
+ selector2HTML: '',
+ datasHTMLForSelect1: '
',
+ datasHTMLForSelect2:'
',
+}
\ No newline at end of file
diff --git a/tests/freeCSV2HTMLSpec.ts b/tests/freeCSV2HTMLSpec.ts
index 00fe89b..3737123 100644
--- a/tests/freeCSV2HTMLSpec.ts
+++ b/tests/freeCSV2HTMLSpec.ts
@@ -112,5 +112,63 @@ describe("freeCSV2HTML", () =>
let txtDatasViewsElt=document.getElementById("datas").innerHTML;
expect(txtDatasViewsElt).toEqual(fixtures.datasHTML);
});
+
+ it("Doit générer une erreur si au moins un des numéros de colonne des sélecteurs ne correspond pas à une des colonne du fichier.", async () =>
+ {
+ converter.datasViewElt={ id:"datas" };
+ converter.datasSourceUrl="http://localhost:9876/datas/elements-chimiques.csv";
+ converter.datasSelectors=[{ colCSV:0, id:"selector1"},{ colCSV:5, id:"selector2"}];
+ await expectAsync(converter.run()).toBeRejectedWith(new Error(errors.selectorFieldNotFound));
+ });
+
+ it("Ne doit pas générer d'erreur si tous les numéros de colonne des sélecteurs correspondent pas à une des colonne du fichier.", async () =>
+ {
+ converter.datasViewElt={ id:"datas" };
+ converter.datasSourceUrl="http://localhost:9876/datas/elements-chimiques.csv";
+ converter.datasSelectors=[{ colCSV:3, id:"selector1"},{ colCSV:4, id:"selector2"}];
+ await expectAsync(converter.run()).not.toBeRejected();
+ });
+
+ it("Pour chaque sélecteur demandé doit générer un élement