Ajout fonctionnalité permettant de classer les données via les colonnes + adaptation exemple et nouvelle compilation du code en JS
This commit is contained in:
parent
14608b8488
commit
4939153d89
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "freedatas2html",
|
"name": "freedatas2html",
|
||||||
"version": "0.3.4",
|
"version": "0.3.5",
|
||||||
"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": {
|
||||||
|
File diff suppressed because one or more lines are too long
@ -19,6 +19,7 @@
|
|||||||
</article>
|
</article>
|
||||||
<aside><p>Les données affichées viennent d'<a href="datas/elements-chimiques.csv">un fichier CSV</a> reprenant une partie des informations trouvées <a href="https://fr.wikipedia.org/wiki/%C3%89l%C3%A9ment_chimique#Caract%C3%A9ristiques_des_diff%C3%A9rents_%C3%A9l%C3%A9ments" target="_blank">sur Wikipédia</a>.</p>
|
<aside><p>Les données affichées viennent d'<a href="datas/elements-chimiques.csv">un fichier CSV</a> reprenant une partie des informations trouvées <a href="https://fr.wikipedia.org/wiki/%C3%89l%C3%A9ment_chimique#Caract%C3%A9ristiques_des_diff%C3%A9rents_%C3%A9l%C3%A9ments" target="_blank">sur Wikipédia</a>.</p>
|
||||||
<p>La dernière colonne permet de montrer la possibilité d'<b>extraire des données d'une colonne ayant plusieurs valeurs par ligne</b>, ici séparées par une virgule.<br>Ce choix de la virgule comme séparateur ne pose pas de problème, tant le fichier CSV est correctement conçu.<br>Elle ne doit par contre pas être présente dans les expressions à extraire de la colonne, sachant que l'on peut désigner n'importe quel autre caractère séparateur.</p>
|
<p>La dernière colonne permet de montrer la possibilité d'<b>extraire des données d'une colonne ayant plusieurs valeurs par ligne</b>, ici séparées par une virgule.<br>Ce choix de la virgule comme séparateur ne pose pas de problème, tant le fichier CSV est correctement conçu.<br>Elle ne doit par contre pas être présente dans les expressions à extraire de la colonne, sachant que l'on peut désigner n'importe quel autre caractère séparateur.</p>
|
||||||
|
<p>Toujours en option, certaines peuvent être désignées comme permettant de classer les données : un 1ᵉʳ clic lance un classement par ordre croissant, le 2ᵉ pour ordre décroissant et ainsi de suite.</p>
|
||||||
<p>Design basé sur <a href="https://www.getpapercss.com" target="_blank">PaperCSS</a></p></aside>
|
<p>Design basé sur <a href="https://www.getpapercss.com" target="_blank">PaperCSS</a></p></aside>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -43,7 +43,8 @@ var initialise = function () { return __awaiter(void 0, void 0, void 0, function
|
|||||||
_a.trys.push([0, 2, , 3]);
|
_a.trys.push([0, 2, , 3]);
|
||||||
converter = new freeDatas2HTML();
|
converter = new freeDatas2HTML();
|
||||||
converter.datasViewElt = { id: "datas" };
|
converter.datasViewElt = { id: "datas" };
|
||||||
converter.datasSelectors = [{ datasFielNb: 3, id: "filtre1" }, { datasFielNb: 4, id: "filtre2" }];
|
converter.datasSelectors = [{ datasFieldNb: 3, id: "filtre1" }, { datasFieldNb: 4, id: "filtre2" }, { datasFieldNb: 5, id: "filtre3", separator: "," }];
|
||||||
|
converter.datasSortingColumns = [{ datasFieldNb: 0 }, { datasFieldNb: 1 }, { datasFieldNb: 2 }];
|
||||||
converter.datasSourceUrl = "http://localhost:8080/datas/elements-chimiques.csv";
|
converter.datasSourceUrl = "http://localhost:8080/datas/elements-chimiques.csv";
|
||||||
return [4, converter.run()];
|
return [4, converter.run()];
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -36,11 +36,13 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|||||||
};
|
};
|
||||||
var Papa = require("papaparse");
|
var Papa = require("papaparse");
|
||||||
var errors = require("./errors.js");
|
var errors = require("./errors.js");
|
||||||
|
var compare = require('natural-orderby').compare;
|
||||||
var freeDatas2HTML = (function () {
|
var freeDatas2HTML = (function () {
|
||||||
function freeDatas2HTML() {
|
function freeDatas2HTML() {
|
||||||
this._datasViewElt = { id: "", eltDOM: undefined };
|
this._datasViewElt = { id: "", eltDOM: undefined };
|
||||||
this._datasSourceUrl = "";
|
this._datasSourceUrl = "";
|
||||||
this._datasSelectors = [];
|
this._datasSelectors = [];
|
||||||
|
this._datasSortingColumns = [];
|
||||||
this.parseMeta = undefined;
|
this.parseMeta = undefined;
|
||||||
this.parseDatas = [];
|
this.parseDatas = [];
|
||||||
this.parseErrors = [];
|
this.parseErrors = [];
|
||||||
@ -81,10 +83,12 @@ var freeDatas2HTML = (function () {
|
|||||||
checkContainerExist = document.getElementById(selectionElts[i].id);
|
checkContainerExist = document.getElementById(selectionElts[i].id);
|
||||||
if (checkContainerExist === null)
|
if (checkContainerExist === null)
|
||||||
console.error(errors.elementNotFound + selectionElts[i].id);
|
console.error(errors.elementNotFound + selectionElts[i].id);
|
||||||
else if (Number.isInteger(selectionElts[i].datasFielNb) === false || selectionElts[i].datasFielNb < 0)
|
else if (Number.isInteger(selectionElts[i].datasFieldNb) === false || selectionElts[i].datasFieldNb < 0)
|
||||||
console.error(errors.needNaturalNumber);
|
console.error(errors.needNaturalNumber);
|
||||||
else {
|
else {
|
||||||
selectionElts[i].eltDOM = checkContainerExist;
|
selectionElts[i].eltDOM = checkContainerExist;
|
||||||
|
if (selectionElts[i].separator !== undefined && selectionElts[i].separator === "")
|
||||||
|
selectionElts[i].separator = undefined;
|
||||||
this._datasSelectors.push(selectionElts[i]);
|
this._datasSelectors.push(selectionElts[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,6 +96,24 @@ var freeDatas2HTML = (function () {
|
|||||||
enumerable: true,
|
enumerable: true,
|
||||||
configurable: true
|
configurable: true
|
||||||
});
|
});
|
||||||
|
Object.defineProperty(freeDatas2HTML.prototype, "datasSortingColumns", {
|
||||||
|
get: function () {
|
||||||
|
return this._datasSortingColumns;
|
||||||
|
},
|
||||||
|
set: function (sortingColumns) {
|
||||||
|
this._datasSortingColumns = [];
|
||||||
|
for (var i = 0; i < sortingColumns.length; i++) {
|
||||||
|
if (Number.isInteger(sortingColumns[i].datasFieldNb) === false || sortingColumns[i].datasFieldNb < 0)
|
||||||
|
console.error(errors.needNaturalNumber);
|
||||||
|
else {
|
||||||
|
sortingColumns[i].order = undefined;
|
||||||
|
this._datasSortingColumns.push(sortingColumns[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true
|
||||||
|
});
|
||||||
freeDatas2HTML.prototype.parse = function () {
|
freeDatas2HTML.prototype.parse = function () {
|
||||||
return __awaiter(this, void 0, void 0, function () {
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
var converter;
|
var converter;
|
||||||
@ -129,7 +151,7 @@ var freeDatas2HTML = (function () {
|
|||||||
};
|
};
|
||||||
freeDatas2HTML.prototype.run = function () {
|
freeDatas2HTML.prototype.run = function () {
|
||||||
return __awaiter(this, void 0, void 0, function () {
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
var converter_1, selectorsHTML, i, values, colName, row, j, selectElement;
|
var converter_1, selectorsHTML, i, values, colName, row, checkedValue, checkedValues, i_1, checkedValue, j, selectElement, i;
|
||||||
return __generator(this, function (_a) {
|
return __generator(this, function (_a) {
|
||||||
switch (_a.label) {
|
switch (_a.label) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -146,21 +168,30 @@ var freeDatas2HTML = (function () {
|
|||||||
console.error(this.parseErrors);
|
console.error(this.parseErrors);
|
||||||
else {
|
else {
|
||||||
converter_1 = this;
|
converter_1 = this;
|
||||||
this.datasHTML = this.createDatasHTML(this.parseMeta.fields, this.parseDatas);
|
|
||||||
this._datasViewElt.eltDOM.innerHTML = this.datasHTML;
|
|
||||||
if (this._datasSelectors.length > 0) {
|
if (this._datasSelectors.length > 0) {
|
||||||
selectorsHTML = [];
|
selectorsHTML = [];
|
||||||
for (i in this._datasSelectors) {
|
for (i in this._datasSelectors) {
|
||||||
if (this._datasSelectors[i].datasFielNb > (this.parseMeta.fields.length - 1))
|
if (this._datasSelectors[i].datasFieldNb > (this.parseMeta.fields.length - 1))
|
||||||
throw new Error(errors.selectorFieldNotFound);
|
throw new Error(errors.selectorFieldNotFound);
|
||||||
else {
|
else {
|
||||||
values = [], colName = this.parseMeta.fields[this._datasSelectors[i].datasFielNb];
|
values = [], colName = this.parseMeta.fields[this._datasSelectors[i].datasFieldNb];
|
||||||
for (row in this.parseDatas) {
|
for (row in this.parseDatas) {
|
||||||
if (values.indexOf(this.parseDatas[row][colName].trim()) === -1)
|
if (this._datasSelectors[i].separator === undefined) {
|
||||||
values.push(this.parseDatas[row][colName].trim());
|
checkedValue = this.parseDatas[row][colName].trim();
|
||||||
|
if (checkedValue !== "" && values.indexOf(checkedValue) === -1)
|
||||||
|
values.push(checkedValue);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
checkedValues = this.parseDatas[row][colName].split(this._datasSelectors[i].separator);
|
||||||
|
for (i_1 in checkedValues) {
|
||||||
|
checkedValue = checkedValues[i_1].trim();
|
||||||
|
if (checkedValue !== "" && values.indexOf(checkedValue) === -1)
|
||||||
|
values.push(checkedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (values.length > 0) {
|
if (values.length > 0) {
|
||||||
values.sort();
|
values.sort(compare());
|
||||||
this._datasSelectors[i].name = colName;
|
this._datasSelectors[i].name = colName;
|
||||||
this._datasSelectors[i].values = values;
|
this._datasSelectors[i].values = values;
|
||||||
selectorsHTML[i] = "<label for='freeDatas2HTMLSelector" + i + "'>" + colName + " : </label><select name='freeDatas2HTMLSelector" + i + "' id='freeDatas2HTMLSelector" + i + "'><option value='0'>----</option>";
|
selectorsHTML[i] = "<label for='freeDatas2HTMLSelector" + i + "'>" + colName + " : </label><select name='freeDatas2HTMLSelector" + i + "' id='freeDatas2HTMLSelector" + i + "'><option value='0'>----</option>";
|
||||||
@ -171,12 +202,18 @@ var freeDatas2HTML = (function () {
|
|||||||
selectElement = document.getElementById("freeDatas2HTMLSelector" + i);
|
selectElement = document.getElementById("freeDatas2HTMLSelector" + i);
|
||||||
selectElement.addEventListener('change', function (e) {
|
selectElement.addEventListener('change', function (e) {
|
||||||
converter_1.datasHTML = converter_1.createDatasHTML(converter_1.parseMeta.fields, converter_1.parseDatas);
|
converter_1.datasHTML = converter_1.createDatasHTML(converter_1.parseMeta.fields, converter_1.parseDatas);
|
||||||
converter_1._datasViewElt.eltDOM.innerHTML = converter_1.datasHTML;
|
converter_1.refreshView();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (i in this._datasSortingColumns) {
|
||||||
|
if (this._datasSortingColumns[i].datasFieldNb > (this.parseMeta.fields.length - 1))
|
||||||
|
throw new Error(errors.sortingColumnsFieldNotFound);
|
||||||
|
}
|
||||||
|
this.datasHTML = this.createDatasHTML(this.parseMeta.fields, this.parseDatas);
|
||||||
|
this.refreshView();
|
||||||
return [2, true];
|
return [2, true];
|
||||||
}
|
}
|
||||||
return [2];
|
return [2];
|
||||||
@ -184,12 +221,50 @@ var freeDatas2HTML = (function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
freeDatas2HTML.prototype.refreshView = function () {
|
||||||
|
if (this._datasViewElt.eltDOM !== undefined) {
|
||||||
|
var converter_2 = this;
|
||||||
|
this._datasViewElt.eltDOM.innerHTML = this.datasHTML;
|
||||||
|
if (this._datasSortingColumns.length > 0) {
|
||||||
|
var getTableTh = document.querySelectorAll("table th");
|
||||||
|
if (getTableTh !== null) {
|
||||||
|
var _loop_1 = function (i) {
|
||||||
|
var datasFieldNb = this_1._datasSortingColumns[i].datasFieldNb;
|
||||||
|
var htmlContent = getTableTh[datasFieldNb].innerHTML;
|
||||||
|
htmlContent = "<a href='#freeDatas2HTMLSorting" + datasFieldNb + "' id='freeDatas2HTMLSorting" + datasFieldNb + "'>" + htmlContent + "</a>";
|
||||||
|
getTableTh[datasFieldNb].innerHTML = htmlContent;
|
||||||
|
var sortingElement = document.getElementById("freeDatas2HTMLSorting" + datasFieldNb);
|
||||||
|
sortingElement.addEventListener('click', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var order = converter_2.datasSortingColumns[i].order;
|
||||||
|
if (order === undefined || order === "desc")
|
||||||
|
converter_2.datasSortingColumns[i].order = "asc";
|
||||||
|
else
|
||||||
|
converter_2.datasSortingColumns[i].order = "desc";
|
||||||
|
converter_2._datasSortedColumn = converter_2.datasSortingColumns[i];
|
||||||
|
converter_2.datasHTML = converter_2.createDatasHTML(converter_2.parseMeta.fields, converter_2.parseDatas);
|
||||||
|
converter_2.refreshView();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var this_1 = this;
|
||||||
|
for (var i in this._datasSortingColumns) {
|
||||||
|
_loop_1(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
freeDatas2HTML.prototype.createDatasHTML = function (fields, datas) {
|
freeDatas2HTML.prototype.createDatasHTML = function (fields, datas) {
|
||||||
var checkSelectorExist, filters = [];
|
var checkSelectorExist, filters = [];
|
||||||
for (var i in this._datasSelectors) {
|
for (var i in this._datasSelectors) {
|
||||||
checkSelectorExist = document.querySelector("#" + this._datasSelectors[i].id + " select");
|
checkSelectorExist = document.querySelector("#" + this._datasSelectors[i].id + " select");
|
||||||
if (checkSelectorExist != null && checkSelectorExist.value != "0")
|
if (checkSelectorExist != null && checkSelectorExist.selectedIndex != 0)
|
||||||
filters.push({ field: this._datasSelectors[i].name, value: this._datasSelectors[i].values[checkSelectorExist.selectedIndex - 1] });
|
filters.push({ field: this._datasSelectors[i].name, value: this._datasSelectors[i].values[checkSelectorExist.selectedIndex - 1], separator: this._datasSelectors[i].separator });
|
||||||
|
}
|
||||||
|
if (this._datasSortedColumn !== undefined) {
|
||||||
|
var col_1 = fields[this._datasSortedColumn.datasFieldNb];
|
||||||
|
var colOrder_1 = this._datasSortedColumn.order;
|
||||||
|
datas.sort(function (a, b) { return compare({ order: colOrder_1 })(a[col_1], b[col_1]); });
|
||||||
}
|
}
|
||||||
var datasHTML = "<table><thead>";
|
var datasHTML = "<table><thead>";
|
||||||
for (var i in fields)
|
for (var i in fields)
|
||||||
@ -199,9 +274,22 @@ var freeDatas2HTML = (function () {
|
|||||||
var visible = true;
|
var visible = true;
|
||||||
if (filters.length !== 0) {
|
if (filters.length !== 0) {
|
||||||
for (var i in filters) {
|
for (var i in filters) {
|
||||||
|
if (filters[i].separator === undefined) {
|
||||||
if (datas[row][filters[i].field].trim() != filters[i].value)
|
if (datas[row][filters[i].field].trim() != filters[i].value)
|
||||||
visible = false;
|
visible = false;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
var checkedValues = datas[row][filters[i].field].split(filters[i].separator), finded = false;
|
||||||
|
for (var j in checkedValues) {
|
||||||
|
if (checkedValues[j].trim() === filters[i].value) {
|
||||||
|
finded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!finded)
|
||||||
|
visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (visible) {
|
if (visible) {
|
||||||
datasHTML += "<tr>";
|
datasHTML += "<tr>";
|
||||||
|
@ -7,4 +7,5 @@ module.exports =
|
|||||||
needUrl: "Merci de fournir une url valide pour le fichier CSV à parser.",
|
needUrl: "Merci de fournir une url valide pour le fichier CSV à parser.",
|
||||||
parserFail: "La lecture des données du fichier a échoué.",
|
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.",
|
selectorFieldNotFound: "Au moins une des colonnes devant servir à filtrer les données n'existe pas dans le fichier.",
|
||||||
|
sortingColumnsFieldNotFound: "Au moins une des colonnes devant servir à classer les données n'existe pas dans le fichier.",
|
||||||
};
|
};
|
@ -7,6 +7,7 @@ const initialise = async () =>
|
|||||||
let converter=new freeDatas2HTML();
|
let converter=new freeDatas2HTML();
|
||||||
converter.datasViewElt={ id:"datas" };
|
converter.datasViewElt={ id:"datas" };
|
||||||
converter.datasSelectors=[{ datasFieldNb:3, id:"filtre1"}, { datasFieldNb:4, id:"filtre2"},{ datasFieldNb:5, id:"filtre3", separator:"," }];
|
converter.datasSelectors=[{ datasFieldNb:3, id:"filtre1"}, { datasFieldNb:4, id:"filtre2"},{ datasFieldNb:5, id:"filtre3", separator:"," }];
|
||||||
|
converter.datasSortingColumns=[{ datasFieldNb:0 }, { datasFieldNb:1 },{ datasFieldNb:2 }];
|
||||||
converter.datasSourceUrl="http://localhost:8080/datas/elements-chimiques.csv";
|
converter.datasSourceUrl="http://localhost:8080/datas/elements-chimiques.csv";
|
||||||
await converter.run();
|
await converter.run();
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,15 @@ const errors = require("./errors.js");
|
|||||||
const { compare }= require('natural-orderby');
|
const { compare }= require('natural-orderby');
|
||||||
|
|
||||||
import { papaParseDatas, papaParseErrors, papaParseMeta } from "./papaParseInterfaces";
|
import { papaParseDatas, papaParseErrors, papaParseMeta } from "./papaParseInterfaces";
|
||||||
import { domElement, selectors } from "./freeDatas2HTMLInterfaces";
|
import { domElement, selectors, sortingColumns } from "./freeDatas2HTMLInterfaces";
|
||||||
|
|
||||||
export class freeDatas2HTML
|
export class freeDatas2HTML
|
||||||
{
|
{
|
||||||
private _datasViewElt: domElement = { id:"", eltDOM:undefined };
|
private _datasViewElt: domElement = { id:"", eltDOM:undefined };
|
||||||
private _datasSourceUrl: string = "";
|
private _datasSourceUrl: string = "";
|
||||||
private _datasSelectors: selectors[] = [];
|
private _datasSelectors: selectors[] = [];
|
||||||
|
private _datasSortingColumns: sortingColumns[] = [];
|
||||||
|
private _datasSortedColumn : sortingColumns|undefined;
|
||||||
|
|
||||||
public parseMeta: papaParseMeta|undefined = undefined;
|
public parseMeta: papaParseMeta|undefined = undefined;
|
||||||
public parseDatas: papaParseDatas[] = [];
|
public parseDatas: papaParseDatas[] = [];
|
||||||
@ -46,7 +48,7 @@ export class freeDatas2HTML
|
|||||||
checkContainerExist=document.getElementById(selectionElts[i].id);
|
checkContainerExist=document.getElementById(selectionElts[i].id);
|
||||||
if(checkContainerExist === null)
|
if(checkContainerExist === null)
|
||||||
console.error(errors.elementNotFound+selectionElts[i].id);
|
console.error(errors.elementNotFound+selectionElts[i].id);
|
||||||
else if(Number.isInteger( selectionElts[i].datasFieldNb) === false || selectionElts[i].datasFieldNb < 0)
|
else if(Number.isInteger(selectionElts[i].datasFieldNb) === false || selectionElts[i].datasFieldNb < 0)
|
||||||
console.error(errors.needNaturalNumber);
|
console.error(errors.needNaturalNumber);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -63,6 +65,26 @@ export class freeDatas2HTML
|
|||||||
return this._datasSelectors;
|
return this._datasSelectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set datasSortingColumns(sortingColumns: sortingColumns[])
|
||||||
|
{
|
||||||
|
this._datasSortingColumns=[];
|
||||||
|
for(let i = 0; i < sortingColumns.length; i++)
|
||||||
|
{
|
||||||
|
if(Number.isInteger(sortingColumns[i].datasFieldNb) === false || sortingColumns[i].datasFieldNb < 0)
|
||||||
|
console.error(errors.needNaturalNumber);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sortingColumns[i].order=undefined;
|
||||||
|
this._datasSortingColumns.push(sortingColumns[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get datasSortingColumns() : sortingColumns[]
|
||||||
|
{
|
||||||
|
return this._datasSortingColumns;
|
||||||
|
}
|
||||||
|
|
||||||
public async parse(): Promise<any>
|
public async parse(): Promise<any>
|
||||||
{
|
{
|
||||||
const converter=this;
|
const converter=this;
|
||||||
@ -118,9 +140,7 @@ export class freeDatas2HTML
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
let converter=this;
|
let converter=this;
|
||||||
// Affichage initial de toutes les données du fichier
|
|
||||||
this.datasHTML=this.createDatasHTML(this.parseMeta!.fields, this.parseDatas);
|
|
||||||
this._datasViewElt.eltDOM.innerHTML=this.datasHTML;
|
|
||||||
// Si demandé, création des listes permettant de filter les données
|
// Si demandé, création des listes permettant de filter les données
|
||||||
if(this._datasSelectors.length > 0)
|
if(this._datasSelectors.length > 0)
|
||||||
{
|
{
|
||||||
@ -168,19 +188,67 @@ export class freeDatas2HTML
|
|||||||
selectElement.addEventListener('change', function(e)
|
selectElement.addEventListener('change', function(e)
|
||||||
{
|
{
|
||||||
converter.datasHTML=converter.createDatasHTML(converter.parseMeta!.fields as string[], converter.parseDatas);
|
converter.datasHTML=converter.createDatasHTML(converter.parseMeta!.fields as string[], converter.parseDatas);
|
||||||
converter._datasViewElt.eltDOM!.innerHTML=converter.datasHTML;
|
converter.refreshView();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Je teste aussi les colonnes devant servir à classer les données.
|
||||||
|
for(let i in this._datasSortingColumns)
|
||||||
|
{
|
||||||
|
if(this._datasSortingColumns[i].datasFieldNb > (this.parseMeta!.fields.length-1))
|
||||||
|
throw new Error(errors.sortingColumnsFieldNotFound);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si tout est ok, affichage initial de toutes les données du fichier
|
||||||
|
this.datasHTML=this.createDatasHTML(this.parseMeta!.fields, this.parseDatas);
|
||||||
|
this.refreshView();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private refreshView() : void
|
||||||
|
{
|
||||||
|
if(this._datasViewElt.eltDOM !== undefined)
|
||||||
|
{
|
||||||
|
const converter=this;
|
||||||
|
this._datasViewElt.eltDOM.innerHTML=this.datasHTML;
|
||||||
|
// Ici car il faut que la tableau soit déjà dans le DOM pour écouter les clics
|
||||||
|
if(this._datasSortingColumns.length > 0)
|
||||||
|
{
|
||||||
|
let getTableTh=document.querySelectorAll("table th");
|
||||||
|
if(getTableTh !== null)
|
||||||
|
{
|
||||||
|
for(let i in this._datasSortingColumns)
|
||||||
|
{
|
||||||
|
let datasFieldNb=this._datasSortingColumns[i].datasFieldNb;
|
||||||
|
let htmlContent=getTableTh[datasFieldNb].innerHTML;
|
||||||
|
htmlContent="<a href='#freeDatas2HTMLSorting"+datasFieldNb+"' id='freeDatas2HTMLSorting"+datasFieldNb+"'>"+htmlContent+"</a>";
|
||||||
|
getTableTh[datasFieldNb].innerHTML=htmlContent;
|
||||||
|
let sortingElement=document.getElementById("freeDatas2HTMLSorting"+datasFieldNb);
|
||||||
|
sortingElement!.addEventListener('click', function(e)
|
||||||
|
{
|
||||||
|
e.preventDefault();
|
||||||
|
let order=converter.datasSortingColumns[i].order ;
|
||||||
|
if(order === undefined || order === "desc")
|
||||||
|
converter.datasSortingColumns[i].order="asc";
|
||||||
|
else
|
||||||
|
converter.datasSortingColumns[i].order="desc";
|
||||||
|
converter._datasSortedColumn = converter.datasSortingColumns[i];
|
||||||
|
converter.datasHTML=converter.createDatasHTML(converter.parseMeta!.fields as string[], converter.parseDatas);
|
||||||
|
converter.refreshView();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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.
|
// Dois-je filtrer les données ?
|
||||||
let checkSelectorExist: HTMLSelectElement|null, filters: any[] = [];
|
let checkSelectorExist: HTMLSelectElement|null, filters: any[] = [];
|
||||||
for(let i in this._datasSelectors)
|
for(let i in this._datasSelectors)
|
||||||
{
|
{
|
||||||
@ -189,6 +257,15 @@ export class freeDatas2HTML
|
|||||||
if(checkSelectorExist != null && checkSelectorExist.selectedIndex != 0)
|
if(checkSelectorExist != null && checkSelectorExist.selectedIndex != 0)
|
||||||
filters.push({ field: this._datasSelectors[i].name, value: this._datasSelectors[i].values![checkSelectorExist.selectedIndex-1], separator:this._datasSelectors[i].separator });
|
filters.push({ field: this._datasSelectors[i].name, value: this._datasSelectors[i].values![checkSelectorExist.selectedIndex-1], separator:this._datasSelectors[i].separator });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dois-je classer les données par rapport à une colonne ?
|
||||||
|
if(this._datasSortedColumn !== undefined)
|
||||||
|
{
|
||||||
|
const col=fields[this._datasSortedColumn.datasFieldNb];
|
||||||
|
const colOrder=this._datasSortedColumn.order;
|
||||||
|
datas.sort( (a, b) => compare( {order: colOrder} )(a[col], b[col]));
|
||||||
|
}
|
||||||
|
|
||||||
// Création du tableau de données :
|
// 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)
|
||||||
|
@ -10,3 +10,8 @@ export interface selectors extends domElement
|
|||||||
name?: string;
|
name?: string;
|
||||||
values? : string[];
|
values? : string[];
|
||||||
}
|
}
|
||||||
|
export interface sortingColumns
|
||||||
|
{
|
||||||
|
datasFieldNb: number;
|
||||||
|
order?: "asc"|"desc"|undefined;
|
||||||
|
}
|
@ -9,4 +9,8 @@ module.exports =
|
|||||||
datasHTMLFor2Select:'<table><thead><tr><th>Z (numéro atomique)</th><th>Élément</th><th>Symbole</th><th>Famille</th><th>Abondance des éléments dans la croûte terrestre (μg/k)</th></tr></thead><tbody><tr><td>2</td><td>Hélium</td><td>He</td><td>Gaz noble</td><td>> 1 et < 100 000</td></tr><tr><td>10</td><td>Néon</td><td>Ne</td><td>Gaz noble</td><td>> 1 et < 100 000</td></tr><tr><td>18</td><td>Argon</td><td>Ar</td><td>Gaz noble</td><td>> 1 et < 100 000</td></tr></tbody></table>',
|
datasHTMLFor2Select:'<table><thead><tr><th>Z (numéro atomique)</th><th>Élément</th><th>Symbole</th><th>Famille</th><th>Abondance des éléments dans la croûte terrestre (μg/k)</th></tr></thead><tbody><tr><td>2</td><td>Hélium</td><td>He</td><td>Gaz noble</td><td>> 1 et < 100 000</td></tr><tr><td>10</td><td>Néon</td><td>Ne</td><td>Gaz noble</td><td>> 1 et < 100 000</td></tr><tr><td>18</td><td>Argon</td><td>Ar</td><td>Gaz noble</td><td>> 1 et < 100 000</td></tr></tbody></table>',
|
||||||
datasHTMLFor2SelectNone:'<table><thead><tr><th>Z (numéro atomique)</th><th>Élément</th><th>Symbole</th><th>Famille</th><th>Abondance des éléments dans la croûte terrestre (μg/k)</th></tr></thead><tbody></tbody></table>',
|
datasHTMLFor2SelectNone:'<table><thead><tr><th>Z (numéro atomique)</th><th>Élément</th><th>Symbole</th><th>Famille</th><th>Abondance des éléments dans la croûte terrestre (μg/k)</th></tr></thead><tbody></tbody></table>',
|
||||||
datasHTMLForSelectTagsField:'<table><thead><tr><th>Z (numéro atomique)</th><th>Élément</th><th>Symbole</th><th>Famille</th><th>Abondance des éléments dans la croûte terrestre (μg/k)</th><th>Étiquettes</th></tr></thead><tbody><tr><td>118</td><td>Oganesson</td><td>Og</td><td>Indéfinie</td><td>Inexistant</td><td>Exemple10</td></tr></tbody></table>',
|
datasHTMLForSelectTagsField:'<table><thead><tr><th>Z (numéro atomique)</th><th>Élément</th><th>Symbole</th><th>Famille</th><th>Abondance des éléments dans la croûte terrestre (μg/k)</th><th>Étiquettes</th></tr></thead><tbody><tr><td>118</td><td>Oganesson</td><td>Og</td><td>Indéfinie</td><td>Inexistant</td><td>Exemple10</td></tr></tbody></table>',
|
||||||
|
sortingColumn1HTML: '<a href="#freeDatas2HTMLSorting0" id="freeDatas2HTMLSorting0">Z (numéro atomique)</a>',
|
||||||
|
sortingColumn2HTML: '<a href="#freeDatas2HTMLSorting2" id="freeDatas2HTMLSorting2">Symbole</a>',
|
||||||
|
datasHTMLFor2Select1Clic: '<table><thead><tr><th>Z (numéro atomique)</th><th>Élément</th><th><a href="#freeDatas2HTMLSorting2" id="freeDatas2HTMLSorting2">Symbole</a></th><th>Famille</th><th>Abondance des éléments dans la croûte terrestre (μg/k)</th></tr></thead><tbody><tr><td>18</td><td>Argon</td><td>Ar</td><td>Gaz noble</td><td>> 1 et < 100 000</td></tr><tr><td>2</td><td>Hélium</td><td>He</td><td>Gaz noble</td><td>> 1 et < 100 000</td></tr><tr><td>10</td><td>Néon</td><td>Ne</td><td>Gaz noble</td><td>> 1 et < 100 000</td></tr></tbody></table>',
|
||||||
|
datasHTMLFor2Select2Clic: '<table><thead><tr><th>Z (numéro atomique)</th><th>Élément</th><th><a href="#freeDatas2HTMLSorting2" id="freeDatas2HTMLSorting2">Symbole</a></th><th>Famille</th><th>Abondance des éléments dans la croûte terrestre (μg/k)</th></tr></thead><tbody><tr><td>10</td><td>Néon</td><td>Ne</td><td>Gaz noble</td><td>> 1 et < 100 000</td></tr><tr><td>2</td><td>Hélium</td><td>He</td><td>Gaz noble</td><td>> 1 et < 100 000</td></tr><tr><td>18</td><td>Argon</td><td>Ar</td><td>Gaz noble</td><td>> 1 et < 100 000</td></tr></tbody></table>',
|
||||||
}
|
}
|
@ -51,6 +51,16 @@ describe("freeDatas2HTML", () =>
|
|||||||
expect(converter.datasSelectors[0].id).toEqual("selector1");
|
expect(converter.datasSelectors[0].id).toEqual("selector1");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Ne doit accepter que les colonnes de classement pour lesquelles les numéros fournis sont des nombres naturels.", () =>
|
||||||
|
{
|
||||||
|
converter.datasSortingColumns=[{ datasFieldNb:2.3 },{ datasFieldNb:3 }];
|
||||||
|
expect(converter.datasSortingColumns.length).toEqual(1);
|
||||||
|
converter.datasSortingColumns=[{ datasFieldNb:2 },{ datasFieldNb:-1 }];
|
||||||
|
expect(converter.datasSortingColumns.length).toEqual(1);
|
||||||
|
converter.datasSortingColumns=[{ datasFieldNb:2 },{ datasFieldNb:3 }];
|
||||||
|
expect(converter.datasSortingColumns.length).toEqual(2);
|
||||||
|
});
|
||||||
|
|
||||||
it("Si un séparateur vide est fourni pour un sélecteur, il doit être ignoré.", () =>
|
it("Si un séparateur vide est fourni pour un sélecteur, il doit être ignoré.", () =>
|
||||||
{
|
{
|
||||||
converter.datasSelectors=[{ datasFieldNb:2, id:"selector2", separator:"" }];
|
converter.datasSelectors=[{ datasFieldNb:2, id:"selector2", separator:"" }];
|
||||||
@ -244,4 +254,55 @@ describe("freeDatas2HTML", () =>
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Création et action des colonnes permettant de classer les données affichées.", () =>
|
||||||
|
{
|
||||||
|
beforeEach( () =>
|
||||||
|
{
|
||||||
|
converter.datasViewElt={ id:"datas" };
|
||||||
|
converter.datasSourceUrl="http://localhost:9876/datas/datas1.csv";
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Doit générer une erreur si au moins un des numéros de colonne de classement fournis pour ne correspond pas à une des colonne du fichier.", async () =>
|
||||||
|
{
|
||||||
|
converter.datasSortingColumns=[{ datasFieldNb:0 },{ datasFieldNb:5 }];
|
||||||
|
await expectAsync(converter.run()).toBeRejectedWith(new Error(errors.sortingColumnsFieldNotFound));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Ne doit pas pas générer d'erreur si tous les numéros de colonne de classement fournis correspondent à des colonnes du fichier.", async () =>
|
||||||
|
{
|
||||||
|
converter.datasSortingColumns=[{ datasFieldNb:3 },{ datasFieldNb:4 }];
|
||||||
|
await expectAsync(converter.run()).not.toBeRejected();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Pour chaque colonne de classement demandée, doit générer un lien hypertexte dans l'entête de la colonne.", async () =>
|
||||||
|
{
|
||||||
|
converter.datasSortingColumns=[{ datasFieldNb:0 },{ datasFieldNb:2 }];
|
||||||
|
await converter.run();
|
||||||
|
let getTableTh=document.querySelectorAll("table th");
|
||||||
|
expect(getTableTh[0].innerHTML).toEqual(fixtures.sortingColumn1HTML);
|
||||||
|
expect(getTableTh[2].innerHTML).toEqual(fixtures.sortingColumn2HTML);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Le 1er click sur l'entête d'une des colonnes doit classer les données dans le sens ascendant, puis descendant et ainsi de suite, en prenant en compte les éventuels filtres.", async () =>
|
||||||
|
{
|
||||||
|
converter.datasSelectors=[{ datasFieldNb:3, id:"selector1"},{ datasFieldNb:4, id:"selector2"}];
|
||||||
|
converter.datasSortingColumns=[{ datasFieldNb:2 }];
|
||||||
|
await converter.run();
|
||||||
|
let selectElement = document.getElementById("freeDatas2HTMLSelector0") as HTMLInputElement;
|
||||||
|
selectElement.value="2";
|
||||||
|
selectElement = document.getElementById("freeDatas2HTMLSelector1") as HTMLInputElement;
|
||||||
|
selectElement.value="1";
|
||||||
|
selectElement.dispatchEvent(new Event('change'));
|
||||||
|
let getTableThLink=document.querySelector("table th a") as HTMLElement;
|
||||||
|
getTableThLink.click();// tri ascendant
|
||||||
|
let txtDatasViewsElt=document.getElementById("datas").innerHTML;
|
||||||
|
expect(txtDatasViewsElt).toEqual(fixtures.datasHTMLFor2Select1Clic);
|
||||||
|
getTableThLink.click();// tri descendant
|
||||||
|
txtDatasViewsElt=document.getElementById("datas").innerHTML;
|
||||||
|
expect(txtDatasViewsElt).toEqual(fixtures.datasHTMLFor2Select2Clic);
|
||||||
|
getTableThLink.click();// de nouveau ascendant
|
||||||
|
txtDatasViewsElt=document.getElementById("datas").innerHTML;
|
||||||
|
expect(txtDatasViewsElt).toEqual(fixtures.datasHTMLFor2Select1Clic);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
Loading…
Reference in New Issue
Block a user