Felhasználói eszközök

Eszközök a webhelyen


oktatas:web:angular:angular_urlapok_ervenyessege

< Angular

Angular - Űrlapok érvényessége

Kezdő projekt

Készítsünk egy új projektet valid néven.

ng new valid

Készítsünk egy login komponenst.

ng generate component login

Építsük az app.component.html sablonba a login komponenst:

<app-login />

A login TypeScript oldalról:

src/app/login/login.component.ts
import { Component } from '@angular/core';
import { 
  FormBuilder,
  FormControl, 
  FormGroup, 
  ReactiveFormsModule, 
  Validators //<--
} from '@angular/forms';
 
@Component({
  selector: 'app-login',
  standalone: true,
  imports: [ReactiveFormsModule],
  templateUrl: './login.component.html',
  styleUrl: './login.component.css'
})
export class LoginComponent {
 
  constructor(private builder : FormBuilder) {}
 
  loginForm = this.builder.group({
    username: [''],
    password: ['']
  });
 
}

Az űrlap:

src/app/login/login.component.html
<h1>Bejelentkezés</h1>
 
<form [formGroup]="loginForm">
  <div>
    <label for="username">Felhasználónév</label>
    <input type="text" id="username" 
    formControlName="username">
  </div>
  <div>
    <label for="password">Jelszó</label>
    <input type="text" id="password" 
    formControlName="password">
  </div>
 
</form>

Állapotosztályok

A reaktív űrlap különböző állapotosztályokat ad form és input elemekhez.

<form class="ng-untouched ng-pristine ng-valid">

Minden input elem külön állapotosztályt kap:

<input class="ng-untouched ng-pristine ng-valid">

A következő táblázat alapján kideríthetjük milyen állapotban van az űrlapunk:

ng-pristine Az űrlap még érintetlen eredeti.
ng-dirty Az űrlap már érintett, nem az eredeti.
ng-touched Egyszer érintve volt.
ng-untouched Már nem érintetlen
ng-valid Érvényes
ng-invalid Nem érvényes

Indítsuk el a projektünket én nézzük meg az űrlapot a böngészőben. A böngészőben váltsunk a fejlesztői felületre, ott válasszuk az Elements fület.

<input class="form-control" ng-invalid>
                         <--^^^^^^^^^^ -->

Szükséges modul

src/app/app.module.ts
import { 
  FormControl, 
  FormGroup, 
  ReactiveFormsModule, 
 
  Validators //<--
} from '@angular/forms';

Felhasználónév megkövetelése

Most állítsuk be a felhasználónévhez érvényességvizsgálatot.

  loginForm = this.builder.group({
    username: ['', Validators.required],
    password: ['']
  });

Nézzük meg most a böngésző fejlesztői felületén az input elem állapotát. Az állapotok a következők:

form:

  • ng-untouched
  • ng-pristine
  • ng-invalid ⇦

input username:

  • ng-untouched
  • ng-pristine
  • ng-invalid ⇦

input password:

  • ng-untouched
  • ng-pristine
  • ng-valid

Validátorok

Használható statikus függvények a Validators osztályon.

  • min()
  • max()
  • required()
  • requiredTrue()
  • email()
  • minLength()
  • maxLength()
  • patter(sztring)
  • nullValidator()
  • compose()
  • composeAsync()

Több információ:

CSS kiemelések

Az attribútum alapján lehet egy kis piros széle, CSS-sel:

input.ng-invalid {
    border-left: 5px solid red;
}
input.ng-valid {
    border-left: 5px solid green;
}

Több érvényesítő

Ha több érvényesítőt is megadunk, tegyük azokat egy újabb szögletes zárójelbe.

    this.loginForm = this.builder.group({
      username: ['', [Validators.required, Validators.minLength(3)]],
      password: ['']
    })

E-mail

Kötelezőnek jelölés és email:

email: new FormControl('', [Validators.required,Validators.email])

Minta használata

name: new FormControl('', Validators.pattern('[a-z]'))

Segítő szöveg

Angular 12.x

<small *ngIf="loginForm.controls.email.invalid">
<small *ngIf="loginForm.controls.email.invalid && loginForm.controls.email.touched">

Angular 13.x

<small *ngIf="loginForm.controls['email'].invalid">
<small *ngIf="loginForm.controls['email'].invalid && loginForm.controls['email'].touched">

Angular 19.x

    @if(loginForm.controls.username.invalid){
      <small>Hiba</small>
    }
    @if(
      loginForm.controls.username.invalid &&
      loginForm.controls.username.touched
      ){
      <small>Hiba</small>
    }

A követelmények szétválasztása

@if(
  loginForm.controls['username'].errors?.['required']
  && loginForm.controls['username'].touched        
    ){
  <small>Kötelező kitölteni</small>
}
@if(
  loginForm.controls['username'].errors?.['minlength']
  && loginForm.controls['username'].touched
    ){
  <small>Minimum 3 karakter</small>
  }

Saját érvényesítő

ng generate directive shared/forbiddenName
  • src/shared/forbidden-name.directive.spec.ts
  • src/shared/forbidden-name.directive.ts
src/shared/forbidden-name.directive.ts
import { Directive } from '@angular/core';
import { 
  AbstractControl, 
  ValidationErrors,
  ValidatorFn 
} from '@angular/forms';
 
@Directive({
  selector: '[appForbiddenName]',
  standalone: true
})
export class ForbiddenNameDirective{
 
  static validate(forbiddenName: RegExp): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      const forbidden = /admin/.test(control.value);
      return forbidden ? { 'forbiddenName': { value: control.value } } : null;
    }
  }
}

Használat

  loginForm = this.builder.group({
    username: ['', [
      Validators.required, 
      Validators.minLength(3),
      ForbiddenNameDirective.validate(/admin/i)
    ]],
    password: ['']
  });

Segítő üzenet

    @if(
      loginForm.controls['username'].errors?.['forbiddenName']
      && loginForm.controls['username'].touched
        ){
      <small>Admin nem megengedett</small>
      }

Lásd még

Saját érvényesítő függvénnyel

ng generate directive shared/forbiddenName

A generált állományban találunk egy előre létrehozott osztályt. Az egész állomány tartalmát törölhetjük. Új tartalom:

src/app/shared/forbidden-name-validator.directive.ts
import { 
  AbstractControl, 
  ValidationErrors, 
  ValidatorFn 
} from "@angular/forms";
 
export function forbiddenNameValidator(forbiddenName: RegExp): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {
    const forbidden = forbiddenName.test(control.value);
    return forbidden ? { 'forbiddenName': { value: control.value } } : null;
  }
}

Az érvényesítő használata

import { forbiddenNameValidator } from './shared/forbidden-name-validator.directive';
 
//...
 
  ngOnInit() {
    this.employeeForm = this.formBuilder.group({
      name: ['', [
        Validators.required, 
        Validators.minLength(3),
        forbiddenNameValidator(/admin/i)
      ]],
      city: [''],
      salary: ['']
    })
  }

Megtiltjuk az admin név beírását.

HTML sablonban reagálunk az ilyen hibákra:

    @if(employeeForm.controls['name'].errors?.['forbiddenName']) {
      <span>A név nem megengedett.</span>
    }

Saját érvényesítő 3

Validátor generálása:

ng generate directive shared/forbiddenNameValidator
src/app/shared/forbidden-name-validator.directive.ts
import { Directive } from '@angular/core';
import { AbstractControl, ValidationErrors, Validator } from '@angular/forms';
 
@Directive({
  selector: '[forbiddenNameValidator]',
  standalone: true
})
export class ForbiddenNameValidatorDirective implements Validator {
 
  constructor() { }
 
  validate(control: AbstractControl): ValidationErrors | null {
    const forbidden = /admin/.test(control.value);
    return forbidden ? { 'forbiddenName': { value: control.value } } : null;
  }
 
}

Használat:

  loginForm = this.builder.group({
    username: ['', [
      Validators.required, 
      Validators.minLength(3),
      new ForbiddenNameValidatorDirective
    ]],

Segítő szöveg:

    @if(
      loginForm.controls['username'].errors?.['forbiddenName']
      && loginForm.controls['username'].touched
        ){
      <small>Admin nem megengedett</small>
      }

Jelszó érvényessége

Minta jelszó érvényesítéshez:

const pattern = '^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)[A-Za-z\\d]{8,}$';

Megkövetelejük:

  • legyen benne nagybetű (az első zárójeles rész)
  • legyen benne kisbetű (a második zárójeles rész)
  • legyen benne szám (a harmadik zárójeles rész)
  • csak nagy vagy kisbetű és szám lehet (a szögletes zárójel)
  • minimum 8 (a kapcsos zárójel)
src/app/login/login.component.ts
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, ReactiveFormsModule, Validators } from '@angular/forms';
 
@Component({
  selector: 'app-login',
  standalone: true,
  imports: [ReactiveFormsModule],
  templateUrl: './login.component.html',
  styleUrl: './login.component.css'
})
export class LoginComponent {
 
  loginForm !: FormGroup;
 
  constructor(
    private builder: FormBuilder
  ) { }
 
  ngOnInit(): void {
    const pattern = '^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)[A-Za-z\\d]{8,}$';
    this.loginForm = this.builder.group({
      name: [''],
      password: ['', Validators.pattern(pattern)]
    });
  }
 
  login() {
    console.log(this.loginForm.value);
  }
 
}

Források

oktatas/web/angular/angular_urlapok_ervenyessege.txt · Utolsó módosítás: 2025/03/06 08:35 szerkesztette: admin