0

私は複数の入力を持っています。フィールドは必須で、空白は入力しないでください。Angular5を使用してフォームコントロールの変更をチェックする方法

component.html:

<form [formGroup]="contratoForm" class="campo-form"> 
     <div class="campoFormulario"> 
      <label class="etiquetaFormulario" for="txtCodigoContrato">Código contrato</label> 
      <div style="display:inline-block; position: relative;" class="control"> 
       <input [formControl]="txtCodigoContrato" type="text" id="txtCodigoContrato" name="txtCodigoContrato" class="cajaTexto ancho80" /> 
       <span>/</span> 
      </div>     
      <div style="display:inline-block; position: relative;" class="control">     
       <input [formControl]="txtCodigoContrato2" type="text" id="txtCodigoContrato2" name="txtCodigoContrato2" class="cajaTexto ancho80" />    
      </div> 
     </div> 
     <div class="campoFormulario"> 
      <label class="etiquetaFormulario" for="txtContrato">Contrato</label> 
      <div style="display:inline-block; position: relative;" class="control"> 
       <input [formControl]="txtContrato" type="text" id="txtContrato" name="txtContrato" class="cajaTexto ancho350" /> 

      </div> 
     </div> 
     <div *ngIf="((!txtCodigoContrato.valid && (txtCodigoContrato.dirty || txtCodigoContrato.touched)) && (txtCodigoContrato.hasError('required') || txtCodigoContrato.hasError('hasWhites'))) 
       || 
       ((!txtCodigoContrato2.valid && (txtCodigoContrato2.dirty || txtCodigoContrato2.touched)) && (txtCodigoContrato2.hasError('required') || txtCodigoContrato2.hasError('hasWhites'))) 
       || 
     ((!txtContrato.valid && (txtContrato.dirty || txtContrato.touched)) && (txtContrato.hasError('required') || txtContrato.hasError('hasWhites'))) 
       "> 

      <span>check the fields in red, they are required</span>  
     </div>    
     <div class="buttons"> 
      <button class="btn btn-primary boton" type="button" style="float:right;" (click)="onCloseLink()"> 
       <span class="glyphicon glyphicon-off"></span> Cancel 
      </button> 

      <button class="btn btn-primary boton" type="button" style="float:right;" (click)="limpiar()"> 
       <span class="glyphicon glyphicon-trash"></span> Clean 
      </button> 
      <button type="submit" [disabled]="!contratoForm.valid" class="btn btn-primary boton" style="float:right;" (click)="onClick()"> 
       <span class="glyphicon glyphicon-floppy-disk"></span> Save 
      </button> 
     </div> 
    </form> 

component.ts:

import { Component, HostBinding, OnDestroy, OnInit, Input, Output, EventEmitter, ElementRef, NgModule, ViewChild, ChangeDetectorRef } from '@angular/core'; 
    import { Validators, FormBuilder, FormControl, FormGroup, AbstractControl} from '@angular/forms'; 
    import { AfterViewChecked } from '@angular/core/src/metadata/lifecycle_hooks'; 

    @Component({ 
     selector: 'app-formulario-contrato', 
     templateUrl: './contrato.component.html', 
     styleUrls: ['./contrato.component.css'] 
    }) 
    export class FormularioContratoComponent { 

     contratoForm: FormGroup; 

     constructor(private elRef: ElementRef, private formBuilder: FormBuilder, private cdRef: ChangeDetectorRef) {  
      this.createForm();   
     } 

     txtCodigoContrato = new FormControl('', [ 
      Validators.required 
      ,this.hasNotWhites 
     ]); 
     txtCodigoContrato2 = new FormControl('', [ 
      Validators.required 
      , this.hasNotWhites 
     ]); 
     txtContrato = new FormControl('', [ 
      Validators.required 
      , this.hasNotWhites 
     ]); 

     createForm() { 
      this.contratoForm = this.formBuilder.group({ 
       txtCodigoContrato: this.txtCodigoContrato 
       ,txtCodigoContrato2: this.txtCodigoContrato2 
       ,txtContrato: this.txtContrato   
      }); 
     } 

     hasNotWhites(fieldControl: FormControl) { 
      if (fieldControl.value.trim() != '') { 
       return null 
      } 
      else { 
       return { hasWhites: true }; 
      }   
     } 

     ngAfterViewChecked() { 
      this.cdRef.detectChanges(); 
     } 

     limpiar() { 
     } 

     onClick() { 
      return null; 
     } 

component.css:

検証が正常に動作し
/* some stuff...*/ 
:host /deep/ .control input.ng-invalid.ng-touched { 
    border-color: #ff8080; 
} 

は、つまり、彼らはジャンプ場空のままになったり、空白を入力したりします。

<div *ngIf="((!txtCodigoContrato.valid && (txtCodigoContrato.dirty || 
    txtCodigoContrato.touched)) && (txtCodigoContrato.hasError('required') || 
    txtCodigoContrato.hasError('hasWhites'))) 
       || 
       ((!txtCodigoContrato2.valid && (txtCodigoContrato2.dirty || 
    txtCodigoContrato2.touched)) && (txtCodigoContrato2.hasError('required') || 
    txtCodigoContrato2.hasError('hasWhites'))) 
       || 
     ((!txtContrato.valid && (txtContrato.dirty || txtContrato.touched)) 
    && (txtContrato.hasError('required') || txtContrato.hasError('hasWhites'))) 
       "> 

はtypescriptですによって、これらの値を制御する方法は、それぞれの時間、つまり、価値があります:私の問題は、私はより多くのフォームコントロールを追加する必要があり、それが含まれている場合は、メッセージが読めなく行うことができることですコントロールの変更は、trueまたはfalseを返すtypeScriptの関数によって制御され、div内のその関数の値を尋ねるだけの場合は変更されますか?

+0

に自分のコントロール名を追加し、これは動作しますが、唯一の私は変更を行う際にジャンプSTACKBLITZ

を作成しました入力。カーソルをある入力から別の入力に移動するときにジャンプする必要があります。 – ararb78

答えて

0

valueChangesを使用してみてくださいを変更している取得する前に、マップ機能を追加することができます

this.contratoForm.valueChanges.subscribe(value = > //do something) 

ような何かを行うことができますArray.some()関数

hasError: boolean = false; 

constructor(private elRef: ElementRef, 
      private formBuilder: FormBuilder, 
      private cdRef: ChangeDetectorRef) {  
    this.createForm(); 

    // listen to all changes on the form 
    this.contratoForm.valueChanges.subscribe(_ => { 
    const controllersToCheck = [ 
     'txtCodigoContrato', 
     'txtCodigoContrato2', 
     'txtContrato' 
    ]; 
    this.hasError = controllersToCheck.some(ctrlName => { 
     let ctrl = this.contratoForm.get(ctrlName); 
     return (ctrl.dirty || ctrl.touched) && 
      (ctrl.hasError('required') || ctrl.hasError('hasWhites')); 
    }); 
    });   
} 

あなたも聞くことができる述べhere

として

<div *ngIf="hasError"> 
    <span>check the fields in red, they are required</span>  
</div> 

UPDATE

:コントローラにエラーがある場合は、それが無効であるため、!ctrl.validをINGのこと)

HTML冗長です 妥当性確認のステータスが通知された場合は、AbstractControl#statusChanges statusChanges}再計算された です。

私はそれがより多くのあなたのケースに合わせて、その(代わりにvalueChangesの)statusChangesイベントに加入しようと思う:

this.contratoForm.statusChanges.subscribe(.......... 

UPDATE 2

あなたのHTML内の関数を使用します。

<div *ngIf="hasErrors()"> 
    <span>check the fields in red, they are required</span> 
</div> 

この機能をコンポーネントに追加するts f ILE:

hasErrors() { 
    const controllersToCheck = [ 
    'txtCodigoContrato', 
    'txtCodigoContrato2', 
    'txtContrato' 
    ]; 
    return controllersToCheck.some(ctrlName => { 
    let ctrl = this.contratoForm.get(ctrlName); 
    return (ctrl.dirty || ctrl.touched) && 
      (ctrl.hasError('required') || ctrl.hasError('hasWhites')); 
    }); 
} 

私はあなたが同じ検証ロジックを使用して新しいコントローラを追加する場合、単にcontrollersToCheck配列

+0

これは機能しますが、入力を変更するとジャンプするだけで、入力からカーソルへ移動するとジャンプする必要があります別のものを入力しないで – ararb78

+0

'valueChanges'の代わりに' statusChanges'イベントを購読しようとしました。私の更新された答えを参照してください – Andriy

+0

"statuschange"に変更しました。フィールドの状態は変更されますが、関数内でジャンプしません理由を理解できません:this.contratoForm.statusChanges.suscribe(.... 。 – ararb78

0

あなたがしたい場合は、単にあなたがその気にフォームからの値が

this.contratoForm.valueChanges 
.map(values => values.txtCodigoContrato) 
.subscribe(txtCodigoContrato = > //do something) 
関連する問題