06/04/2021, 14:48

Form trong Angular 4 - Angular4

Trong bài này, chúng ta sẽ tìm hiểu về form và hai cách sử dụng form trong Angular 4 là Template Driven Form và Model Driven Form nhé. Với template driven form thì phần lớn các công việc được thực hiện ở phía template và với model driven form thì công việc lại ...

Trong bài này, chúng ta sẽ tìm hiểu về form và hai cách sử dụng form trong Angular 4 là Template Driven FormModel Driven Form nhé.

Với template driven form thì phần lớn các công việc được thực hiện ở phía template và với model driven form thì công việc lại được thực hiện phần lớn ở component class

Template Driven Form

Cùng đi vào 1 ví dụ cụ thể. Chúng ta sẽ tạo 1 form đăng nhập đơn giản có username và password.

Đầu tiên, chúng ta cần import FormsModule từ @angular/core trong file app.module.ts

app.module.ts
  import { BrowserModule } from '@angular/platform-browser';
  import { NgModule } from '@angular/core';
  import { RouterModule } from '@angular/router'

  import {HttpClientModule} from '@angular/common/http';
  // Import forms module
  import { FormsModule } from '@angular/forms';
  import { AppComponent } from './app.component';

  import { NewCmpComponent } from './new-cmp/new-cmp.component';
  import { ChangeTextDirective } from './change-text.directive';
  import { SqrtPipe } from './app.sqrt';
  @NgModule({
    declarations: [
      AppComponent,
      NewCmpComponent,
      ChangeTextDirective,
      SqrtPipe
    ],
    imports: [
      BrowserModule,
      // Khai báo Forms Module
      FormsModule,
      HttpClientModule,
      RouterModule.forRoot([
        {
          path: 'new-cmp',
          component: NewCmpComponent
        }
      ])
    ],
    providers: [],
    bootstrap: [AppComponent]
  })
  export class AppModule { }

Module form đã được import vào project. Bây giờ chúng ta sẽ xử lý gán sự kiện, model ở phía

app.component.html
<form #userlogin = "ngForm" (ngSubmit) = "onClickSubmit(userlogin.value)" >
       <input type = "text" name = "username" placeholder = "username" ngModel>
       <br/>
       <input type = "password" name = "pwd" placeholder = "password" ngModel>
       <br/>
       <input type = "submit" value = "submit">
</form>

Phía trên, ta định nghĩa tên form là userLogin thông qua template #userlogin = "ngForm", gán sự kiện submit cho form này là onClickSubmit(userlogin.value) với tham số truyền vào chính là giá trị của form. Trong form định nghĩa có 2 input lần lượt là usernamepwd.

Angular 4 nhận diện các thành phần của form thông qua ngModelname của thành phần. Như trong ví dụ:

 <input type = "text" name = "username" placeholder = "username" ngModel>

thì thành phần này có name=username và có thuộc tính ngModel. Do vậy Angular sẽ nhận diện đây là 1 thành phần của form có tên là username.

Giá trị userlogin.value chính là một object chứa các thành phần trong form. Chúng ta cùng đi vào phần kiểm soát sự kiện trong component class để hiểu hơn về giá trị value này.

app.component.ts
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})

export class AppComponent {
    onClickSubmit(data) {
        alert("Username bạn vừa nhập là : " + data.username);
     }
}

Trong file app.component.ts trên, ta khai báo phương thức onClickSubmit(data). Tham số data truyền vào chính là giá trị của form userlogin (userlogin.value) ở phía bên view truyền sang.

Trong sự kiện submit, ta alert ra giá trị nhập vào của input username. Khi click submit, ta nhận được kết quả

Kết quả hiển thị khi submit form

Model Driven Form

Để viết code form theo model driven form, ta cần import module ReactiveFormsModule từ @angular/forms.

app.component.ts
  import { BrowserModule } from '@angular/platform-browser';
  import { NgModule } from '@angular/core';
  import { RouterModule } from '@angular/router'

  import {HttpClientModule} from '@angular/common/http';
  import { ReactiveFormsModule } from '@angular/forms';
  import { AppComponent } from './app.component';

  import { NewCmpComponent } from './new-cmp/new-cmp.component';
  import { ChangeTextDirective } from './change-text.directive';
  import { SqrtPipe } from './app.sqrt';
  @NgModule({
    declarations: [
      AppComponent,
      NewCmpComponent,
      ChangeTextDirective,
      SqrtPipe
    ],
    imports: [
      BrowserModule,
      ReactiveFormsModule,
      HttpClientModule,
      RouterModule.forRoot([
        {
          path: 'new-cmp',
          component: NewCmpComponent
        }
      ])
    ],
    providers: [],
    bootstrap: [AppComponent]
  })
  export class AppModule { }

Trong app.component.ts, ta import các thành phần FormGroup, FormControl từ @angular/forms

app.component.ts
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { FormGroup, FormControl } from '@angular/forms';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})

export class AppComponent {
    username;
    formdata;
    ngOnInit() {
        this.formdata = new FormGroup({
            username: new FormControl("Zaidap.com.net"),
            pwd: new FormControl("abcd1234")
        });
    }
    onClickSubmit(data) { this.username = data.username; }
}

Trong đoạn code trên, chúng ta khai báo 2 biến: usernameformdata. Sau đó tạo ra một FormGroup với 2 FormControl: FormControl username với giá trị khởi tạo là "Zaidap.com.net" và FormControl pwd với giá trị khởi tạo là "abcd1234" và tạo sự kiện handle khi submit form là onClickSubmit.

Bên file app.component.html, ta tạo ra giao diện cho form:

app.component.html
<div>
    <form [formGroup]="formdata" (ngSubmit) = "onClickSubmit(formdata.value)" >
       <input type="text" class="fortextbox" name="username" placeholder="username" 
          formControlName="username">
       <br/>
       
       <input type="pwd" class="fortextbox" name="pwd" 
          placeholder="pwd" formControlName="pwd">
       <br/>
       
       <input type="submit" class="forsubmit" value="Log In">
    </form>
 </div>
 <p>
    Bạn vừa nhập username : {{username}}
 </p>

Trong phần html, chúng ta sử dụng thuộc tính formGroup trong cặp ngoặc vuông cho form, trong ví dụ trên là [formGroup]="formdata". Khi submit form, hàm onClickSubmit được gọi với giá trị truyền vào là formdata.value

Thuộc tính formControlName được sử dụng trong thẻ input để chứa giá trị mà chúng ta khai báo bên phía file component class. Trong ví dụ trên thì 2 thẻ input có 2 formControlName là username và pwd.

Khi click vào submit, kết quả hiển thị ở trình duyệt như hình dưới

Kết quả hiển thị khi submit form

Form Validation

Chúng ta cùng đi vào tìm hiểu về form validation sử dụng model driven form. Bạn có thể sử dụng các tính năng xây dựng sẵn (built-in) hay tự tạo (custom) cho việc validation.

Sử dụng built-in validation

Angular có các built-in validator cho một số các trường hợp phổ biến thường dùng như madatory field (trường bắt buộc), minlength (độ dài tối thiểu), maxlength (độ dài tối đa) và pattern (mẫu).

Giả sử ta cần validate trường username với độ dài tối thiểu là 3 kí tự, độ dài tối đa là 20 kí tự và là bắt buộc.

Trước tiên ta cần timport Validators bên trong file app.component.ts

import { FormGroup, FormControl, Validators} from '@angular/forms'

Tiếp đó, thêm phần validator cho control username:

app.component.ts
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { FormGroup, FormControl, Validators } from '@angular/forms';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})

export class AppComponent {
    username;
    formdata;
    ngOnInit() {
        this.formdata = new FormGroup({
            username: new FormControl("Zaidap.com.net", Validators.compose([
                Validators.required,
                Validators.minLength(3),
                Validators.maxLength(20)
            ])),
            pwd: new FormControl("abcd1234")
        });
    }
    onClickSubmit(data) { this.username = data.username; }
}

Trong hàm tạo của FormControl username, ta thêm vào 1 đối thứ 2 là Validator.compose([]). Trong compose, ta truyền vào Validators.required để định nghĩa rằng trường này là bắt buộc, Validators.minLength(3) để định nghĩa độ dài tối thiểu của trường là 3 và Validators.maxLength(20) để định nghĩa độ dài tối đa của trường là 20.

Cuối cùng, ta thêm thuộc tính [disabled] = "!formdata.valid" cho button submit ở file app.component.html để nếu điều kiện validator thoả mãn thì button submit được enable, nếu không thoả mãn thì bị disabled như sau:

app.component.html
<div>
    <form [formGroup]="formdata" (ngSubmit) = "onClickSubmit(formdata.value)" >
       <input type="text" class="fortextbox" name="username" placeholder="username" 
          formControlName="username">
       <br/>
       
       <input type="pwd" class="fortextbox" name="pwd" 
          placeholder="pwd" formControlName="pwd">
       <br/>
       
       <input type="submit" [disabled] = "!formdata.valid" class="forsubmit" value="Log In">
    </form>
 </div>
 <p>
    Bạn vừa nhập username : {{username}}
 </p>

Khi chưa nhập hoặc nhập độ dài không hợp lệ, ta thấy button submit bị disable đi như sau:

Button submit bị disabled khi validator không thoả mãn

Khi nhập username thoả mãn validator, button submit được như hình dưới:

Button submit được enable khi validator thoả mãn

Tạo custom validator

Trong ví dụ này, ta sẽ tạo 1 custom validator cho trường pwd: độ dài tối thiểu phải là 6 kí tự

Để tạo custom validator cho form, ta cần khai báo và sử dụng hàm xử lý validator. Ở đây, chúng ta khai báo hàm pwdLengthValidator để kiểm tra độ dài của form control

app.component.ts
import { Component } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { FormGroup, FormControl, Validators } from '@angular/forms';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})

export class AppComponent {
    username;
    formdata;
    ngOnInit() {
        this.formdata = new FormGroup({
            username: new FormControl("Zaidap.com.net", Validators.compose([
                Validators.required,
                Validators.minLength(3),
                Validators.maxLength(20)
            ])),
            pwd: new FormControl("abcd1234", this.pwdLengthValidator)
        });
    }
    onClickSubmit(data) { this.username = data.username; }

    pwdLengthValidator(control){
        if(control.value.length < 6){
            return {pwd: true};
        }
    }
}

Trong hàm tạo của form control pwd, ta truyền vào tham số là hàm pwdLengthValidator. Phần xử lý logic có thể sẽ khiến bạn hơi "bối rối" một chút. 

app.component.ts
if(control.value.length < 6){
        return {pwd: true};
}

Nếu như độ dài của giá trị form control < 6 thì ta return lại object chứa trạng thái của control bị lỗi hay không. Ở đây chúng ta return lại là  return {pwd: true}; có nghĩa là form control pwd đang bị lỗi.

Ok. Bây giờ thử chạy ứng dụng trên trình duyệt. Nếu nhập password dưới 6 kí tự thì button submit sẽ bị disable đi

Button submit bị disable đi vì độ dài của trường password không đủ

Khi nhập độ dài của password đủ 6 kí tự thì button submit được enable lên

Khi nhập đủ độ dài của trường pwd thì button submit được enable lên.

Nội dung bài học Form trong Angular 4 đến đây là kết thúc rồi. Hẹn gặp lại các bạn trong bài học sau: Animation trong Angular 4 nhé.

 

0