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
{
2021-09-29 17:56:10 +02:00
if ( converter . fields === undefined || converter . datas . length === 0 )
2021-09-17 18:02:45 +02:00
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
2021-10-07 12:43:29 +02:00
// Attention : pas de trim(), car l'espace peut être un séparateur
2021-09-22 17:12:00 +02:00
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-29 17:56:10 +02:00
this . name = this . _converter . fields ! [ this . _datasFieldNb ] ; // this._converter.parse... ne peuvent être indéfinis si this._converter existe (cf constructeur)
2021-10-07 17:15:35 +02:00
for ( let row of this . _converter . datas )
2021-09-17 18:02:45 +02:00
{
if ( this . _separator === undefined )
{
2021-10-07 17:15:35 +02:00
if ( row [ this . name ] !== "" && this . values . indexOf ( row [ this . name ] ) === - 1 )
this . values . push ( row [ this . name ] ) ;
2021-09-17 18:02:45 +02:00
}
else
{
2021-10-07 17:15:35 +02:00
let checkedValues = row [ this . name ] . split ( this . _separator ) ;
for ( let value of checkedValues )
2021-09-17 18:02:45 +02:00
{
2021-10-07 17:15:35 +02:00
if ( value !== "" && this . values . indexOf ( value ) === - 1 )
this . values . push ( value ) ;
2021-09-17 18:02:45 +02:00
}
}
}
if ( this . values . length > 0 )
{
2021-10-07 17:15:35 +02:00
// Classement des données à l'aide (ou non) d'une fonction spécifique :
2021-09-17 18:02:45 +02:00
if ( this . _converter . getSortingFunctionForField ( this . _datasFieldNb ) !== undefined )
2021-10-07 17:15:35 +02:00
this . values . sort ( this . _converter . getSortingFunctionForField ( this . _datasFieldNb ) ! . sort ) ; // sans le "!" : TS2532: Object is possibly 'undefined' ??
2021-09-17 18:02:45 +02:00
else
this . values . sort ( compare ( ) ) ;
2021-10-07 17:15:35 +02:00
// Création et injection du SELECT dans le DOM
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 d'actualiser l'affichage en ignorant ce filtre
for ( let i = 0 ; i < this . values . length ; i ++ )
selectorsHTML += "<option value='" + ( i + 1 ) + "'>" + this . values [ i ] + "</option>" ;
2021-09-17 18:02:45 +02:00
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
2021-10-07 17:15:35 +02:00
if ( data [ this . name ] === undefined ) // champ absent pour cet enregistrement, qui est donc refusé
2021-09-20 11:09:30 +02:00
return false ;
2021-09-17 18:02:45 +02:00
const selectedValueTxt = this . values [ selectedValue ] ;
if ( this . _separator === undefined )
{
2021-10-07 12:43:29 +02:00
if ( data [ this . name ] !== selectedValueTxt )
2021-09-17 18:02:45 +02:00
return false ;
else
return true ;
}
else
{
let find = false ;
2021-10-07 17:15:35 +02:00
let checkedValues = data [ this . name ] . split ( this . _separator ) ;
for ( let value of checkedValues )
2021-09-17 18:02:45 +02:00
{
2021-10-07 17:15:35 +02:00
if ( value === selectedValueTxt )
2021-09-17 18:02:45 +02:00
{
find = true ;
break ;
}
}
return find ;
}
}
}