Forked from Cresson Remi / otbtf
Source project has a limited visibility.
param-input.component.ts 6.92 KiB
// cf. https://blog.thoughtram.io/angular/2016/07/27/custom-form-controls-in-angular-2.html
import { Component, Input, forwardRef, OnInit, DoCheck, ChangeDetectorRef } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR, NG_VALIDATORS, FormControl } from '@angular/forms';
import { ComputeNodeType, ParamDefinition, NumericalString, Message } from 'jalhyd';
import { ParamService } from '../../services/param/param.service';
import { InternationalisationService, LanguageCode } from '../../services/internationalisation/internationalisation.service';
import { NgParameter } from '../../calculators/generic/ngparam';
@Component({
    selector: 'param-input',
    /* OK
    <input placeholder="{{_paramDef.symbol}}" [ngModel]="_paramDef.v" (ngModelChange)="setValue($event)"/>
    <p *ngIf="_message">{{_message}}</p>
    templateUrl: "./param-input.component.html",
    providers: [
            provide: NG_VALUE_ACCESSOR,
            useExisting: forwardRef(() => ParamInputComponent),
            multi: true
            provide: NG_VALIDATORS,
            useExisting: forwardRef(() => ParamInputComponent),
            multi: true
export class ParamInputComponent implements ControlValueAccessor, OnInit, DoCheck {
    /**
     * type de noeud de calcul
    private _computeNode: ComputeNodeType;
    @Input()
    private set computeNodeType(t: ComputeNodeType) {
        this._computeNode = t;
    /**
     * Parameter symbol (Q, Ks, B, ...) attribute
    @Input('symbol')
    private _paramSymbol: string;
    /**
     * enable/disable input field
    @Input('inputDisabled')
    private _inputDisabled: boolean;
    /**
     * managed parameter
    private _paramDef: NgParameter;
    private _message: string;
    /**
     * flag d'affichage du titre
    public displayTitle: boolean = false;
    /**
     * true si la modification du paramètre géré vient de l'interface utilisateur
     * false si la modification du paramètre géré vient d'un appel du code
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
*/ private _fromUI: boolean; /** * valeur dans le contrôle (saisie par l'utilisateur) */ private _uiValue: NumericalString; constructor(private paramService: ParamService, private changeDetector: ChangeDetectorRef, private intlService: InternationalisationService) { this._uiValue = new NumericalString(); } hasError(): boolean { let res = (this._message != undefined); // if (res) // this.log("hasError : true " + this._message); // else // this.log("hasError : false"); return res; } private getSfromUI(): string { return this._fromUI ? " fromUI " : " fromMODEL"; } private getSParam(): string { return " " + this._paramDef.symbol + "=" + this._paramDef.toString() } private getSUIvalue(v: NumericalString = undefined): string { if (v == undefined) return " uiValue=" + this._uiValue.toString() + ""; return " uiValue=" + v.toString() + ""; } ngOnInit() { // retrieve parameter from symbol this._paramDef = this.paramService.getParameter(this._computeNode, this._paramSymbol); } /** * fonction appelée lorsque l'utilisateur fait une saisie * @param event valeur du contrôle */ private setValue(event: any) { this._fromUI = true; this._uiValue.value = event; // this.log(this._uiValue.toString()); return this.validateUIValue(); } /** * fonction appelée lors d'un rafraîchissement de l'UI */ ngDoCheck(): void { // this.log("ngDoCheck start : " + this.getSParam() + this.getSUIvalue() + this.getSfromUI()); if (this._fromUI) this.updateMessage(this._uiValue); else { if (this._paramDef.isDefined) { this.updateMessage(new NumericalString(this._paramDef.getValue())); this._uiValue.value = String(this._paramDef.getValue()); } else this.updateMessage(this._uiValue); } // this.log("ngDoCheck end : " + this.getSParam() + this.getSUIvalue());
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
this._fromUI = false; } private updateMessage(v: NumericalString) { // this.log("updateMessage start :" + this.getSParam() + this.getSfromUI() + this.getSUIvalue(v) + " message=" + this._message); if (v.isNumerical) { this._message = undefined; try { this._paramDef.checkValue(v.numericalValue); } catch (e) { if (e instanceof Message) this._message = this.intlService.localizeMessage(e); else this._message = "invalid value"; } } else { switch (this.intlService.currentLanguage.code) { case LanguageCode.FRENCH: this._message = "Veuillez entrer une valeur numérique"; break; default: this._message = "Please enter a numerical value"; } } // this.log("updateMessage end :" + this.getSParam() + this.getSfromUI() + this.getSUIvalue(v) + " message=" + this._message); } private validateUIValue() { // this.log(""); // this.log("validateValue start : val '" + this._uiValue.toString() + "'" + this.getSParam() + this.getSfromUI()); let ok: boolean = this._uiValue.isNumerical; if (ok) { try { if (!this._paramDef.isDefined || this._paramDef.getValue() != this._uiValue.numericalValue) { this._paramDef.setValue(this._uiValue.numericalValue); this.changeDetector.detectChanges(); // provoque une détection des changements dans les contrôles } } catch (e) { ok = false; } } if (!ok) { // this.log("validateValue end : " + this.getSParam()); let err = { rangeError: { // given: val, given: this._uiValue.toString(), max: 4, min: 0 } }; return err; } // this.log("validateValue end : " + this.getSParam()); return null; } // private log(m: string) {
211212213214215216217218219220221222223224225226227228229230231232233234235236
// console.log("ParamInputComponent(" + this._id + ") : " + m); // } // ControlValueAccessor interface propagateChange = (_: any) => { }; /* //From ControlValueAccessor interface writeValue(value: any) { if (value !== this.innerValue) { this.innerValue = value; } } */ writeValue(value: any) { // this.log("writeValue " + value); } registerOnChange(fn: any) { this.propagateChange = fn; } registerOnTouched() { } }