FreeDatas2HTML/src/freeDatas2HTMLSelector.ts

153 lines
6.6 KiB
TypeScript

const { compare }= require('natural-orderby');
const errors = require("./errors.js");
import { DOMElement, Selectors } from "./freeDatas2HTMLInterfaces";
import { FreeDatas2HTML } from "./freeDatas2HTML";
export class Selector implements Selectors
{
_converter: FreeDatas2HTML;
_datasViewElt: DOMElement= { id:"", eltDOM:undefined }; // élément du DOM dans lequel afficher le "select"
_datasFieldNb: number; // numéro du champ dont les données serviront au filtre
_separator: string|undefined; // séparateur éventuel pour les données du champ
name: string = ""; // nom à afficher dans le DOM comme "label" du "select"
values: string[]=[]; // données proposées par le filtre, après traitement des données reçues
// Injection de la classe principale, mais uniquement si les données ont été importées
constructor(converter: FreeDatas2HTML, datasFieldNb: number, elt: DOMElement)
{
if(converter.parseMetas === undefined || converter.parseMetas.fields === undefined || converter.parseDatas.length === 0)
throw new Error(errors.selectorNeedDatas);
else if(! converter.checkFieldExist(Number(datasFieldNb)))
throw new Error(errors.selectorFieldNotFound);
else
{
this._datasViewElt=FreeDatas2HTML.checkInDOMById(elt); // provoque une erreur, si élement non trouvé dans DOM
this._converter=converter;
this._datasFieldNb=datasFieldNb;
}
}
// Ignore un séparateur de données vide
// Attention : pas de trim() ici, car l'espace peut être un séparateur
set separator(separator: string|undefined)
{
if(separator === "")
this._separator=undefined;
else
this._separator=separator;
}
get datasViewElt() : DOMElement
{
return this._datasViewElt;
}
get datasFieldNb() : number
{
return this._datasFieldNb;
}
get separator() : string|undefined
{
return this._separator;
}
// Création du <select> dans le HTML correspondant au filtre
public selector2HTML() : void
{
if(this._converter === undefined || this._datasViewElt.eltDOM === undefined || this._datasFieldNb === undefined)
throw new Error(errors.selector2HTMLFail);
else
{
this.name=this._converter.parseMetas!.fields![this._datasFieldNb]; // this._converter.parse... ne peuvent être indéfinis si this._converter existe (cf constructeur)
for (let row in this._converter.parseDatas)
{
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)
if(checkedValue !== "" && this.values.indexOf(checkedValue) === -1)
this.values.push(checkedValue);
}
else
{
let checkedValues=String(this._converter.parseDatas[row][this.name]).split(this._separator); // String() car les données peuvent être des chiffres, etc.
for(let i in checkedValues)
{
let checkedValue=checkedValues[i].trim();
if(checkedValue !== "" && this.values.indexOf(checkedValue) === -1)
this.values.push(checkedValue);
}
}
}
if(this.values.length > 0)
{
if(this._converter.getSortingFunctionForField(this._datasFieldNb) !== undefined)
this.values.sort(this._converter.getSortingFunctionForField(this._datasFieldNb)!.sort); // si une fonction est définie pour ce champ, sort() doit exister, cf. interface
else
this.values.sort(compare());
let selectorsHTML="<label for='freeDatas2HTML_"+this._datasViewElt.id+"'>"+this.name+" : </label><select name='freeDatas2HTML_"+this._datasViewElt.id+"' id='freeDatas2HTML_"+this._datasViewElt.id+"'><option value='0'>----</option>"; // l'option zéro permet de rafraichir en ignorant ce filtre
for(let j in this.values)
selectorsHTML+="<option value='"+(Number(j)+1)+"'>"+this.values[j]+"</option>";
selectorsHTML+="</select>";
this. _datasViewElt.eltDOM.innerHTML=selectorsHTML;
const selectElement=document.getElementById("freeDatas2HTML_"+this._datasViewElt.id) as HTMLInputElement, mySelector=this;
selectElement.addEventListener("change", function(e)
{
mySelector._converter.refreshView();
});
}
}
}
// Vérifie si une valeur est sélectionnée dans la liste et, si oui, la retourne
public getSelectionnedId() : number
{
const selectElement=document.getElementById("freeDatas2HTML_"+this._datasViewElt.id) as HTMLInputElement;
if(selectElement === undefined)
return 0;
else
return parseInt(selectElement.value,10);
}
// Vérifie sur l'enregistrement passé correspond à la valeur sélectionnée par l'utilisateur dans le filtre
public dataIsOk(data: any) : boolean
{
if(this.name === undefined || this.name === "")
throw new Error(errors.selectorCheckIsOkFail);
let selectedValue = this.getSelectionnedId();
if(selectedValue === 0) // = pas de valeur sélectionnée = pas de filtre sur ce champ
return true;
else
selectedValue=selectedValue-1;
if(this.values[selectedValue] === undefined)
throw new Error(errors.selectorSelectedIndexNotFound);
if(data[this.name] === undefined) // attribut absent pour cet enregistrement, qui est donc refusé
return false;
const selectedValueTxt=this.values[selectedValue] ;
if(this._separator === undefined)
{
if(data[this.name].trim() !== selectedValueTxt) // retour du trim() utilisé pour créer la liste
return false;
else
return true;
}
else
{
let find=false;
let checkedValues=String(data[this.name]).split(this._separator);
for(let j in checkedValues)
{
if(checkedValues[j].trim() === selectedValueTxt)
{
find=true;
break;
}
}
return find;
}
}
}