Fermer

juillet 22, 2021

Créer des formulaires dynamiques à l'aide de FormArray Angular


Cet article explique étape par étape comment créer un formulaire dynamique dans Angular. Il couvre toutes les classes essentielles d'un formulaire réactif et explique comment la classe FormArray peut être utilisée pour créer un formulaire dynamique.

Avez-vous déjà réservé des billets de cinéma en ligne ? Si oui, alors vous avez utilisé un formulaire dynamique. Par exemple, vous sélectionnez le nombre de billets dans une liste déroulante, puis l'application vous demande de saisir des informations, telles que le nom et l'âge, autant de fois que le nombre de billets sélectionnés. Étant donné que le nombre de cinéphiles n'est pas fixe et peut être modifié au moment de l'exécution par l'utilisateur, un formulaire dynamique est nécessaire pour recueillir les informations des cinéphiles.

Dans cet article, vous apprendrez à créer un formulaire dynamique dans Angular. et écoutez également une explication de haut niveau d'autres classes utiles de Formes réactives angulaires. Si vous n'êtes ici que pour en savoir plus sur les formulaires dynamiques, vous pouvez accéder directement à la section dynamic form.

Reactive Forms

Angular fournit deux types de formulaires :

  • Gestionnaire de modèles formulaires
  • Formulaires réactifs

Les formulaires réactifs sont plus adaptés pour créer un formulaire dynamique. Alors, commençons par apprendre les classes importantes qui constituent un formulaire réactif.

Configuration du projet

Pour travailler avec des formulaires réactifs, vous devez ajouter ReactiveFormsModule dans le tableau imports de l'AppModule .

import { BrowserModule } de '@angular/platform-browser';
import { NgModule } de '@angular/core';
import {ReactiveFormsModule} de '@angular/forms'[19659015];

import { AppComponent } from './app.component';

@NgModule({
  déclarations : [
    AppComponent
  ],
  importations : [
    BrowserModule,ReactiveFormsModule
  ],
  fournisseurs : [],
  bootstrap : [AppComponent]
})
export class AppModule { }

Après cela , importez les classes liées à la fiche réactive dans le composant qui va contenir la fiche.

import {FormControl,
         Groupe de formulaires,
         FormBuilder,
         Tableau de formulaire,
         Validators} from '@angular/forms';

Un formulaire contient des contrôles HTML tels que la saisie, le bouton radio, la liste déroulante, etc. Les formulaires réactifs ont le FormControl classe qui représente un contrôle individuel. Vous pouvez l'utiliser pour créer un contrôle comme indiqué dans la liste de code suivante :

email: FormControl;
  ngOnInit(){[19659060]ce.e-mail = nouveau FormControl("",Validateurs.requis );
  }

Dans le modèle, vous pouvez utiliser le contrôle des e-mails comme indiqué ci-dessous.

<input [formControl]='email'[19659073]type="text" placeholder="Entrez l'e-mail" />[19659080]{{email.valeur | json}}

Maintenant, exécutez l'application et vous devriez voir une zone de texte de saisie qui accepte une valeur de courrier électronique.

Classes pour créer un formulaire réactif

La classe FormArray est utilisée pour créer une forme dynamique. Mais avant cela, explorons d'autres classes essentielles qui constituent une forme réactive. Ce sont :

  • FormControl
  • FormGroup
  • Validators

Vous avez déjà vu la classe FormControl qui crée un seul contrôle. Une classe FormControl prend trois paramètres d'entrée :

  • Valeur de données initiale, y compris null
  • Facultatif, un tableau de validateurs synchrones
  • Facultatif, un tableau de validateurs asynchrones

Vous pouvez créer un FormControl avec la valeur initiale et obligatoire validation comme indiqué dans la liste de code suivante :

 emailControl : FormControl;
  defaultLogin = {
    email :'debugmode@outlook.com',
    mot de passe:'282828282'
  };

  ngOnInit(){
    this.emailControl  = nouveau FormControl(this.defaultLogin.email,[Validators.required]);
  }

Dans les formulaires réactifs, la prochaine classe importante est FormGroupqui est simplement un groupe de FormControls. Vous pouvez placer de nombreux FormControls dans un FormGroup pour créer un formulaire à part entière. Une classe FormGroup correspond à un formulaire HTML et la classe FormControl correspond à un contrôle individuel à l'intérieur du formulaire.

Un FormGroup avec deux contrôles, email et téléphone, peut être créé comme indiqué dans la liste de code suivante :

 buyTicketForm: FormGroup;
  ngOnInit() {
    this.buyTicketForm = nouveau FormGroup (
      {
        emailControl : nouveau FormControl(null, [Validators.requis])[19659015],
        phoneControl: new FormControl(null)
      }
    )
  }

Dans le modèle du composant, vous pouvez le lier à formulaire et contrôles comme indiqué ci-dessous.

 <form [formGroup]='buyTicketForm' novalidate class=[19659015]"form" (ngSubmit)='buyTickets()'>
 <input formControlName='emailControl' type="text" class ="form-control" placeholder="Entrez l'e-mail" />
  <input formControlName='phoneControl' type=" text" class="form-control" placeholder="Entrez le téléphone " />
 <bouton class="btn btn-info"> Envoyer</bouton>
 </form>

Dans le formulaire ci-dessus, il y a un bouton pour soumettre la valeur du formulaire. Lorsque l'utilisateur clique sur le bouton de soumission, la fonction buyTickets() est exécutée.

 buyTickets() {

    if(this.buyTicketForm.statut ==[19659014]'VALIDE'){
      console.log(this.buyTicketForm.value);
    }
  }[19659048] Ainsi, vous utilisez la classe FormGroup pour encapsuler divers objets FormControl, des objets FormArray, ainsi que des objets  imbriqués FormGroup. Vous pouvez ajouter un FormGroup imbriqué dans le buyTicketForm comme indiqué dans la liste de codes suivante :

buyTicketForm: FormGroup;
  ngOnInit() {[19659060]ce.buyTicketForm = nouveau FormGroup(
      {
        emailControl : nouveau FormControl(null, [Validators.requis])[19659015],
        phoneControl: nouveau FormControl(null),
        adresse:nouveau Form Group({
          streetControl : nouveau FormControl(),
          postalcodeControl: new FormControl()
        })
      }
    )
  }

Et dans le modèle, vous peut mapper l'adresse du champ FormGroup imbriqué en définissant la propriété formGroupName du formulaire imbriqué comme indiqué ci-dessous.

 <form [formGroup]='buyTicketForm' novalidate class=[19659015]"form" (ngSubmit)='buyTickets()'>
 <input formControlName='emailControl' type="text" class= "form-control" placeholder="Entrez l'e-mail" />
 < input formControlName='phoneControl' type="text" class[19659074]="form-control" placeholder="Entrez le téléphone" />[19659080] <form formGroupName='address'>
 <input[19659148]formControlName='streetControl' type="text" class=" form-control" placeholder="Entrez la rue " />
 <input  formControlName='postalcodeControl' type="number" class=[19659015]"form-control" placeholder="Entrez le bureau de poste" />
 </ form>
 <bouton class="btn btn-info">Envoyer</bouton>
 </form>

Principalement FormGroup propose une API pour :

  • Suivre la validation d'un formulaire
  • Suivre la validation de l'ensemble de contrôles
  • Définir et récupérer la valeur d'un formulaire
  • Définir et récupérer la valeur de l'ensemble de contrôles[19659008]À partir de maintenant, vous avez appris toutes les classes importantes qui constituent un formulaire réactif dans Angular.

    Utiliser FormBuilder

    Créer plusieurs formulaires à l'aide de FormGroup et FormControl peut être très long et répétitif. Ainsi, pour vous aider, Angular fournit un service appelé FormBuilder. Il fournit le sucre syntaxique qui raccourcit la syntaxe pour créer des instances de FormControl, FormGroup et FormArray.

    Il y a trois étapes pour utiliser FormBuilder :

    1. Importer la classe FormBuilder.
    2. Injecter le service FormBuilder dans le composant.[19659007]Utilisez-le pour générer les contrôles.

    Vous injectez la classe FormBuilder dans le composant comme indiqué ci-dessous :

     constructor(private fb: FormBuilder ) {
    
      }
    

    Après avoir injecté FormBuilder, vous pouvez refactoriser buyTicketForm pour utiliser le service FormBuilder comme indiqué dans la liste de code suivante :

     this.buyTicketForm = ce.fb.groupe(
          {
            emailControl : [null, [Validators.required]],
            phoneControl : [null],
            adresse :ce.fb.groupe({
              streetControl : [],
              postalcodeControl: []
            })
          }
        )
    

    Comme vous le remarquerez, ce code est désormais moins répétitif. D'un autre côté, que vous utilisiez l'approche de classe FormBuilder ou l'approche de classe FormGroup, le code dans le modèle serait exactement le même. Ainsi, pour utiliser FormBuilder, vous n'avez pas besoin de modifier le modèle.

    Avant d'aller de l'avant et d'apprendre à ajouter des contrôles de manière dynamique, mettons à jour le formulaire pour utiliser les classes d'amorçage et ajoutons également un bouton pour ajouter des tickets. .

    <div class="conteneur">
     <br  />
     <h1 class="text-danger text-center">Acheter des billets </h1>
    
      <div class="row">
     <div class ="col-md-3">
     <bouton class=" btn btn-danger" (click)='addTicket()'>Ajouter un ticket </bouton>
     </div>
     </div>
    
      <form [formGroup]='buyTicketForm' novalidate class="text -center border border-light p-5" (ngSubmit)='buyTickets()'>
      <input formControlName='emailControl' type="text" class[19659074]="form-control mb-4" placeholder="Entrez l'e-mail" />[19659080] <input formControlName='phoneControl' type="text"  class="form-control mb-4" placeholder="Entrez le téléphone" />
     <form formGroupName='address'>
     [19659189]<input formControlName='streetControl' type="text" class ="form-control mb-4" placeholder="Entrez le nom de la rue" / >
     <input formControlName='postalcodeControl' type="numéro" class="form-control mb-4"
     placeholder="Entrez le code postal " />
     </form>
     <bouton  class="btn btn-danger">Envoyer</bouton>
      </formulaire>
    
    </div>
    

    À ce stade de l'exécution de l'application, vous devriez obtenir un formulaire pour acheter des billets. Notre exigence est qu'à chaque fois qu'un utilisateur clique sur le bouton Ajouter un ticketun nouveau ticket doit être ajouté au formulaire.

    Formulaires dynamiques utilisant FormArray

    Comme l'utilisateur ajoute des tickets au moment de l'exécution, pour gérer cela, vous devez créer un formulaire dynamique. Un formulaire dynamique peut contenir soit un contrôle unique soit un groupe de contrôles. Dans notre exemple, un ticket contient le nom et l'âge, c'est donc un groupe de contrôles. Comme vous l'avez déjà vu, ce groupe de contrôles est représenté par FormGroup, créons donc une fonction qui renvoie un FormGroup, qui correspond à un ticket.

     createTicket():FormGroup{
    
        return this.fb.group[19659015]({
          nom :[null,Validateurs.requis],
          age:[null,Validators.required]
        })
      }
    

    Le createTicket La fonction renvoie un FormGroup qui se compose du nom et de l'âge d'un cinéphile. De plus, nous voulons faire en sorte que l'utilisateur doive fournir des valeurs pour les champs de nom et d'âge, donc pour les deux contrôles, la validation requise est définie dessus.

    Le formulaire peut contenir plusieurs tickets, ajoutez donc une nouvelle propriété appelée tickets de type FormArray dans le formulaire buyTicketForm.

    this.buyTicketForm = this .fb.groupe(
          {
            emailControl : [null, [Validators.required]],
            phoneControl : [null],
            adresse :ce.fb.groupe({
              streetControl : [],
              code postalControl : []
            }),
            billets:this.fb.array([this.createTicket([19659015])],Validateurs.requis)
          }
        )
      }
    

    Dans le formulaire ci-dessus, nous utilisons la méthode FormBuilder array pour créer un contrôle de type FormArray et sa valeur initiale est définie en appelant la fonction createTicket. La validation requise est également définie au niveau du tableau afin que l'utilisateur doive fournir des valeurs dans les contrôles de nom et d'âge avant d'ajouter un ticket au tableau tickets.

    Ensuite, pour lire la valeur du tableau tickets, ajoutez un getter dans le composant comme indiqué ci-dessous :

     get tickets():FormArray{
        return[19659597]<FormArray> this.buyTicketForm.get('tickets');[19659068]}
    

    De plus, dans le modèle, il y a un bouton pour ajouter un ticket. En cliquant sur le bouton, il pousse un nouveau ticket dans le FormArray de tickets comme indiqué ci-dessous.

     addTicket() {
        this.tickets.push(this.[19659205]createTicket());
      }
    

    Jusqu'à présent, nous avons créé un FormArray, validé dessus, créé un getter pour lire sa valeur, et également ajouté une fonction pour pousser de nouveaux éléments dans le tableau.

    Modèle de formulaires dynamiques et validations

    Les tickets sont du type FormArray, et dans le modèle pour l'utiliser, vous utilisez ngFor structural directive.

     <div formArrayName="tickets" *ngFor=" let t de tickets.controls; let i = index">
     <input formControlName='name' id="{{'nom'+i}}" type ="text" class="form-control mb-4" placeholder=" Entrez le nom" />
     <input formControlName='age'[19659073]id="{{'age' + i}}" type=" numéro" classe[19659074]="form-control mb-4"
     placeholder="Entrez l'âge "  />
     </div>
    

    Quelques points essentiels dans le modèle ci-dessus :

    • Un div est mappé avec un champ de type FormArrray en définissant la valeur of formArrayName.
    • Les éléments de FormArray sont itérés à l'aide de la directive ngFor.
    • Pour un contrôle à l'intérieur, FormArray id doit être défini dynamiquement, et interpolation avec boucle index peuvent être utilisés pour cela.

    Si l'utilisateur ne fournit pas de valeur pour le contrôle du nom ou de l'âge, vous pouvez afficher le message de validation comme indiqué ci-dessous :

     <div class="alerte alerte-danger" *ngIf=" tickets.controls[i].get('name').hasError('required') && tickets. contrôles[i].get('name').touched">
     Le nom est requis
          </div>
    

    Pour obtenir un contrôle particulier, vous utilisez la valeur ngFor index puis le nom du contrôle. En rassemblant le tout, le modèle devrait ressembler à la liste ci-dessous :

    <div class="container">[19659080] <br />
     <h1 class="text-danger text-center" >Acheter des billets</h1>
    
      <div class="row">
     <div class ="col-md-3">
     <bouton class=" btn btn-danger" (click)='addTicket()'>Ajouter un ticket </bouton>
     </div>
     </div>
     <form [1945905]='buyTicketForm' novalidate class="text-center border border- light p-5" (ngSubmit)='buyTickets()'>
     <entrée  formControlName=[19659015]'emailControl' type="text" class="form-control mb -4" placeholder="Entrez l'e-mail" />
     <input formControlName ='phoneControl' type="text" class="form-control mb-4" placeholder="Entrez le téléphone" />
     < form formGroupName='address'>
     <input formControlName= 'streetControl' type="text" class="form-control mb-4" placeholder="Entrez le nom de la rue" />
     <input[19659148]formControlName='postalcodeControl' type="number" class=" form-control mb-4"
     placeholder="Entrez le code postal " />
     [19659189]</form>
     <div formArrayName="tickets" *ngFor[19659074]="let t de tickets.controls; let i = index">
     <div class="row" [formGroupName]="i">
     <div class="col-md-2">
     <p class="plomb">Billet {{i+1}}</p>
     </div>
     [19659189][div class="col-md-5">
     <input[19659148]formControlName='nom' id="{{'nom' +i}}" type="tex t" class="form-control mb-4"
     placeholder="Entrez le nom " />
     </div>
     <div class= "col-md-5">
     <input formControlName='age ' id="{{'age' + i}}" type=[19659015]"number" class="form-control mb-4"
     placeholder= "Entrez l'âge " />
     </div>
    
          </div>
     <div class="row" >
     <div class="col-md-2">
    
            </div>
     <div class="col-md-5">
    
              <div class="alerte alerte-danger"
     *ngIf=" tickets.controls[i].get('name').hasError('required') && tickets.controls[i].get('name').touched">
     Le nom est requis
              </div>
     </div>
     <div class=[19659015]"col-md-5">
     <div class="alerte alerte- danger"
     *ngIf="tickets.controls[i].get('age'). hasError('required') && tickets.controls[i].get('age').touched" >
     L'âge est requis
              </div>
     </div>
     </div>
    
        </div>
    
        <button class="btn btn-danger" [disabled]='buyTicketForm. invalid'>Submit</button>
      </form>
    
    </div>
    

    Wrap-up

    On running the application, you should now have a fully functional dynamic form. So, in this article, you learned about reactive forms and various classes of them. You also learned about FormArray to create a dynamic form.

    I hope you found it useful. Suggestions and comments are welcome.




Source link