const Papa = require("papaparse"); import { papaParseDatas, papaParseErrors, papaParseMeta } from "./papaParseInterfaces"; const errors=require("./errors.js"); interface domElement { id: string; eltDOM?: HTMLElement; } interface selectors extends domElement { colCSV: number; } export class freeCSV2HTML { // Configuration : private _datasViewElt: domElement = { id:"", eltDOM:undefined }; 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[] = []; private datasHTML: string = ""; set datasViewElt(elt: domElement) { let checkContainerExist=document.getElementById(elt.id); if(checkContainerExist === null) throw new Error(errors.elementNotFound+elt.id); else { this._datasViewElt.id=elt.id; this._datasViewElt.eltDOM=checkContainerExist; } } // Pas plus de tests car nombreux protocoles possibles pour l'url du fichier, pas uniquement http(s). À revoir. set datasSourceUrl(url: string) { if(url.trim().length === 0) throw new Error(errors.needUrl); else 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[]) { let checkContainerExist: HTMLElement|null; for(let i = 0; i < selectors.length; i++) { checkContainerExist=document.getElementById(selectors[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); else selectors[i].eltDOM=checkContainerExist; } this._datasSelectors=selectors; } public async parse(): Promise { const converter=this; // nécessaire pour éviter confusion avec le "this" de la promise return new Promise((resolve,reject) => { if(this._datasSourceUrl !== "" ) { Papa.parse(this._datasSourceUrl, { quoteChar:'"', // à proposer en option ? 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 ? converter.parseDatas=results.data; resolve(true); }, error:function(error :any) { reject(new Error(errors.parserFail)); }, download: true, skipEmptyLines: true, // à proposer en option ? }); } else resolve(new Error(errors.needUrl)); }); } public async run(): Promise { if (this._datasViewElt.eltDOM === undefined) throw new Error(errors.needDatasElt); if(this._datasSourceUrl === "" ) throw new Error(errors.needUrl); if(await this.parse() === true) { 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.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.datasHTML+=""; } this.datasHTML+="
"+this.parseMeta.fields[i]+"
"+this.parseDatas[row][field]+"
"; this._datasViewElt.eltDOM.innerHTML=this.datasHTML; return true; } } } }