1.13.3. fejezet, Forms

HTML Form

user.component.html

<form (submit)="submitForm($event)">
  <input type="text" placeholder="Name" name="name"/>
  <br/><br/>
  <input type="email" placeholder="E-mail" name="email"/>
  <br/><br/>
  <input type="text" placeholder="Address" name="address"/>
  <br/><br/>
  <button type="submit">Submit</button>
</form>

user.component.ts

@Component({
  selector: 'app-user',
  templateUrl: './user.component.html',
  styleUrl: './user.component.css'
})
export class UserComponent {
  submitForm(event: SubmitEvent) {
    event.preventDefault()
    console.log('Form submitted')
    let data = new FormData(event.target as HTMLFormElement);
    console.log(data.get('name'));
    console.log(data.get('email'));
    console.log(data.get('address'));
  }
}

Ez a módszer elavult, sok hibalehetőséget tartalmaz. Helyette használjuk a sablon vezérelt űrlap módszert a következők szerint.

Template-Driven Forms (ngModel)

Importálni kell a FormsModule-t a kompiens (pl.: app.module.ts) fájlba:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
 
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';
 
@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, AppRoutingModule, FormsModule], // !!!!! FormsModule !!!!!
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

A FormsModule szükséges a kétirányú kapcsolatkezeléshez, hogy fel tudjuk vennni a [(ngModel)]-t az input tulajdonságai közé.

<input [(ngModel)]="title" />
<h1 [innerHTML]="title"></h1>
{{ title }}
<button (click)="resetTitle()">Reset title</button>

Egy DOM elemere hivatkozhatunk közvetlenül, ha használjuk a #azonosito deklarációt. Pl.:

<input #titleInput [(ngModel)]="title" />
<h1 [innerHTML]="title"></h1>
{{ title }}
<button (click)="resetTitle()">Reset title</button>
<button (click)="reverseTitle(titleInput.value)">Reverse title</button>

A komponens kontroller (pl.: app.component.ts) példa pedig lehet ez:

import { Component } from '@angular/core';
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  title = 'homework4angular';
  resetTitle() {
    this.title = 'homework4angular';
  }
  reverseTitle(value: string) {
    this.title = value.split('').reverse().join('');
  }
}

Itt a title tulajdonságra közvetlenül is hivatkozhattunk volna, a reverse-be nem szükséges átadni paraméterként az értéket, de most a DOM elemre hivatkozást szemléltettem.

Egy másik Template-driven minta:

user.component.html

<form (submit)="submitForm(f)" #f="ngForm">
  <input type="text" placeholder="Name" name="name" ngModel/>
  <br/><br/>
  <input type="email" placeholder="E-mail" name="email" ngModel/>
  <br/><br/>
  <input type="text" placeholder="Address" name="address" ngModel/>
  <br/><br/>
  <button type="submit">Submit</button>
</form>

user.component.ts

import { Component } from '@angular/core';
import {NgForm} from '@angular/forms';
 
interface UserForm {
  name: string;
  email: string;
  address: string;
}
 
@Component({
  selector: 'app-user',
  templateUrl: './user.component.html',
  styleUrl: './user.component.css'
})
export class UserComponent {
 
  submitForm(f: NgForm) {
    let form = f.value as UserForm;
    console.log(form)
  }
 
}

Form validáció

<form (submit)="submitForm(f)" #f="ngForm">
  <input type="text" placeholder="Name" name="name" ngModel #fullName="ngModel" required minlength="3"/>
  @if(fullName.invalid && fullName.touched) {
    <span style="color: red;">{{fullName.errors | json}}</span>
    @if(fullName.hasError('required')) {
      <span style="color: red;">UserName is required!</span>
    } @else if(fullName.hasError('minlength')) {
      <span style="color: red;">UserName length is minimum 3 character!</span>
    }
  }
  <br/><br/>
  <input type="email" placeholder="E-mail" name="email" ngModel #email="ngModel" pattern="^([a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$)"/>
   @if(email.invalid && email.touched) {
      @if(email.hasError('pattern')) {
        <span style="color: red;">Email format required!</span>
      }
   }
  <br/><br/>
  <input type="text" placeholder="Address" name="address" ngModel/>
  <br/><br/>
  <button type="submit" [disabled]="f.invalid">Submit</button>
</form>