FreeDatas2HTML/src/extensions/SortingFieldsStandAlone.ts

87 lines
3.5 KiB
TypeScript

// Cette classe est une alternative à l'utilisation directe de SortingField.
// Ici, les liens de classement sont créés dans un élément du DOM externe à celui affichant les données
import { DOMElement } from "../interfaces";
import { FreeDatas2HTML, SortingField } from "../FreeDatas2HTML";
const errors=require("../errors.js");
errors.needSortingFields="Vous devez fournir au moins un champ de classement valide.";
interface SortingFieldsSettings
{
allBeginning: string;
allEnding: string;
fieldBeginning: string;
fieldEnding: string;
}
export class SortingFieldsStandAlone
{
private _converter: FreeDatas2HTML;
private _datasViewElt: DOMElement={ id: "", eltDOM: undefined };
public datasSortingFields: SortingField[]=[]; // SortingField refusera les champs non valides
public rendSettings: SortingFieldsSettings;
static readonly defaultSettings=
{
allBeginning: "<span>#LABEL</span><ul>",
allEnding: "</ul>",
fieldBeginning: "<li>",
fieldEnding: "</li>",
};
constructor(converter: FreeDatas2HTML, elt: DOMElement, settings: SortingFieldsSettings=SortingFieldsStandAlone.defaultSettings)
{
// Ne peut être appelé avant d'avoir récupéré la liste des champs :
if(converter.fields.length === 0)
throw new Error(errors.sortingFieldNeedDatas);
// Test l'existence dans le DOM de l'élément devant afficher les options de classement :
this._datasViewElt=FreeDatas2HTML.checkInDOMById(elt);
this._converter=converter;
this.rendSettings=settings;
}
get converter() : FreeDatas2HTML
{
return this._converter;
}
get datasViewElt() : DOMElement
{
return this._datasViewElt;
}
public rend2HTML(label:string="") : void
{
// Au moins un champ de classement valide doit avoir été fourni :
if(this.datasSortingFields.length === 0)
throw new Error(errors.needSortingFields);
// Arrivé ici, il y a au moins un lien de classement à injecter :
let htmlContent=this.rendSettings.allBeginning.replace("#LABEL", label);
for(let field of this.datasSortingFields)
{
htmlContent+=this.rendSettings.fieldBeginning+"<a href='#freeDatas2HTMLSorting"+field.datasFieldNb+"' id='freeDatas2HTMLSorting"+field.datasFieldNb+"'>"+this._converter.fields[field.datasFieldNb]+"</a>"+this.rendSettings.fieldEnding;
}
htmlContent+=this.rendSettings.allEnding;
this._datasViewElt.eltDOM!.innerHTML=htmlContent;// "!" car existence de l'élement dans le DOM a été testé dans le constructeur.
// Les liens venant d'êtres injectés dans le DOM, il reste à les rendre actifs :
for(let field of this.datasSortingFields)
{
let sortingLink=document.getElementById("freeDatas2HTMLSorting"+field.datasFieldNb);
sortingLink!.addEventListener("click", function(e) // "!" car je sais que sortingLink existe, venant de le créer.
{
e.preventDefault();
if(field.order === undefined || field.order === "desc")
field.order="asc";
else
field.order="desc";
field.converter.datasSortedField=field;
field.converter.refreshView();
});
}
}
}
// Utile au script de tests :
export { FreeDatas2HTML, SortingField } from "../FreeDatas2HTML";
export { errors };