2021-09-17 18:02:45 +02:00
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"
2021-09-22 17:12:00 +02:00
_datasFieldNb : number ; // numéro du champ dont les données serviront au filtre
2021-09-17 18:02:45 +02:00
_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
2021-09-20 11:09:30 +02:00
// Injection de la classe principale, mais uniquement si les données ont été importées
2021-09-22 17:12:00 +02:00
constructor ( converter : FreeDatas2HTML , datasFieldNb : number , elt : DOMElement )
2021-09-17 18:02:45 +02:00
{
if ( converter . parseMetas === undefined || converter . parseMetas . fields === undefined || converter . parseDatas . length === 0 )
throw new Error ( errors . selectorNeedDatas ) ;
2021-09-22 17:12:00 +02:00
else if ( ! converter . checkFieldExist ( Number ( datasFieldNb ) ) )
throw new Error ( errors . selectorFieldNotFound ) ;
2021-09-17 18:02:45 +02:00
else
2021-09-22 17:12:00 +02:00
{
this . _datasViewElt = FreeDatas2HTML . checkInDOMById ( elt ) ; // provoque une erreur, si élement non trouvé dans DOM
2021-09-17 18:02:45 +02:00
this . _converter = converter ;
2021-09-22 17:12:00 +02:00
this . _datasFieldNb = datasFieldNb ;
}
2021-09-17 18:02:45 +02:00
}
2021-09-22 17:12:00 +02:00
// 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 )
2021-09-17 18:02:45 +02:00
{
2021-09-22 17:12:00 +02:00
if ( separator === "" )
this . _separator = undefined ;
else
this . _separator = separator ;
2021-09-17 18:02:45 +02:00
}
get datasViewElt ( ) : DOMElement
{
return this . _datasViewElt ;
}
2021-09-22 17:12:00 +02:00
get datasFieldNb ( ) : number
2021-09-17 18:02:45 +02:00
{
return this . _datasFieldNb ;
}
2021-09-22 17:12:00 +02:00
get separator ( ) : string | undefined
2021-09-17 18:02:45 +02:00
{
2021-09-22 17:12:00 +02:00
return this . _separator ;
2021-09-17 18:02:45 +02:00
}
// 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
{
2021-09-20 11:09:30 +02:00
this . name = this . _converter . parseMetas ! . fields ! [ this . _datasFieldNb ] ; // this._converter.parse... ne peuvent être indéfinis si this._converter existe (cf constructeur)
2021-09-17 18:02:45 +02:00
for ( let row in this . _converter . parseDatas )
{
if ( this . _separator === undefined )
{
2021-09-20 11:09:30 +02:00
let checkedValue = String ( this . _converter . parseDatas [ row ] [ this . name ] ) . trim ( ) ; // trim() nécessaire pour éviter problème de classement du tableau (sort)
2021-09-17 18:02:45 +02:00
if ( checkedValue !== "" && this . values . indexOf ( checkedValue ) === - 1 )
this . values . push ( checkedValue ) ;
}
else
{
2021-09-20 11:09:30 +02:00
let checkedValues = String ( this . _converter . parseDatas [ row ] [ this . name ] ) . split ( this . _separator ) ; // String() car les données peuvent être des chiffres, etc.
2021-09-17 18:02:45 +02:00
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 ( ) ;
} ) ;
}
}
}
2021-09-20 11:09:30 +02:00
// Vérifie si une valeur est sélectionnée dans la liste et, si oui, la retourne
2021-09-17 18:02:45 +02:00
public getSelectionnedId ( ) : number
{
const selectElement = document . getElementById ( "freeDatas2HTML_" + this . _datasViewElt . id ) as HTMLInputElement ;
if ( selectElement === undefined )
return 0 ;
else
return parseInt ( selectElement . value , 10 ) ;
}
2021-09-20 11:09:30 +02:00
// Vérifie sur l'enregistrement passé correspond à la valeur sélectionnée par l'utilisateur dans le filtre
2021-09-17 18:02:45 +02:00
public dataIsOk ( data : any ) : boolean
2021-09-20 11:09:30 +02:00
{
if ( this . name === undefined || this . name === "" )
throw new Error ( errors . selectorCheckIsOkFail ) ;
2021-09-17 18:02:45 +02:00
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 ) ;
2021-09-20 11:09:30 +02:00
if ( data [ this . name ] === undefined ) // attribut absent pour cet enregistrement, qui est donc refusé
return false ;
2021-09-17 18:02:45 +02:00
const selectedValueTxt = this . values [ selectedValue ] ;
if ( this . _separator === undefined )
{
2021-09-20 11:09:30 +02:00
if ( data [ this . name ] . trim ( ) !== selectedValueTxt ) // retour du trim() utilisé pour créer la liste
2021-09-17 18:02:45 +02:00
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 ;
}
}
}