web-dev-qa-db-ja.com

Angular2リアクティブフォームテーブル

見上げてやりたいことをやろうとして困っています。

各行に入力があるテーブルがあり、ngForを使用して作成された各行をフォームグループと見なしたいと思います。

各フォームグループ内で、行内のコントロールのいずれかが入力されている場合、送信を行う前にフォームグループ全体を入力する必要があるという検証が必要です。

これが私のテンプレートにこれまでにあるものです。

Angular.ioを使用して数時間検索しても、必要なものに近いものが何も表示されないため、コンポーネントにはまだ何もありません。

<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>

更新

テンプレートに以下を追加しました。

入力を次のように変更しました:

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

コンポーネントに以下を追加しました。

    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

モデル駆動型フォーム

スケーリングや保守が難しいテンプレート駆動型フォームを使用しています。

ここでは、モデル駆動型フォームに移行する方法を説明します。

成分

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);
}
}

テンプレート内:

<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>
11
Hamid Asghari

成分

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()])
    })
  }

}

テンプレート

<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