Nouvelle version avec classe séparée pour parser le CSV.

This commit is contained in:
Fabrice PENHOËT 2021-09-29 17:56:10 +02:00
parent bcc5ea66f2
commit 50b8a8fccc
11 changed files with 251 additions and 130 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "freedatas2html", "name": "freedatas2html",
"version": "0.5.2", "version": "0.6.0",
"description": "Visualization of data from various sources (CSV, API, HTML...) with filters, classification, pagination, etc.", "description": "Visualization of data from various sources (CSV, API, HTML...) with filters, classification, pagination, etc.",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

View File

@ -3,6 +3,7 @@ module.exports =
converterElementNotFound : "Aucun élément HTML n'a été trouvé ayant comme \"id\" : ", converterElementNotFound : "Aucun élément HTML n'a été trouvé ayant comme \"id\" : ",
converterFieldNotFound : "Le champ n'existe pas dans les données ou les données n'ont pas encore été chargées.", 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.", converterNeedDatasElt: "Merci de fournir un id valide pour l'élément où afficher les données.",
converterNeedDatas: "Merci de fournir les données à traiter.",
converterRefreshFail: "Le nom des champs et l'élement du DOM receveur sont nécessaires à l'affichage des données.", converterRefreshFail: "Le nom des champs et l'élement du DOM receveur sont nécessaires à l'affichage des données.",
pagination2HTMLFail : "Toutes les donnée nécessaires à la création des sélecteurs de pagination n'ont pas été fournies.", 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.", paginationNeedByfaultValueBeInOptions: "La valeur de pagination par défaut doit faire partie des options proposées.",
@ -10,8 +11,11 @@ module.exports =
paginationNeedOptionsValues: "Vous n'avez fourni aucune options possibles pour la pagination.", paginationNeedOptionsValues: "Vous n'avez fourni aucune options possibles pour la pagination.",
paginationNeedPositiveInteger: "Merci de fournir un nombre entier supérieur à zéro pour désigner chaque option de pagination.", paginationNeedPositiveInteger: "Merci de fournir un nombre entier supérieur à zéro pour désigner chaque option de pagination.",
parserDatasNotFound : "Aucune donnée n'a été trouvée.", parserDatasNotFound : "Aucune donnée n'a été trouvée.",
parserFail: "La lecture des données du fichier a échoué.", parserFail: "La lecture des données a échoué.",
parserNeedUrl: "Merci de fournir une url valide pour le fichier à parser.", parserMeetErrors : "Au moins une erreur a été rencontrée durant le traitement des données.",
parserNeedDatas: "Merci de fournir une chaîne de caractères valide à parser.",
parserNeedSource: "Merci de fournir une chaîne de caractères où une url pour les données à parser.",
parserNeedUrl: "Merci de fournir une url valide pour la source distante de données.",
renderNeedDatas: "Il ne peut y avoir de pagination, si les données n'ont pas été récupérées.", renderNeedDatas: "Il ne peut y avoir de pagination, si les données n'ont pas été récupérées.",
renderUnknownField: "Un champ non attendu a été trouvé dans les données à afficher : ", renderUnknownField: "Un champ non attendu a été trouvé dans les données à afficher : ",
selector2HTMLFail: "Le création d'un filtre dans le DOM nécessite l'initialisation de l'élément HTML et du numéro du champs à filter.", selector2HTMLFail: "Le création d'un filtre dans le DOM nécessite l'initialisation de l'élément HTML et du numéro du champs à filter.",

View File

@ -19,11 +19,9 @@ const initialise = async () =>
}; };
// Création d'un convertisseur parsant les données d'un fichier CSV "distant" // Création d'un convertisseur parsant les données d'un fichier CSV "distant"
let converter=new FreeDatas2HTML(); let converter=new FreeDatas2HTML("CSV","", { url:"http://localhost:8080/datas/elements-chimiques.csv"});
converter.datasViewElt={ id:"datas" }; converter.datasViewElt={ id:"datas" };
converter.datasSourceUrl="http://localhost:8080/datas/elements-chimiques.csv"; await converter.run();
await converter.parse();
converter.datasSortingFunctions=[{ datasFieldNb:4, sort:mySort }];
// Adaptation du rendu suivant la taille de l'écran // Adaptation du rendu suivant la taille de l'écran
const myRender=new Render(converter); const myRender=new Render(converter);
if(window.innerWidth < 800) if(window.innerWidth < 800)
@ -46,6 +44,9 @@ const initialise = async () =>
converter.datasRender=myRender; converter.datasRender=myRender;
} }
// Ajout d'une fonction de classement spécifique
converter.datasSortingFunctions=[{ datasFieldNb:4, sort:mySort }];
// Configuration de la pagination // Configuration de la pagination
const pagination=new Pagination(converter, { id:"pages" }, "Page à afficher :"); const pagination=new Pagination(converter, { id:"pages" }, "Page à afficher :");
pagination.options={ displayElement: { id:"paginationOptions" }, values: [10,20,50,500] , name: "Choix de pagination :" }; pagination.options={ displayElement: { id:"paginationOptions" }, values: [10,20,50,500] , name: "Choix de pagination :" };
@ -55,7 +56,7 @@ const initialise = async () =>
// Affichage initial // Affichage initial
converter.datasCounter={ id:"compteur" }; converter.datasCounter={ id:"compteur" };
await converter.run(); await converter.run();
// Création d'outils permettant de filtrer les données des champs de données // Création d'outils permettant de filtrer les données des champs de données
let filtre1=new Selector(converter, 3, { id:"filtre1"} ); let filtre1=new Selector(converter, 3, { id:"filtre1"} );
@ -67,7 +68,7 @@ const initialise = async () =>
filtre3.selector2HTML(); filtre3.selector2HTML();
// + Injection des filtres dans le convertisseur // + Injection des filtres dans le convertisseur
converter.datasSelectors=[filtre1,filtre2,filtre3]; converter.datasSelectors=[filtre1,filtre2,filtre3];
// Ajout de champs permettant de classer les données // Ajout de champs permettant de classer les données
// Uniquement avec un rendu tableau (grand écran), car entêtes de colonne nécessaires // Uniquement avec un rendu tableau (grand écran), car entêtes de colonne nécessaires
if(window.innerWidth >= 800) if(window.innerWidth >= 800)

View File

@ -1,52 +1,77 @@
const Papa = require("papaparse"); const { compare }=require('natural-orderby');
const errors = require("./errors.js"); const errors=require("./errors.js");
const { compare }= require('natural-orderby');
import { Counter, DatasRenders, DOMElement, Paginations, Selectors, SortingFields, SortingFunctions } from "./freeDatas2HTMLInterfaces"; import { Counter, Datas, DatasRenders, DOMElement, Paginations, Parsers, ParseErrors, RemoteSource, Selectors, SortingFields, SortingFunctions } from "./freeDatas2HTMLInterfaces";
import { Pagination} from "./freeDatas2HTMLPagination"; import { Pagination} from "./freeDatas2HTMLPagination";
import { ParserForCSV} from "./freeDatas2HTMLParserForCSV";
import { Render} from "./freeDatas2HTMLRender"; import { Render} from "./freeDatas2HTMLRender";
import { Selector } from "./freeDatas2HTMLSelector"; import { Selector } from "./freeDatas2HTMLSelector";
import { SortingField } from "./freeDatas2HTMLSortingField"; import { SortingField } from "./freeDatas2HTMLSortingField";
import { PapaParseDatas, PapaParseErrors, PapaParseMeta } from "./papaParseInterfaces";
export class FreeDatas2HTML export class FreeDatas2HTML
{ {
// L'élément HTML où afficher les données. Laisser à undefined si non affichées : // L'élément HTML où afficher les données. Laisser à undefined si non affichées :
private _datasViewElt: DOMElement|undefined = undefined; private _datasViewElt: DOMElement|undefined=undefined;
// Le moteur de rendu pour préparer l'affichage des données // Le moteur de rendu pour préparer l'affichage des données
public datasRender: DatasRenders; public datasRender: DatasRenders;
// Le code HTML résultant : // Le code HTML résultant :
public datasHTML: string = ""; public datasHTML: string = "";
// Le parseur :
public parser: Parsers; // public pour permettre de charger un parseur tiers après instanciation
// L'url où accéder aux données : // Données distantes :
private _datasSourceUrl: string = ""; //private _datasRemoteSource: RemoteSource|undefined=undefined;
// Le nom des champs (interfaces à renommer, car PapaParse = cas particulier) : // Ou locales :
public parseMetas: PapaParseMeta|undefined = undefined; //private _datas2Parse:string|undefined=undefined;
// Dans tous les cas, besoin d'un type :
public datasType: "CSV"|"HTML"|"JSON"|undefined;
// Le nom des champs trouvés dans les données :
public fields: string[]|undefined=undefined;
// Les données à proprement parler : // Les données à proprement parler :
public parseDatas: PapaParseDatas[] = []; public datas: []=[];
// Les erreurs rencontrées durant le parsage : // Les erreurs rencontrées durant le traitement des données reçues :
public parseErrors: PapaParseErrors[] = []; public parseErrors: ParseErrors[]|undefined;
// Doit-on tout arrêter si une erreur est rencontrée durant la parsage ? // Doit-on tout arrêter si une erreur est rencontrée durant le traitement ?
public stopIfParseErrors: boolean = false; public stopIfParseErrors: boolean = false;
// Les fonctions spécifiques de classement pour certains champs : // Les fonctions spécifiques de classement pour certains champs :
private _datasSortingFunctions: SortingFunctions[] = []; private _datasSortingFunctions: SortingFunctions[] = [];
// Les filtres possible sur certains champs // Les filtres possible sur certains champs :
datasSelectors: Selectors[] = []; datasSelectors: Selectors[] = [];
// Les champs pouvant être classés // Les champs pouvant être classés :
datasSortingFields: SortingFields[] = []; datasSortingFields: SortingFields[] = [];
// La dernier champ pour lequel le classement a été demandé // La dernier champ pour lequel le classement a été demandé :
datasSortedField: SortingFields|undefined; datasSortedField: SortingFields|undefined;
// La Pagination : // Éventuelle pagination :
pagination: Paginations|undefined; pagination: Paginations|undefined;
// Affichage du nombre total de lignes de données (optionnel) : // Affichage du nombre total de lignes de données (optionnel) :
private _datasCounter: Counter = {}; private _datasCounter: Counter = {};
// J'initialiser avec des valeurs par défaut pouvant être surchargées par les setters // J'initialiser avec des valeurs par défaut pouvant être surchargées par les setters
constructor() constructor(datasType:"CSV"|"HTML"|"JSON", datas2Parse="", datasRemoteSource?:RemoteSource)
{ {
this.datasRender=new Render(this); this.datasRender=new Render(this);
switch (datasType)
{
case "CSV":
this.parser=new ParserForCSV();
break;
case "HTML":
this.parser=new ParserForCSV();
console.error("Appeler le parseur HTML");
break;
case "JSON":
this.parser=new ParserForCSV();
console.error("Appeler le parseur JSON");
break;
}
if(datas2Parse !== "")
this.parser.datas2Parse=datas2Parse;
else if(datasRemoteSource!==undefined)
this.parser.datasRemoteSource=datasRemoteSource;
else
throw new Error(errors.converterNeedDatas);
} }
// Vérifie s'il y a bien un élément dans le DOM pour l'id fourni // Vérifie s'il y a bien un élément dans le DOM pour l'id fourni
@ -65,7 +90,7 @@ export class FreeDatas2HTML
// Vérifie qu'un champ existe bien dans les données // Vérifie qu'un champ existe bien dans les données
public checkFieldExist(nb: number) : boolean public checkFieldExist(nb: number) : boolean
{ {
if(this.parseMetas === undefined || this.parseMetas.fields === undefined || this.parseMetas.fields[nb] === undefined) if(this.fields === undefined || this.fields[nb] === undefined)
return false; return false;
else else
return true; return true;
@ -77,15 +102,6 @@ export class FreeDatas2HTML
this._datasViewElt=FreeDatas2HTML.checkInDOMById(elt); this._datasViewElt=FreeDatas2HTML.checkInDOMById(elt);
} }
// Vérifie que l'url où chercher les données n'est pas vide : inutile si données dans page ou tranmises
set datasSourceUrl(url: string)
{
if(url.trim().length === 0)
throw new Error(errors.parserNeedUrl);
else
this._datasSourceUrl=url.trim();
}
// Vérifie que les numéros de champs pour lesquels il y a des fonctions de classement spécifiques sont cohérents // Vérifie que les numéros de champs pour lesquels il y a des fonctions de classement spécifiques sont cohérents
// ! Ne peut être testé qu'après avoir reçu les données // ! Ne peut être testé qu'après avoir reçu les données
set datasSortingFunctions(SortingFunctions: SortingFunctions[]) set datasSortingFunctions(SortingFunctions: SortingFunctions[])
@ -126,72 +142,36 @@ export class FreeDatas2HTML
return undefined; return undefined;
} }
// Parse des données distantes (url) fournies en CSV :
public async parse(): Promise<any>
{
const converter=this;
return new Promise((resolve,reject) =>
{
if(converter._datasSourceUrl !== "" )
{
Papa.parse(converter._datasSourceUrl,
{
quoteChar: '"',
header: true,
complete: function(results :any)
{
converter.parseErrors=results.errors;
converter.parseDatas=results.data;
// Attention, papaParse peut accepter un nom de colonne vide
let realFields: string[]=[];
for(let i in results.meta.fields)
{
if(results.meta.fields[i].trim() !== "")
realFields.push(results.meta.fields[i]);
}
results.meta.fields=realFields;
converter.parseMetas=results.meta;
resolve(true);
},
error:function(error :any)
{
reject(new Error(errors.parserFail));
},
download: true,
skipEmptyLines: true,
});
}
else
reject(new Error(errors.parserNeedUrl));
});
}
// Lance FreeDatas2HTML suivant les données reçues : // Lance FreeDatas2HTML suivant les données reçues :
public async run(): Promise<any> public async run(): Promise<any>
{ {
if(this._datasSourceUrl === "" ) await this.parser.parse();
throw new Error(errors.parserNeedUrl); if(this.parser.parseResults === undefined)
throw new Error(errors.parserFail);
await this.parse();
if(this.parseDatas.length === 0 || this.parseMetas!.fields === undefined) // je force avec "!", car l'existence de parseMetas est certaine après parse().
throw new Error(errors.parserDatasNotFound);
else if(this.stopIfParseErrors && this.parseErrors.length!==0)
console.error(this.parseErrors);
else else
{ {
// Si tout est ok, affichage initial de toutes les données du fichier this.fields=this.parser.parseResults.fields;
this.refreshView(); this.datas=this.parser.parseResults.datas;
return true; this.parseErrors=this.parser.parseResults.errors;
if(this.fields === undefined)
throw new Error(errors.parserDatasNotFound);
else if(this.stopIfParseErrors && this.parseErrors !== undefined)
throw new Error(errors.parrserMeetErrors);
else
{
// Si tout est ok, affichage initial de toutes les données du fichier
this.refreshView();
return true;
}
} }
} }
refreshView() : void refreshView() : void
{ {
if(this.parseMetas === undefined || this.parseMetas.fields === undefined) if(this.fields === undefined)
throw new Error(errors.converterRefreshFail); throw new Error(errors.converterRefreshFail);
this.datasHTML=this.createDatas2Display(this.parseMetas.fields, this.parseDatas); this.datasHTML=this.createDatas2Display(this.fields, this.datas);
if(this._datasViewElt !== undefined && this._datasViewElt.eltDOM !== undefined) if(this._datasViewElt !== undefined && this._datasViewElt.eltDOM !== undefined)
this._datasViewElt.eltDOM.innerHTML=this.datasHTML; this._datasViewElt.eltDOM.innerHTML=this.datasHTML;

View File

@ -46,6 +46,36 @@ export interface PaginationsPages
values?: number[]; values?: number[];
selectedValue?: number; selectedValue?: number;
} }
export interface Datas
{
[key: string]: string;
}
export interface ParseErrors // erreurs non bloquantes rencontrées lors du parsage de données
{
code?: string;
message: string;
row: number;
type?: string;
}
export interface ParseResults
{
datas: [];
errors: ParseErrors[];
fields: string[];
}
export interface Parsers
{
datasRemoteSource: RemoteSource|undefined;
datas2Parse:string|undefined;
parseResults:ParseResults|undefined;
parse(): Promise<void>;
}
export interface RemoteSource
{
url: string;
headers?: { key:string, value:string|boolean|number }[] ;// revoir types possibles pour Headers ?
withCredentials?:boolean;
}
export interface Selectors export interface Selectors
{ {
datasViewElt: DOMElement; datasViewElt: DOMElement;

View File

@ -21,7 +21,7 @@ export class Pagination implements Paginations
// De plus l'élément du DOM devant recevoir la liste des pages doit exister // De plus l'élément du DOM devant recevoir la liste des pages doit exister
constructor(converter: FreeDatas2HTML, pagesElt: DOMElement, pagesName: string="Pages") constructor(converter: FreeDatas2HTML, pagesElt: DOMElement, pagesName: string="Pages")
{ {
if(converter.parseMetas === undefined || converter.parseMetas.fields === undefined) if(converter.fields === undefined)
throw new Error(errors.paginationNeedDatas); throw new Error(errors.paginationNeedDatas);
else else
{ {

View File

@ -0,0 +1,129 @@
const Papa = require("papaparse");
const errors = require("./errors.js");
import { ParseResults, Parsers, RemoteSource } from "./freeDatas2HTMLInterfaces";
interface papaParseOptions
{
delimiter: string;
newline: string;
quoteChar: string;
escapeChar: string;
transformHeader?(field: string, index: number): string;
preview: number;
comments: false|string,
fastMode: boolean|undefined;
transform?(value: string): string;
}
export class ParserForCSV implements Parsers
{
private _datasRemoteSource: RemoteSource|undefined=undefined;
private _datas2Parse:string|undefined=undefined;
private _parseResults:ParseResults|undefined=undefined;
// Ouverture de certaines options de Papa Parse :
// cf. https://www.papaparse.com/docs#config
public options: papaParseOptions =
{
delimiter: "",
newline: "",
quoteChar: '"',
escapeChar: '"',
transformHeader: function(field: string, index: number): string { return field.trim() },
preview: 0,
comments: "",
fastMode: undefined,
transform: undefined
}
set datasRemoteSource(source: RemoteSource)
{
if(source.url.trim().length === 0)
throw new Error(errors.parserNeedUrl);
else
{
source.url=source.url.trim();
this._datasRemoteSource=source;
}
}
set datas2Parse(datas: string)
{
if(datas.trim().length === 0)
throw new Error(errors.parserNeedDatas);
else
this._datas2Parse=datas.trim();
}
get parseResults() : ParseResults|undefined
{
return this._parseResults;
}
// async dans le cas d'une source distante
// Et création d'une Promise car PapaParse utilise une fonction callback.
public async parse(): Promise<any>
{
const parser=this, options=this.options;
return new Promise((resolve,reject) =>
{
let parseContent="", parseDownload=false, parseDownloadRequestHeaders: any=undefined, parseWithCredentials: any=undefined;
if(parser._datasRemoteSource !== undefined)
{
parseContent=parser._datasRemoteSource.url;
parseDownload=true;
parseWithCredentials=parser._datasRemoteSource.withCredentials; // undefined ok pour PapaParse
if(parser._datasRemoteSource.headers !== undefined)
{
parseDownloadRequestHeaders={};
for (let i in parser._datasRemoteSource.headers)
parseDownloadRequestHeaders[parser._datasRemoteSource.headers[Number(i)].key]=parser._datasRemoteSource.headers[Number(i)].value;
}
}
else if(parser._datas2Parse !== undefined)
parseContent=parser._datas2Parse;
else
reject(new Error(errors.parserNeedSource));
Papa.parse(parseContent,
{
delimiter: options.delimiter,
newline: options.newline,
quoteChar: options.quoteChar,
escapeChar: options.escapeChar,
header: true, // nécessaire pour obtenir le nom des champs
transformHeader: options.transformHeader,
preview: options.preview,
comments: options.comments,
complete: function(results :any)
{
// Attention, Papa Parse peut accepter un nom de champ vide
let realFields: string[]=[];
for(let i in results.meta.fields)
{
if(results.meta.fields[i].trim() !== "")
realFields.push(results.meta.fields[i]);
}
if(realFields.length === 0)
reject(new Error(errors.parserFail));
else
{
parser._parseResults={
datas: results.data,
errors: results.errors,
fields: realFields,
};
resolve(true);
}
},
download: parseDownload,
downloadRequestHeaders: parseDownloadRequestHeaders,
skipEmptyLines:"greedy",
fastMode: options.fastMode,
withCredentials: parseWithCredentials,
transform: options.transform,
});
});
}
}

View File

@ -31,7 +31,7 @@ export class Render implements DatasRenders
public rend2HTML(datas: any[]) : string public rend2HTML(datas: any[]) : string
{ {
// Il peut n'y avoir aucune donnée (filtres...), mais les noms des champs doivent être connus. // Il peut n'y avoir aucune donnée (filtres...), mais les noms des champs doivent être connus.
if(this._converter.parseMetas === undefined || this._converter.parseMetas.fields === undefined) if(this._converter.fields === undefined)
throw new Error(errors.renderNeedDatas); throw new Error(errors.renderNeedDatas);
else else
{ {
@ -40,8 +40,8 @@ export class Render implements DatasRenders
if(this.settings.fieldsBegining !== undefined && this.settings.fieldDisplaying !== undefined && this.settings.fieldsEnding !== undefined ) if(this.settings.fieldsBegining !== undefined && this.settings.fieldDisplaying !== undefined && this.settings.fieldsEnding !== undefined )
{ {
datasHTML+=this.settings.fieldsBegining; datasHTML+=this.settings.fieldsBegining;
for (let i in this._converter.parseMetas.fields) for (let i in this._converter.fields)
datasHTML+=this.settings.fieldDisplaying.replace("#FIELDNAME", this._converter.parseMetas.fields[Number(i)]); datasHTML+=this.settings.fieldDisplaying.replace("#FIELDNAME", this._converter.fields[Number(i)]);
datasHTML+=this.settings.fieldsEnding; datasHTML+=this.settings.fieldsEnding;
} }
datasHTML+=this.settings.linesBegining; datasHTML+=this.settings.linesBegining;
@ -51,7 +51,7 @@ export class Render implements DatasRenders
for(let field in datas[row]) for(let field in datas[row])
{ {
// On n'affiche que les champs attendus et signale les erreurs dans la console // On n'affiche que les champs attendus et signale les erreurs dans la console
if(this._converter.parseMetas.fields.indexOf(field) !== -1) if(this._converter.fields.indexOf(field) !== -1)
datasHTML+=this.settings.dataDisplaying.replace("#VALUE" , datas[row][field]).replace("#FIELDNAME" , field); datasHTML+=this.settings.dataDisplaying.replace("#VALUE" , datas[row][field]).replace("#FIELDNAME" , field);
else else
console.log(errors.renderUnknownField+field); console.log(errors.renderUnknownField+field);

View File

@ -15,7 +15,7 @@ export class Selector implements Selectors
// Injection de la classe principale, mais uniquement si les données ont été importées // Injection de la classe principale, mais uniquement si les données ont été importées
constructor(converter: FreeDatas2HTML, datasFieldNb: number, elt: DOMElement) constructor(converter: FreeDatas2HTML, datasFieldNb: number, elt: DOMElement)
{ {
if(converter.parseMetas === undefined || converter.parseMetas.fields === undefined || converter.parseDatas.length === 0) if(converter.fields === undefined || converter.datas.length === 0)
throw new Error(errors.selectorNeedDatas); throw new Error(errors.selectorNeedDatas);
else if(! converter.checkFieldExist(Number(datasFieldNb))) else if(! converter.checkFieldExist(Number(datasFieldNb)))
throw new Error(errors.selectorFieldNotFound); throw new Error(errors.selectorFieldNotFound);
@ -59,18 +59,18 @@ export class Selector implements Selectors
throw new Error(errors.selector2HTMLFail); throw new Error(errors.selector2HTMLFail);
else else
{ {
this.name=this._converter.parseMetas!.fields![this._datasFieldNb]; // this._converter.parse... ne peuvent être indéfinis si this._converter existe (cf constructeur) this.name=this._converter.fields![this._datasFieldNb]; // this._converter.parse... ne peuvent être indéfinis si this._converter existe (cf constructeur)
for (let row in this._converter.parseDatas) for (let row in this._converter.datas)
{ {
if(this._separator === undefined) if(this._separator === undefined)
{ {
let checkedValue=String(this._converter.parseDatas[row][this.name]).trim(); // trim() nécessaire pour éviter problème de classement du tableau (sort) let checkedValue=String(this._converter.datas[row][this.name]).trim(); // trim() nécessaire pour éviter problème de classement du tableau (sort)
if(checkedValue !== "" && this.values.indexOf(checkedValue) === -1) if(checkedValue !== "" && this.values.indexOf(checkedValue) === -1)
this.values.push(checkedValue); this.values.push(checkedValue);
} }
else else
{ {
let checkedValues=String(this._converter.parseDatas[row][this.name]).split(this._separator); // String() car les données peuvent être des chiffres, etc. let checkedValues=String(this._converter.datas[row][this.name]).split(this._separator); // String() car les données peuvent être des chiffres, etc.
for(let i in checkedValues) for(let i in checkedValues)
{ {
let checkedValue=checkedValues[i].trim(); let checkedValue=checkedValues[i].trim();

View File

@ -13,7 +13,7 @@ export class SortingField implements SortingFields
// Injection de la classe principale, mais uniquement si le nom des champs ont été importés et affichés correctement // Injection de la classe principale, mais uniquement si le nom des champs ont été importés et affichés correctement
constructor(converter: FreeDatas2HTML, datasFieldNb: number, fieldsDOMSelector: string = "th") constructor(converter: FreeDatas2HTML, datasFieldNb: number, fieldsDOMSelector: string = "th")
{ {
if(converter.parseMetas === undefined || converter.parseMetas.fields === undefined) if(converter.fields === undefined)
throw new Error(errors.sortingFieldNeedDatas); throw new Error(errors.sortingFieldNeedDatas);
else if(! converter.checkFieldExist(Number(datasFieldNb))) else if(! converter.checkFieldExist(Number(datasFieldNb)))
throw new Error(errors.sortingFieldFieldNotFound); throw new Error(errors.sortingFieldFieldNotFound);
@ -22,7 +22,7 @@ export class SortingField implements SortingFields
const fields=document.querySelectorAll(fieldsDOMSelector); const fields=document.querySelectorAll(fieldsDOMSelector);
if(fields === undefined) if(fields === undefined)
throw new Error(errors.sortingFieldsNotInHTML); throw new Error(errors.sortingFieldsNotInHTML);
else if(fields.length !== converter.parseMetas.fields.length) else if(fields.length !== converter.fields.length)
throw new Error(errors.sortingFieldsNbFail); throw new Error(errors.sortingFieldsNbFail);
else else
{ {

View File

@ -1,23 +0,0 @@
// cf. https://www.papaparse.com/docs#results
export interface PapaParseDatas
{
[key: string]: string;
}
export interface PapaParseErrors
{
type: string;
code: string;
message: string;
row: number;
}
export interface PapaParseMeta
{
delimiter?: string;
linebreak?: string;
aborted?: boolean;
fields?: string[];
truncated?: boolean;
}