Relecture du code

This commit is contained in:
Fabrice PENHOËT 2021-08-12 16:05:12 +02:00
parent cf4802c9d2
commit f5a4c7ba72

View File

@ -17,7 +17,6 @@ interface selectors extends domElement
export class freeCSV2HTML export class freeCSV2HTML
{ {
// Configuration :
private _datasViewElt: domElement = { id:"", eltDOM:undefined }; private _datasViewElt: domElement = { id:"", eltDOM:undefined };
private _datasSourceUrl: string = ""; private _datasSourceUrl: string = "";
private _datasSelectors: selectors[] = []; private _datasSelectors: selectors[] = [];
@ -25,7 +24,7 @@ export class freeCSV2HTML
public parseMeta: papaParseMeta|undefined = undefined; public parseMeta: papaParseMeta|undefined = undefined;
public parseDatas: papaParseDatas[] = []; public parseDatas: papaParseDatas[] = [];
public parseErrors: papaParseErrors[] = []; public parseErrors: papaParseErrors[] = [];
private datasHTML: string = ""; public datasHTML: string = "";
set datasViewElt(elt: domElement) set datasViewElt(elt: domElement)
{ {
@ -39,7 +38,6 @@ export class freeCSV2HTML
} }
} }
// Pas plus de tests + poussés, car nombreux protocoles possibles pour l'url du fichier. À revoir.
set datasSourceUrl(url: string) set datasSourceUrl(url: string)
{ {
if(url.trim().length === 0) if(url.trim().length === 0)
@ -57,11 +55,11 @@ export class freeCSV2HTML
if(checkContainerExist === null) if(checkContainerExist === null)
throw new Error(errors.elementNotFound+selectionElts[i].id); throw new Error(errors.elementNotFound+selectionElts[i].id);
else if(Number.isInteger( selectionElts[i].colCSV) === false || selectionElts[i].colCSV < 0) 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. throw new Error(errors.needNaturalNumber);
else else
selectionElts[i].eltDOM=checkContainerExist; selectionElts[i].eltDOM=checkContainerExist;
} }
this._datasSelectors= selectionElts; this._datasSelectors=selectionElts;
} }
public async parse(): Promise<any> public async parse(): Promise<any>
@ -78,7 +76,7 @@ export class freeCSV2HTML
complete: function(results :any) complete: function(results :any)
{ {
converter.parseMeta=results.meta; converter.parseMeta=results.meta;
converter.parseErrors=results.errors; // prévoir option bloquant la suite à la moindre erreur trouvée ? converter.parseErrors=results.errors;
converter.parseDatas=results.data; converter.parseDatas=results.data;
resolve(true); resolve(true);
}, },
@ -99,19 +97,18 @@ export class freeCSV2HTML
{ {
if (this._datasViewElt.eltDOM === undefined) if (this._datasViewElt.eltDOM === undefined)
throw new Error(errors.needDatasElt); throw new Error(errors.needDatasElt);
else if(this._datasSourceUrl === "" ) if(this._datasSourceUrl === "" )
throw new Error(errors.needUrl); throw new Error(errors.needUrl);
await this.parse(); await this.parse();
if(this.parseDatas.length === 0 || this.parseMeta === undefined || this.parseMeta.fields === undefined) if(this.parseDatas.length === 0 || this.parseMeta!.fields === undefined) // je force avec "!", car l'existence de parseMeta certaine après parse().
{ {
this._datasViewElt.eltDOM.innerHTML=errors.datasNotFound; this._datasViewElt.eltDOM.innerHTML=errors.datasNotFound;
return false; return false;
} }
else else
{ {
let converter=this; // pour les situations ambigues let converter=this;
// Affichage initial des données du fichier // Affichage initial des données du fichier
this.datasHTML=this.createDatasHTML(this.parseMeta.fields, this.parseDatas); this.datasHTML=this.createDatasHTML(this.parseMeta.fields, this.parseDatas);
this._datasViewElt.eltDOM.innerHTML=this.datasHTML; this._datasViewElt.eltDOM.innerHTML=this.datasHTML;
@ -130,20 +127,22 @@ export class freeCSV2HTML
let values=[], colName=this.parseMeta.fields[this._datasSelectors[i].colCSV]; let values=[], colName=this.parseMeta.fields[this._datasSelectors[i].colCSV];
for (let row in this.parseDatas) for (let row in this.parseDatas)
{ {
if(values.indexOf(this.parseDatas[row][colName]) === -1) if(values.indexOf(this.parseDatas[row][colName].trim()) === -1)
values.push(this.parseDatas[row][colName]); values.push(this.parseDatas[row][colName].trim());
// Des espaces gauche pourraient fausser le classement alphabétique.
// Donc réutiliser le trim() lorsque l'on filtre l'affichage des données.
} }
if(values.length > 0) 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 values.sort();
this._datasSelectors[i].name = colName; this._datasSelectors[i].name = colName;
this._datasSelectors[i].values=values; this._datasSelectors[i].values=values;
selectorsHTML[i]="<label for='CSVDatasSelector"+i+"'>"+colName+" : </label><select name='CSVDatasSelector"+i+"' id='CSVDatasSelector"+i+"'><option value='0'>----</option>"; selectorsHTML[i]="<label for='CSVDatasSelector"+i+"'>"+colName+" : </label><select name='CSVDatasSelector"+i+"' id='CSVDatasSelector"+i+"'><option value='0'>----</option>";
for(let j in values) for(let j in values)
selectorsHTML[i]+="<option value='"+(Number(j)+1)+"'>"+values[j]+"</option>"; selectorsHTML[i]+="<option value='"+(Number(j)+1)+"'>"+values[j]+"</option>";
selectorsHTML[i]+="</select>"; selectorsHTML[i]+="</select>";
this._datasSelectors[i].eltDOM!.innerHTML=selectorsHTML[i];// je force avec "!", car l'existence de eltDOM a été testée par le setter. this._datasSelectors[i].eltDOM!.innerHTML=selectorsHTML[i];
// On rechargera les données lors de chaque choix de l'utilisateur // On recharge l'affichage des données lors de chaque choix de l'utilisateur :
let selectElement = document.getElementById("CSVDatasSelector"+i) as HTMLInputElement; let selectElement = document.getElementById("CSVDatasSelector"+i) as HTMLInputElement;
selectElement.addEventListener('change', function(e) selectElement.addEventListener('change', function(e)
{ {
@ -160,37 +159,40 @@ export class freeCSV2HTML
private createDatasHTML(fields: string[], datas: any[]) : string private createDatasHTML(fields: string[], datas: any[]) : string
{ {
// Je vérifie si des valeurs ont été sélectionnées pour filter les données // Je vérifie si des valeurs ont été sélectionnées pour filter les données.
let checkContainerExist: HTMLSelectElement|null, filters: any[] = []; let checkSelectorExist: HTMLSelectElement|null, filters: any[] = [];
for(let i in this._datasSelectors) for(let i in this._datasSelectors)
{ {
checkContainerExist=document.querySelector("#"+ this._datasSelectors[i].id+" select"); // Attention : je peux avoir des _datasSelectors fournis, mais pas de liste dans le DOM si aucune donnée ou autre problème.
if(checkContainerExist != null && checkContainerExist.value != "0") checkSelectorExist=document.querySelector("#"+ this._datasSelectors[i].id+" select");
filters.push({ field: this._datasSelectors[i].name, value: this._datasSelectors[i].values![checkContainerExist.selectedIndex-1] }); if(checkSelectorExist != null && checkSelectorExist.value != "0")
}// ! si on récupère innerHTML du select, certains caractères peuvent être modifiés ! filters.push({ field: this._datasSelectors[i].name, value: this._datasSelectors[i].values![checkSelectorExist.selectedIndex-1] });
// Attention : si on récupère innerHTML du select, certains caractères peuvent être modifiés !
}
// Création du tableau de données :
let datasHTML="<table><thead>"; let datasHTML="<table><thead>";
for (let i in fields) for (let i in fields)
datasHTML+="<th>"+fields[i]+"</th>"; datasHTML+="<th>"+fields[i]+"</th>";
datasHTML+="</thead><tbody>"; datasHTML+="</thead><tbody>";
for (let row in datas) for (let row in datas)
{ {
let view=true; let visible=true;
if(filters.length !== 0) if(filters.length !== 0)
{ {
for(let i in filters) for(let i in filters)
{ {
if(datas[row][filters[i].field] != filters[i].value) if(datas[row][filters[i].field].trim() != filters[i].value)
view=false; visible=false;
} }
} }
if(view) if(visible)
{ {
datasHTML+="<tr>"; datasHTML+="<tr>";
for(let field in datas[row]) for(let field in datas[row])
{ {
if(fields.indexOf(field) !== -1) // si les erreurs papaParse sont acceptées, il peut y avoir des données en trop : "__parsed_extra" // Attention : si les erreurs papaParse ne sont pas bloquantes, il peut y avoir des données en trop, avec comme nom de colonne : "__parsed_extra"
datasHTML+="<td>"+datas[row][field]+"</td>"; if(fields.indexOf(field) !== -1)
datasHTML+="<td>"+datas[row][field]+"</td>";
} }
datasHTML+="</tr>"; datasHTML+="</tr>";
} }
@ -200,38 +202,3 @@ export class freeCSV2HTML
} }
} }
/* 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*/