How to Validate FormArray length in angular2

后端 未结 6 1548
猫巷女王i
猫巷女王i 2021-02-02 09:16

I have a data driven form in angular2 like below

this.formBuilder.group({
  \'name\': [\'\',Validators.required],
  \'description\': [\'\', Validators.required],         


        
相关标签:
6条回答
  • 2021-02-02 09:51

    because you using wrong validator function name: minlength -> minLength

    demo code:

    import { Component, OnInit } from '@angular/core';
    import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms';
    
    @Component({
      selector: 'app-root',
      template: `
        <form novalidate [formGroup]="tpForm" (ngSubmit)="onSubmit()">
          <div><input type="text" formControlName="name"></div>
          <div><textarea formControlName="description"></textarea></div>
          <div formArrayName="places">
            <button type="button" (click)="addPlace()">+</button>
            <div *ngFor="let place of places.controls; let i = index">
              <div>
                  <span>Places {{i + 1}}</span>
                  <button type="button" *ngIf="places.controls.length > 0" 
                      (click)="removePlace(i)">
                      x
                  </button>
              </div>
              <input type="text" [formControlName]="i">
            </div>
          </div>
          <button type="submit">Submit</button>
        </form>
    
        <p>Status: {{ tpForm.valid }}</p>
      `,
      styles: [
        `
    
    
        `
      ]
    })
    export class AppComponent implements OnInit {
      tpForm: FormGroup;
    
      constructor(private fb: FormBuilder) {}
    
      ngOnInit() {
        this.tpForm = this.fb.group({
          'name': ['',Validators.required],
          'description': ['', Validators.required],
          'places': this.fb.array([
            this.fb.control('')
          ], Validators.minLength(1))
        })
      }
    
      get places(): FormArray {
        return this.tpForm.get('places') as FormArray;
      }
    
      onSubmit() {
    
      }
    
      addPlace() {
        this.places.push(this.fb.control(''));
      }
    
      removePlace(index) {
        this.places.removeAt(index);
      }
    
    }
    

    Plunker: https://plnkr.co/edit/cfi7nN?p=preview

    0 讨论(0)
  • 2021-02-02 09:52

    Add this custom validator to your validation service:

    minLengthArray(min: number) {
        return (c: AbstractControl): {[key: string]: any} => {
            if (c.value.length >= min)
                return null;
    
            return { 'minLengthArray': {valid: false }};
        }
    }
    

    And then when creating the form do the following:

    this.formBuilder.group({
      'name': ['',Validators.required],
      'description': ['', Validators.required],
      'places': this.formBuilder.array([], this.validationService.minLengthArray(1)) 
    });
    

    And you can check errors against the FormArray by checking FormArray.hasError('minLengthArray')

    0 讨论(0)
  • 2021-02-02 09:57

    Good and clear way to do this is :

    Create a Array.validator.ts and put all the custom validations over there , like minLength , maxLength etc

    import { ValidatorFn, AbstractControl, FormArray } from '@angular/forms';
    
    // Array Validators
    export class ArrayValidators {
    
        // max length
        public static maxLength(max: number): ValidatorFn | any {
            return (control: AbstractControl[]) => {
                if (!(control instanceof FormArray)) return;
                return control.length > max ? { maxLength: true } : null;
            }
        }
    
        // min length
        public static minLength(min: number): ValidatorFn | any {
            return (control: AbstractControl[]) => {
                if (!(control instanceof FormArray)) return;
                return control.length < min ? { minLength: true } : null;
            }
        }
    }
    

    And Then just import that file and use validation wherever you want to :

    import { ArrayValidators } from './array.validator'; // Import it
    
    'hobbies':new FormArray([],ArrayValidators.minLength(2)) // Use it
    

    WORKING DEMO


    Note :

    You can directly use this package also ng-validator ( Reference is taken from this package ) , But If you need just required array validations you can do it like above.

    0 讨论(0)
  • 2021-02-02 10:04

    if you are trying to add validation to formarray try this may help you,

    this.formBuilder.group({
      'name': ['',Validators.required],
      'description': ['', Validators.required],
      'places': this.formBuilder.array(this.initPlaces()) 
    })
    
    initPlaces() {       
            return this._fb.group({
                places: ['',[Validators.minLength(1)]]           
            });
      }
    

    this initPlaces will simply return formGroup with validation as per requirement.

    0 讨论(0)
  • 2021-02-02 10:04

    Having a template

    <div formArrayName="items">
        <div *ngFor="[...] let i = index" [formGroupName]="i">
    
        [...]
    
        </div>
    </div>
    

    You could simply use this in your button :

    [disabled]="!myForm.get('items.1')"
    
    0 讨论(0)
  • 2021-02-02 10:05

    Validators.required does the magic for you:

    // using required 
    
    this.formGroup = this.formBuilder.group({
        taskTreeId: [Common.UID()],
        executionProgrammedTime: ["", [Validators.required]],
        description: [""],
        tasks: this.formBuilder.array([], Validators.required)
    });  
    
    // using custom validation
    
    export const minLengthArray = (min: number) => {
      return (c: AbstractControl): {[key: string]: any} => {
        if (c.value.length >= min)
          return null;
    
        return { MinLengthArray: true};
      }
    }
    
     this.formGroup = this.formBuilder.group({
            taskTreeId: [Common.UID()],
            executionProgrammedTime: ["", [Validators.required]],
            description: [""],
            tasks: this.formBuilder.array([], minLengthArray(2))
        });
    
    <button type="button" class="btn btn-success btn-rounded" 
        [disabled]="!formGroup.valid">SAVE</button>
    
    0 讨论(0)
提交回复
热议问题