How to display only single validation error at a time

后端 未结 6 1649
失恋的感觉
失恋的感觉 2021-02-08 02:35

I have this code to which displaying errors on my form


&         


        
相关标签:
6条回答
  • 2021-02-08 02:58

    This works and you don't have to hardcode the validations in you template like @Joes answer above.

    Template:
        <input id="password" placeholder="Password" type="password" formControlName="password" [(ngModel)]="password"  [ngClass]="{'invalid-input': !formUserDetails.get('password').valid && formUserDetails.get('password').touched}">
              <div class="validation-container">
                <ng-container *ngFor="let validation of userValidationMessages.password">
                  <div class="invalid-message" *ngIf="formUserDetails.get('password').hasError(validation.type) && formUserDetails.get('password').touched">
                    {{validation.message}}
                  </div>
                </ng-container>
              </div>
    
    CSS:
        .validation-container div {
          display: none;
        }
    
        .validation-container div:first-child {
          display: block;
        }
    
    0 讨论(0)
  • 2021-02-08 03:04

    You can create a Custom Pipe that checks first error equals with specified error:

    CUSTOM PIPE

    import { Pipe, PipeTransform } from '@angular/core';
    
    @Pipe({
      name: 'equals'
    })
    
    export class Equals implements PipeTransform {
    
      transform(errors: any, error: any, args?: any): any {
        if (!errors)
          return false;
    
        const array = Object.keys(errors);
        if (array && array.length > 0)
          return errors[array[0]] === error;
    
        return false;
      }
    }
    

    You can have lots of error div but just one error will be shown:

    // input is form.controls.input1
    <div *ngIf="input.errors | equals:input.errors.required">Required</div>
    <div *ngIf="input.errors | equals:input.errors.maxlength">MaxLength</div>
    <div *ngIf="input.errors | equals:input.errors.pattern">Pattern</div>
    
    0 讨论(0)
  • 2021-02-08 03:09

    If you have consistent markup for your error message blocks, then you can use css to display only the first message and hide the rest:

    css

    .message-block .error-message {
      // Hidden by default
      display: none;
    }
    .message-block .error-message:first-child {
      display: block;
    }
    

    markup

    <div class="message-block">
      <span class="error-message" *ngIf="myForm.get('email').hasError('required')">
        Email is required (first-child of message block is displayed)
      </span>
      <span class="error-message" *ngIf="myForm.get('email').hasError('email')">
        Invalid email format (error message hidden by default)
      </span>
    </div>
    
    0 讨论(0)
  • 2021-02-08 03:12

    Angular2 behind the scene checks the status of the control and reacts accordingly. So if you don't want to have more validation at a time, you can logically play with AND(&&) or/and OR(||) or/and NOT(!) operators.

    0 讨论(0)
  • 2021-02-08 03:20
    <input [ngFormControl]="form1.controls['thing']" type="text" id="thing" #thing="ngForm">
    <div *ngIf='thing.dirty && !thing.valid'>
        <div class="err" *ngIf='thing.errors.required'>
            Thing is required.
        </div >
        <div class="err" *ngIf='!thing.errors.required && thing.errors.ivalid'>
            Thing is invalid.
        </div >
    </div>
    

    You could create a reusable component for showing errors so you don't need to repeat this code again and again.

    0 讨论(0)
  • 2021-02-08 03:24

    You could create a custom pipe to get the first element of the errors object of the validator:

    @Pipe({
      name: 'first'
    })
    export class FirstKeyPipe {
      transform(obj) {
        var keys = Object.keys(obj);
        if (keys && keys.length>0) {
          return keys[0];
        }
        return null;
      }
    }
    

    This way you would be able to display only one error:

    @Component({
      selector: 'my-app',
      template: `
        <form>
          <input [ngFormControl]="form.controls.input1">
          <div *ngIf="form.controls.input1.errors">
            <div *ngIf="(form.controls.input1.errors | first)==='required'">
              Required
            </div>
            <div *ngIf="(form.controls.input1.errors | first)==='custom'">
              Custom
            </div>
          </div>
        </form>
      `,
      pipes: [ FirstKeyPipe ]
    })
    export class MyFormComponent {
      constructor(private fb:FormBuilder) {
        this.form = fb.group({
          input1: ['', Validators.compose([Validators.required, customValidator])]
        });
      }
    }
    

    See this plunkr: https://plnkr.co/edit/c0CqOGuzvFHHh5K4XNnA?p=preview.

    Note: agreed with Günter to create a usable component ;-) See this article for more details:

    • http://restlet.com/blog/2016/02/17/implementing-angular2-forms-beyond-basics-part-2/
    0 讨论(0)
提交回复
热议问题