161 lines
6.8 KiB
TypeScript
161 lines
6.8 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|undefined; // 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
|
||
|
|
||
|
constructor(converter: FreeDatas2HTML)
|
||
|
{
|
||
|
if(converter.parseMetas === undefined || converter.parseMetas.fields === undefined || converter.parseDatas.length === 0)
|
||
|
throw new Error(errors.selectorNeedDatas);
|
||
|
else
|
||
|
this._converter=converter;
|
||
|
}
|
||
|
|
||
|
// Vérifie que l'élément devant recevoir le filtre existe dans la page
|
||
|
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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
get datasViewElt() : DOMElement
|
||
|
{
|
||
|
return this._datasViewElt;
|
||
|
}
|
||
|
|
||
|
// Vérifie que le numéro de champ existe dans les données reçues
|
||
|
set datasFieldNb(datasFieldNb: number|undefined)
|
||
|
{
|
||
|
if(datasFieldNb !== undefined && this._converter.parseMetas!.fields![datasFieldNb] === undefined)
|
||
|
throw new Error(errors.selectorFieldNotFound);
|
||
|
else
|
||
|
this._datasFieldNb=datasFieldNb;
|
||
|
}
|
||
|
|
||
|
get datasFieldNb() : number|undefined
|
||
|
{
|
||
|
return this._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;
|
||
|
}
|
||
|
|
||
|
// 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 peut être indéfinis si this.converter existe (cf constructeur)
|
||
|
for (let row in this._converter.parseDatas)
|
||
|
{
|
||
|
if(this._separator === undefined)
|
||
|
{
|
||
|
let checkedValue=this._converter.parseDatas[row][this.name].trim();
|
||
|
if(checkedValue !== "" && this.values.indexOf(checkedValue) === -1)
|
||
|
this.values.push(checkedValue);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
let checkedValues=String(this._converter.parseDatas[row][this.name]).split(this._separator); // 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.datasHTML=mySelector._converter.createDatasHTML(mySelector._converter.parseMetas!.fields!, mySelector._converter.parseDatas);
|
||
|
mySelector._converter.refreshView();
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Vérifie sur une valeur est sélectionnée dans la liste et 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 est valide pour la valeur sélectionnée dans le filtre
|
||
|
public dataIsOk(data: any) : boolean
|
||
|
{
|
||
|
if(this.name === undefined || data[this.name] === undefined) // attribut absent pour cet enregistrement
|
||
|
return false;
|
||
|
|
||
|
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);
|
||
|
|
||
|
const selectedValueTxt=this.values[selectedValue] ;
|
||
|
if(this._separator === undefined)
|
||
|
{
|
||
|
if(data[this.name].trim() !== selectedValueTxt)
|
||
|
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;
|
||
|
}
|
||
|
}
|
||
|
}
|