import { Component, Input, Output, EventEmitter, QueryList, ViewChildren, DoCheck, AfterViewInit } from "@angular/core"; import { FieldsetContainer } from "../../formulaire/fieldset-container"; import { FieldSetComponent } from "../field-set/field-set.component"; import { FieldSet } from "../../formulaire/fieldset"; import { FormulaireDefinition } from "../../formulaire/definition/form-definition"; @Component({ selector: "fieldset-container", templateUrl: "./fieldset-container.component.html", styleUrls: [ "./fieldset-container.component.scss" ] }) export class FieldsetContainerComponent implements DoCheck, AfterViewInit { public get title(): string { if (this._container) { return this._container.label; } } public get fieldsets() { return this._container.fieldsets; } public get isValid() { return this._isValid; } @Input() private _container: FieldsetContainer; /** * liste des composants FieldSet enfants */ @ViewChildren(FieldSetComponent) private _fieldsetComponents: QueryList<FieldSetComponent>; /** * flag de validité des FieldSet enfants */ private _isValid = false; /** * événément de changement d'état d'un radio */ // tslint:disable-next-line:no-output-on-prefix @Output() private radio = new EventEmitter<any>(); /** * événément de changement de validité */ @Output() private validChange = new EventEmitter(); /** * événément de changement de valeur d'un input */ @Output() private inputChange = new EventEmitter(); /** événement signalant un appui sur TAB ou SHIFT+TAB */ @Output() protected tabPressed = new EventEmitter<any>(); private addStructure(after?: FieldSet) { if (after) { this._container.addFromTemplate(0, after.indexAsKid()); } else { this._container.addFromTemplate(0); } } private onFieldsetListChange() { // affichage des boutons ajouter, supprimer, monter, descendre this._fieldsetComponents.forEach(fs => fs.showButtons = true); // désactivation du bouton supprimer s'il n'en reste qu'un if (this._fieldsetComponents.length === 1) { const fs = this._fieldsetComponents.last as FieldSetComponent; fs.enableRemoveButton = false; } else { this._fieldsetComponents.forEach(fs => fs.enableRemoveButton = true); } // désactivation du bouton monter pour le 1er this._fieldsetComponents.forEach(fs => { fs.enableUpButton = true; fs.enableDownButton = true; }); this._fieldsetComponents.first.enableUpButton = false; // désactivation du bouton monter pour le dernier this._fieldsetComponents.last.enableDownButton = false; // renumérotation let n = 1; this._fieldsetComponents.forEach(fsc => { fsc.fieldsetNumber = n; n++; } ); } public ngAfterViewInit() { this.onFieldsetListChange(); this._fieldsetComponents.changes.subscribe(_ => this.onFieldsetListChange()); } /* * gestion des événements clic sur les radios : * réception d'un message du composant enfant (field-set) * cf. https://angular.io/guide/component-interaction#parent-listens-for-child-event */ private onRadioClick(info: any) { // on renvoie l'info au parent this.radio.emit(info); } public ngDoCheck() { this.updateValidity(); } /** * calcul de la validité de tous les FieldSet de la vue */ private updateValidity() { this._isValid = false; if (this._fieldsetComponents !== undefined) { this._isValid = this._fieldsetComponents.reduce( // callback ( // accumulator (valeur précédente du résultat) acc, // currentValue (élément courant dans le tableau) fieldset, // currentIndex (indice courant dans le tableau) currIndex, // array (tableau parcouru) array ) => { return acc && fieldset.isValid; } // valeur initiale , this._fieldsetComponents.length > 0); } this.validChange.emit(); } /** * réception d'un événement de validité de FieldSet */ private onFieldsetValid() { this.updateValidity(); } /** * réception d'un événement de changement de valeur d'un input */ private onInputChange(event: boolean) { this.inputChange.emit(); } /** * relit les valeurs dans l'interface et met à jour les NgParameter */ public updateParametersFromUI() { this._fieldsetComponents.forEach(fsc => fsc.updateParametersFromUI()); } /** * met à jour les paramètres liés */ public updateLinkedParameters() { this._fieldsetComponents.forEach(fsc => fsc.updateLinkedParameters()); } /** * réception d'un événement de demande d'ajout d'un FieldSet */ private onAddFieldset(fs: FieldSet) { this.addStructure(fs); } /** * réception d'un événement de demande de suppression d'un FieldSet */ private onRemoveFieldset(fs: FieldSet) { const form = this._container.parent as FormulaireDefinition; form.removeFieldset(fs); } /** * réception d'un événement de demande de remontée d'un FieldSet */ private onMoveFieldsetUp(fs: FieldSet) { const form = this._container.parent as FormulaireDefinition; form.moveFieldsetUp(fs); } /** * réception d'un événement de demande de descente d'un FieldSet */ private onMoveFieldsetDown(fs: FieldSet) { const form = this._container.parent as FormulaireDefinition; form.moveFieldsetDown(fs); } /** * Renvoie l'événement au composant du dessus */ public onTabPressed(event) { this.tabPressed.emit(event); } }