diff --git a/src/app/components/field-set/field-set.component.ts b/src/app/components/field-set/field-set.component.ts
index 391966eba56243aaaf92a2467215ea2190e3c7ae..0594d7767c6cc9b5597c292ffd0a7b037b4cf0c5 100644
--- a/src/app/components/field-set/field-set.component.ts
+++ b/src/app/components/field-set/field-set.component.ts
@@ -1,11 +1,10 @@
-import { Component, Input, Output, EventEmitter, ViewChildren, QueryList } from "@angular/core";
+import { Component, Input, Output, EventEmitter, ViewChildren, QueryList, DoCheck } from "@angular/core";
 
 import { ParamDefinition } from "jalhyd";
 
 import { NgParameter, ParamRadioConfig } from "../../formulaire/ngparam";
 import { FieldSet } from "../../formulaire/fieldset";
 import { ParamFieldLineComponent } from "../param-field-line/param-field-line.component";
-import { BaseComponent } from "../base/base.component";
 import { SelectEntry } from "../../formulaire/select-entry";
 import { Field } from "../../formulaire/field";
 import { InputField } from "../../formulaire/input-field";
@@ -26,7 +25,7 @@ import { CheckField } from "../../formulaire/check-field";
         }`
     ]
 })
-export class FieldSetComponent extends BaseComponent {
+export class FieldSetComponent implements DoCheck {
     /**
     * field set attribute
     */
@@ -44,7 +43,7 @@ export class FieldSetComponent extends BaseComponent {
      * événément de changement de validité
      */
     @Output()
-    private onValid = new EventEmitter();
+    private validChange = new EventEmitter();
 
     /**
      * flag de validité de la saisie
@@ -152,6 +151,8 @@ export class FieldSetComponent extends BaseComponent {
      * calcul de la validité de tous les ParamFieldLineComponent de la vue
      */
     private updateValidity() {
+        this._isValid = false;
+
         if (this._paramComponents != undefined)
             this._isValid = this._paramComponents.reduce(
                 // callback
@@ -169,9 +170,11 @@ export class FieldSetComponent extends BaseComponent {
                 }
                 // valeur initiale
                 , true);
+
+        this.validChange.emit();
     }
 
-    protected afterFirstViewChecked() {
+    public ngDoCheck() {
         this.updateValidity();
     }
 
@@ -180,7 +183,6 @@ export class FieldSetComponent extends BaseComponent {
      */
     private onParamLineValid(event: boolean) {
         this.updateValidity();
-        this.onValid.emit();
     }
 
     /**
diff --git a/src/app/components/fieldset-container/fieldset-container.component.html b/src/app/components/fieldset-container/fieldset-container.component.html
index 81bbc3f36742dcfa01f9be0c15f3a99bd5aeadde..ad35465953f2001a197494e447a72d15ff6cdfa8 100644
--- a/src/app/components/fieldset-container/fieldset-container.component.html
+++ b/src/app/components/fieldset-container/fieldset-container.component.html
@@ -6,6 +6,7 @@
         <!-- bouton d'ajout d'un ouvrage -->
         <button type="button" class="btn btn-grey waves-light" mdbRippleRadius (click)="addStructure()">Ajouter un ouvrage</button>
     </div>
-    <field-set *ngFor="let fs of fieldsets" [fieldSet]=fs (selectChange)=onSelectChanged($event) (onRadio)=onRadioClick($event)>
+    <field-set *ngFor="let fs of fieldsets" [fieldSet]=fs (selectChange)=onSelectChanged($event) (onRadio)=onRadioClick($event)
+        (onValid)=onFieldsetValid()>
     </field-set>
 </div>
\ No newline at end of file
diff --git a/src/app/components/fieldset-container/fieldset-container.component.ts b/src/app/components/fieldset-container/fieldset-container.component.ts
index 240513653ab32aa79367709847bc42e7676bcd41..e2da23746b7f5597f247edc93573bccff8d42eb9 100644
--- a/src/app/components/fieldset-container/fieldset-container.component.ts
+++ b/src/app/components/fieldset-container/fieldset-container.component.ts
@@ -1,13 +1,15 @@
-import { Component, Input, Output, EventEmitter } from "@angular/core";
+import { Component, Input, Output, EventEmitter, QueryList, ViewChildren, DoCheck } from "@angular/core";
 
 import { FieldsetContainer } from "../../formulaire/fieldset-container";
 import { SelectEntry } from "../../formulaire/select-entry";
+import { FieldSet } from "../../formulaire/fieldset";
+import { FieldSetComponent } from "../field-set/field-set.component";
 
 @Component({
     selector: "fieldset-container",
     templateUrl: "./fieldset-container.component.html"
 })
-export class FieldsetContainerComponent {
+export class FieldsetContainerComponent implements DoCheck {
     @Input("container")
     private _container: FieldsetContainer;
 
@@ -17,6 +19,17 @@ export class FieldsetContainerComponent {
     @Output()
     private selectChange = new EventEmitter<SelectEntry>();
 
+    /**
+     * liste des composants FieldSet enfants
+     */
+    @ViewChildren(FieldSetComponent)
+    private _fieldsetComponents: QueryList<FieldSetComponent>;
+
+    /**
+     * flag de validité des FieldSet enfants
+     */
+    private _isValid: boolean = false;
+
     private get title(): string {
         if (this._container == undefined)
             return undefined;
@@ -53,4 +66,52 @@ export class FieldsetContainerComponent {
      */
     @Output()
     private onRadio = new EventEmitter<any>();
+
+    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)
+                    fielset,
+                    // currentIndex (indice courant dans le tableau)
+                    currIndex,
+                    // array (tableau parcouru)
+                    array
+                ) => {
+                    return acc && fielset.isValid;
+                }
+                // valeur initiale
+                , this._fieldsetComponents.length > 0);
+
+        this.validChange.emit();
+    }
+
+    public get isValid() {
+        return this._isValid;
+    }
+
+    /**
+     * événément de changement de validité
+     */
+    @Output()
+    private validChange = new EventEmitter();
+
+    /**
+     * réception d'un événement de validité de FieldSet
+     */
+    private onFieldsetValid() {
+        this.updateValidity();
+    }
 }
\ No newline at end of file
diff --git a/src/app/components/generic-calculator/calculator.component.html b/src/app/components/generic-calculator/calculator.component.html
index 1a379046433c8b4e53f81253e89843c47f745543..5d8e836580d6155bf467a002b35c0fa1c7c9b443 100644
--- a/src/app/components/generic-calculator/calculator.component.html
+++ b/src/app/components/generic-calculator/calculator.component.html
@@ -24,9 +24,10 @@
             <!-- chapitres -->
             <ng-template ngFor let-fe [ngForOf]="formElements">
                 <field-set *ngIf="isFieldset(fe)" [style.display]="getFieldsetStyleDisplay(fe.id)" [fieldSet]=fe (onRadio)=onRadioClick($event)
-                    (selectChange)=onSelectChanged($event) (onValid)=OnFieldsetValid()></field-set>
+                    (selectChange)=onSelectChanged($event) (validChange)=OnFieldsetValid()></field-set>
 
-                <fieldset-container *ngIf="isFieldsetContainer(fe)" [container]=fe (selectChange)=onSelectChanged($event) (onRadio)=onRadioClick($event)></fieldset-container>
+                <fieldset-container *ngIf="isFieldsetContainer(fe)" [container]=fe (selectChange)=onSelectChanged($event) (onRadio)=onRadioClick($event)
+                    (validChange)=onFieldsetContainerValid()></fieldset-container>
             </ng-template>
         </div>
 
@@ -67,4 +68,4 @@
             </div>
         </div>
     </div>
-</div>
+</div>
\ No newline at end of file
diff --git a/src/app/components/generic-calculator/calculator.component.ts b/src/app/components/generic-calculator/calculator.component.ts
index fcb732cbcfcea47faadc3adc03aa7aee32f8f7c0..f69d1cb95d015e88ba7b6b19dbd5136633791784 100644
--- a/src/app/components/generic-calculator/calculator.component.ts
+++ b/src/app/components/generic-calculator/calculator.component.ts
@@ -14,6 +14,7 @@ import { CalculatorNameComponent } from "./calc-name.component";
 import { SelectEntry } from "../../formulaire/select-entry";
 import { FormulaireElement } from "../../formulaire/formulaire-element";
 import { FieldsetContainer } from "../../formulaire/fieldset-container";
+import { FieldsetContainerComponent } from "../fieldset-container/fieldset-container.component";
 
 @Component({
     selector: 'hydrocalc',
@@ -43,6 +44,12 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
     @ViewChildren(FieldSetComponent)
     private _fieldsetComponents: QueryList<FieldSetComponent>;
 
+    /**
+     * liste des FieldsetContainerComponent
+     */
+    @ViewChildren(FieldsetContainerComponent)
+    private _fieldsetContainerComponents: QueryList<FieldsetContainerComponent>;
+
     /**
      * composant d'affichage des résultats
      */
@@ -268,6 +275,8 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
      * calcul de la validité globale de la vue
      */
     private updateUIValidity() {
+        this._isUIValid = false;
+
         if (this._fieldsetComponents != undefined)
             this._isUIValid = this._fieldsetComponents.reduce(
                 // callback
@@ -284,6 +293,24 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
                     return acc && fieldset.isValid;
                 }
                 // valeur initiale
+                , this._fieldsetComponents.length > 0);
+
+        if (this._fieldsetContainerComponents != undefined)
+            this._isUIValid = this._isUIValid && this._fieldsetContainerComponents.reduce(
+                // callback
+                (
+                    // accumulator (valeur précédente du résultat)
+                    acc,
+                    // currentValue (élément courant dans le tableau)
+                    fieldsetContainer,
+                    // currentIndex (indice courant dans le tableau)
+                    currIndex,
+                    // array (tableau parcouru)
+                    array
+                ) => {
+                    return acc && fieldsetContainer.isValid;
+                }
+                // valeur initiale
                 , true);
     }
 
@@ -293,4 +320,11 @@ export class GenericCalculatorComponent extends BaseComponent implements OnInit,
     private OnFieldsetValid() {
         this.updateUIValidity();
     }
+
+    /**
+     * réception d'un événement de validité d'un FieldsetContainerComponent
+     */
+    private onFieldsetContainerValid() {
+        this.updateUIValidity();
+    }
 }