web-dev-qa-db-fra.com

Tableau des formes réactives angulaires2

J'ai du mal à lever les yeux et à essayer de faire ce que je veux.

J'ai une table avec des entrées dans chaque ligne et je veux que chaque ligne créée à l'aide d'un ngFor soit considérée comme un groupe de formulaires.

Dans chaque groupe de formulaires, je souhaite une validation en ce sens que si l'un des contrôles est renseigné dans la ligne, le groupe de formulaires complet doit être rempli avant que la soumission ne puisse être effectuée.

Voici ce que j'ai jusqu'à présent dans mon modèle.

Je n'ai encore rien dans le composant Angular.io et chercher quelques heures ne me permet pas de savoir ce que je veux.

<form>
        <table id="table" class="mdl-data-table mdl-js-data-table mdl-data-table mdl-shadow--2dp">
            <thead>
                <tr>
                    <th>Day</th>
                    <th>Description</th>
                    <th>Open Time</th>
                    <th>Close Time</th>
                </tr>
            </thead>

            <tbody>

                <tr *ngFor="let scheduleDetail of scheduleDetails">
                    <td style="padding: 0 8px 0 8px;">{{weekdayConverter(scheduleDetail.dayId)}}</td>
                    <td class="pad-input">
                        <mdl-textfield style="max-width:100px;" type="text" class="font" name="description" [(ngModel)]="scheduleDetail.description"></mdl-textfield>
                    </td>
                    <td>
                        <mdl-textfield style="max-width:75px" type="text" error-msg="hh:mm" name="openTime" pattern="([01]\d|2[0-3]):?([0-5]\d)" [(ngModel)]="scheduleDetail.openTime"></mdl-textfield>
                    </td>
                    <td>
                        <mdl-textfield style="max-width:75px" type="text" error-msg="hh:mm" name="closeTime" pattern="([01]\d|2[0-3]):?([0-5]\d)" [(ngModel)]="scheduleDetail.closeTime"></mdl-textfield>
                    </td>
                </tr>

            </tbody>

        </table>
    </form>

Mettre à jour

Ajout de ce qui suit au modèle:

Entrées modifiées pour:

<mdl-textfield (keyup)="formChange(scheduleDetail)" style="max-width:100px;" type="text" class="font" name="description" [(ngModel)]="scheduleDetail.description"></mdl-textfield>

Ajout de ce qui suit au composant:

    formChange(detail:scheduleDetail){
if(this.checkValid(detail)==false)
this.scheduleDetails.filter(detail => detail == detail)[0].require=true;
else
this.scheduleDetails.filter(detail => detail == detail)[0].require=false;

this.checkForm();
}

checkValid(detail:scheduleDetail){
if(detail.description!=null && detail.description!=""){
  if(this.checkTime(detail))
    return true
  else 
    return false
}
else
  return true
}

checkTime(detail:scheduleDetail){
  if(
    (detail.openTime!=null && detail.closeTime!=null) && 
    ( detail.openTime!="" && detail.closeTime!="") &&
    (this.checkRegExp(detail.openTime) && this.checkRegExp(detail.closeTime))
    ){
    return true
    }

  else if((this.checkRegExp(detail.openTime) && this.checkRegExp(detail.closeTime))){
    return true
  }
  else return false
}

checkRegExp(time:string){
let timeRegExp = /([01]\d|2[0-3]):?([0-5]\d)/;

if(timeRegExp.test(time)){
  return true;
}
else
  return false;

}

checkForm(){
let valid: boolean = true;
  this.scheduleDetails.forEach(detail => {
    if(detail.require==true){
      valid = false;
    }
  });

    this.scheduleDetails.forEach(detail => {
    if(detail.description=="" || detail.description==null){
      valid = false;
    }
  });
this.formValid = valid;
}
5
Jesse S

Formes modelées

Vous utilisez un formulaire basé sur des modèles, difficile à mettre à l'échelle et à gérer.

Ici, je vais vous guider pour migrer vers un formulaire basé sur un modèle.

Composant

export class WeekScheduleComponent {

// Our empty Form
myForm: FormGroup;

constructor(private fb: FormBuilder){
 // We inject FormBuilder to our component

 // Now, we instantiate myForm with FormBuilder
 // Notice that myForm is a FormGroup which contains an empty FormArray
    this.myForm = this.fb.group({
                   scheduleDetail: this.fb.array([])
                  })
}

addRow(){
    // This function instantiates a FormGroup for each day
    // and pushes it to our FormArray

    // We get our FormArray
    const control = <FormArray>this.myForm.controls['scheduleDetail'];

    // instantiate a new day FormGroup;
    newDayGroup: FormGroup = this.initItems();

    // Add it to our formArray
    control.Push(newDayGroup);
}

initItems(): FormGroup{
    // Here, we make the form for each day

    return this.fb.group({
               description: [null, Validators.required],
               openTime: [null, Validators.required],
               closeTime: [null, Validators.required]
           });
}

submit(){
    // do stuff and submit result
    console.log(this.myForm.value);
}
}

dans votre modèle:

<form [formGroup]="myForm" *ngIf="myForm">
     <table formArrayName="scheduleDetail">

            <tr *ngFor="let item of myForm.controls.scheduleDetail.controls; let i=index"
                [formGroupName]="i" >

                <td><input type='text' formControlName="description"></td>
                <td><input type='text' formControlName="openTime"></td>
                <td><input type='text' formControlName="closeTime"></td>

            </tr>

     </table>
</form>

<button (click)="addRow()">Add new item</button>
<button (click)="submit()" [disabled]="!myForm.valid">Submit</button>
7
Hamid Asghari

Composant

import { Component, OnInit } from '@angular/core';
import {FormGroup, FormBuilder, FormControl, Validators, FormArray} from '@angular/forms';

@Component({
  selector: 'app-sales',
  templateUrl: './sales.component.html',
  styleUrls: ['./sales.component.css']
})
export class SalesComponent implements OnInit {

  myForm: FormGroup;

  constructor(private fb: FormBuilder){

  }
  // getter to get a reference to scheduleDetail form array in myForm form group
  get scheduleDetail():FormArray{
    return <FormArray>this.myForm.get('scheduleDetail')
  }
  // add a new row, get reference to form array using getter method and Push form group into it   
  addRow(){
    this.scheduleDetail.Push(this.initItems());
  }
  // make a form for each row!
  initItems(): FormGroup{
    return this.fb.group({
              description: [null, Validators.required],
              openTime: [null, Validators.required],
              closeTime: [null, Validators.required]
          });
  }

  submit(){
    console.log(this.myForm.value)
  }

  ngOnInit() {
    this.myForm = this.fb.group({
      scheduleDetail: this.fb.array([this.initItems()])
    })
  }

}

Modèle

<form [formGroup]="myForm" *ngIf="myForm">
    <table formArrayName="scheduleDetail">
        <thead> 
            <tr>
              <th >Desc</th>
              <th >Open Time</th>
              <th >Close Time</th>
            </tr>
          </thead>
          <tbody>
              <tr *ngFor="let item of myForm.controls.scheduleDetail.controls; let i=index"
              [formGroupName]="i" >
                <td><input type='text' formControlName="description"></td>
                <td><input type='text' formControlName="openTime"></td>
                <td><input type='text' formControlName="closeTime"></td>
            </tr>
          </tbody>
    </table>
</form>

<button (click)="addRow()">Add new item</button>
<button (click)="submit()" [disabled]="!myForm.valid">Submit</button>
0
Arun Mankad