IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Angular Discussion :

Charger l' événement avec un formulaire imbriqué


Sujet :

Angular

  1. #1
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2008
    Messages
    1 191
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 1 191
    Points : 595
    Points
    595
    Par défaut Charger l' événement avec un formulaire imbriqué
    Bonjour ,

    j'ai un composant qui possède 2 imbrications de formulaires FGmatière et FGpblk qui englobe un formGroupe:

    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <form [formGroup]="imbriqueForm" (ngSubmit)="submit()">
        <app-form-matiere formControlName="FGmatiere" ></app-form-matiere>
        <app-form-pblk formControlName="FGpblk" ></app-form-pblk>
        <button>Valider</button>
        <button type="button" (click)="resetForm()">Reset</button>
    </form>

    FGmatière sélectionne plusieurs options, c'est une liste déroulante à choisir entre plusieurs matière:
    FGpblk sélectionne plusieurs options, c'est une liste déroulante de choix de catégorie qui dépend du choix de la matière,
    par exemple si je sélectionne informatique, on doit me proposer la catégorie programmation, réseau ou infographie,
    si je sélectionne francais, on doit me proposer la catégorie français,anglais,italien.

    Je recherche donc à récupérer la valeur des catégories en fonction de la première liste choisi.
    Quel serais le mécanisme pour faire transités l'information entre ces 3 composantes ?

    - 1 composant du formulaire affiche le formulaire
    - 2 composant matière qui récupère les matières disponible
    - 3 composant catégorie qui récupère les les catégorie disponible

    voici à quoi ressemble ma composante matiere:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    import { Component, forwardRef, OnDestroy, ChangeDetectionStrategy } from '@angular/core';
    import { ControlValueAccessor, NG_VALUE_ACCESSOR, FormBuilder, FormGroup, Validators, FormControl, NG_VALIDATORS } from '@angular/forms';
    import { Subscription } from 'rxjs';
    import { Router } from '@angular/router';
    import { AuthenticationService } from 'src/services/authentification.service';
    import { HttpClient, HttpHeaders } from '@angular/common/http';
    import { NavigationService } from 'src/services/navigation.service';
     
    @Component({
      selector: 'app-form-matiere',
      templateUrl: './form-matiere.component.html',
      styleUrls: ['./form-matiere.component.less'],
      providers: [
        {
          provide: NG_VALUE_ACCESSOR,
          useExisting: forwardRef(() => FormMatiereComponent),
          multi: true
        },
        {
          provide: NG_VALIDATORS,
          useExisting: forwardRef(() => FormMatiereComponent),
          multi: true,
        }
      ],
      changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class FormMatiereComponent implements ControlValueAccessor, OnDestroy {
      FGmatiere: FormGroup;
      subscriptions: Subscription[] = [];
      public titre = "Ajouter une nouvelle matière";
      private idSommaireSelected: number;
      public allowSelectedCatego = false;
     
      public televerser = false;
      public menu_hz = JSON.parse(localStorage.getItem("menu_hz"));
      public category;
      public recupIdMongo;
      private matiere;
      public cacheWait = true;
     
      constructor(
        private formBuilder: FormBuilder, private router: Router, public authService: AuthenticationService, private http: HttpClient, private navService: NavigationService
      ) {
     
        this.FGmatiere = this.formBuilder.group({
          listMenuSelected: ['', Validators.required],
        });
     
        this.subscriptions.push(
          this.FGmatiere.valueChanges.subscribe(value => {
            this.onChange(value);
            this.onTouched();
          })
        );
      }
     
      /**uniquement matiere */
      changeIdSommaire(event) {
        this.cacheWait = false;
        if (event.isUserInput) {
          //let urlSommaire = event.source.value._links.self.href;
          this.idSommaireSelected = parseInt(event.source.id.split('-')[2], 10);
          this.idSommaireSelected = this.idSommaireSelected + 1// +1 car on commence à 1
          this.FGmatiere.controls['listMenuSelected'].setValue(this.idSommaireSelected);
         // console.log(JSON.stringify(this.idSommaireSelected));
          localStorage.setItem('listMenuSelected',JSON.stringify(this.idSommaireSelected));
        }
      }
     
      get value() {
     
        return this.FGmatiere.value;
      }
     
      set value(value) {
        this.FGmatiere.setValue(value);
        this.onChange(value);
        this.onTouched();
      }
     
     
     
     
     
      ngOnDestroy() {
        this.subscriptions.forEach(s => s.unsubscribe());
      }
     
      onChange: any = () => { };
      onTouched: any = () => { };
     
     
      registerOnChange(fn) {
     
        this.onChange = fn;
      }
     
      writeValue(value) {
        if (value) {
          this.FGmatiere = value;
        }
     
        if (value === null) {
          this.FGmatiere.reset();
        }
      }
     
      registerOnTouched(fn) {
        this.onTouched = fn;
      }
     
      validate(_: FormControl) {
     
        console.log(this.FGmatiere.valid);
        return this.FGmatiere.valid ? null : { imbriqueForm: { valid: false, }, };
      }
    }
    j'ai tenté de mettre un évement change dans la balise app-form-matiere mais cela ne fonctionne pas, quand je sélectionne la liste
    des matières , je n'ai aucun événement .

    pour le moment ce n'est qu'au niveau du composant formulaire que je puisse récupérer quel "options" j'ai choisi.

    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    <app-form-matiere formControlName="FGmatiere"  change="ldListeMatiere()"></app-form-matiere>

    mon raisonnement étais de dire que je change une matière, je pourrais alors charger la liste des catégories dans la listes les options catégories tout en restant à l'intérieur du composant qui possède le formGroup

    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <h1>Ajouter une nouvelle publication :</h1>
    <form [formGroup]="imbriqueForm" (ngSubmit)="submit()">
        <app-form-matiere formControlName="FGmatiere"  change="ldListeMatiere()"></app-form-matiere>
        <app-form-pblk formControlName="FGpblk"  *ngIf="category"></app-form-pblk>
        <button>Valider</button>
        <button type="button" (click)="resetForm()">Reset</button>
    </form>
     
    <p>
        Form is {{imbriqueForm.valid ? 'Valid' : 'Invalid'}}
    </p>
     
    <pre>
          {{imbriqueForm.value | json}}
    </pre>

    Merci d'avance de vos réponses, si vous avez déjà tenter d'implémenter cela

    EDIT solution :

    j'ai utiliser les décoration @output pour traverser les composants, je pensais qu'on pourrais utiliser autre chose comme les accessors des formulaires déjà mis en place ...

  2. #2
    Membre confirmé

    Profil pro
    Inscrit en
    Août 2008
    Messages
    1 191
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 1 191
    Points : 595
    Points
    595
    Par défaut
    Je suis arrivé à construire mes 2 formulaire imbriqué mais j'ai un autre problème de chargement de la liste du deuxième formulaire FGpblk.

    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    <form [formGroup]="imbriqueForm" (ngSubmit)="submit()">
        <app-form-matiere 
            formControlName="FGmatiere" 
            (sendRecord)="getRecord($event)">
        </app-form-matiere>
        <app-form-pblk 
            formControlName="FGpblk" 
            (sendRecordPblk)="getRecordPblk($event)">
        </app-form-pblk>

    FGpblk est liste déroulante à sélectionner, mais je n'arrive pas à initialiser correctement.
    Pour pouvoir choisir une option FGpblk(ce champs est caché,il doit apparaître une fois qu'on à selectionner FGmatiere) ,
    mais au démarrage de la page j'ai l'erreur de console de la valeur des listes à afficher, ce qui est normal puisqu'il ne la connais pas encore


    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    <mat-select  [formGroup]="FGpblk" placeholder="ajouter dans quelle matière ?">
      <mat-option  formControlName="listMatiereSelected" (onSelectionChange)="changeCategoMatiere($event)"
    *ngIf="category"
        *ngFor="let catego of category._embedded.bookodMatieres" [value]="catego">
        {{catego.route}}
      </mat-option>
    </mat-select>

    ici category est à null

    j'ai donc essayé d'ajouter un ngIf mais j'ai cette erreur:
    compiler.js:2175 Uncaught Error: Template parse errors:
    Can't have multiple template bindings on one element. Use only one attribute prefixed with * ("tegory" formControlName="listMatiereSelected" (onSelectionChange)="changeCategoMatiere($event)"
    [ERROR ->]*ngFor="let catego of category._embedded.bookodMatieres"
    je me suis dit si cela ne fonctionne sur le formulaire , je l'applique sur le formGroup imbriqueFrom

    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <h1>Ajouter une nouvelle publication :</h1>
    <form [formGroup]="imbriqueForm" (ngSubmit)="submit()">
        <app-form-matiere 
            formControlName="FGmatiere" 
            (sendRecord)="getRecord($event)">
        </app-form-matiere>
        <app-form-pblk 
            *ngIf="idSommaireSelected"
            formControlName="FGpblk" 
            (sendRecordPblk)="getRecordPblk($event)">
        </app-form-pblk>

    mais j'ai toujours le même souci, en plus il freeze (je ne peux pas selectionner une matiere) lorsque je sélectionne le formulaire FGmatiere.
    Comment je dois initialiser correctement mes 2 formulaires ?

    si vous avez une idée merci de la réponse ou un exemple à télécharger.

Discussions similaires

  1. [3.x] Problème avec un formulaire imbriqué
    Par vodkline dans le forum Symfony
    Réponses: 2
    Dernier message: 25/05/2018, 10h42
  2. Réponses: 7
    Dernier message: 11/03/2013, 22h34
  3. FORMULAIRE avec 2 foreach imbriquer
    Par kate59 dans le forum PHP & Base de données
    Réponses: 24
    Dernier message: 03/08/2011, 14h50
  4. problème avec un formulaire et événement Windows Media Player
    Par tomguiss dans le forum Balisage (X)HTML et validation W3C
    Réponses: 0
    Dernier message: 03/11/2009, 19h21
  5. Changer l'image d'un formulaire avec un click..
    Par dsolheid dans le forum IHM
    Réponses: 2
    Dernier message: 11/12/2007, 19h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo