Form Custom Validators

Panusitt Khuenkham
Angular in Thailand
4 min readNov 27, 2017

สร้างการตรวจสอบฟอร์มแบบกำหนดเอง

https://qph.ec.quoracdn.net/main-qimg-ef0e116da7fd48a80fe2a4695f545071

โดยปกติแล้ว validators พื้นฐาน ทาง browser และ angular ก็เตรียมมาให้แล้วพอสมควร แต่ก็ขึ้นอยู่กับความต้องการของเราที่จะเลือกใช้

…แต่ถ้าเกิดมันไม่มีที่เราต้องการหละ!!! ทำไงดี? เราก็ต้องสร้าง validators ขึ้นมาเอง

บทความนี้จะยกตัวอย่าง validators คำต้องห้าม หรือพูดง่ายๆ ก็คือ ห้ามตั้ง username ที่มีชื่อตรงกับคำเหล่านี้ >> bamossza, admin, superadmin

ก่อนอื่นต้องขอบอกก่อนนะครับ ว่าผมใช้ css bootstrap เพื่อให้ UI สวยงาม

ดูวิธีติดตั้งและใช้งานได้ที่นี่

และใช้วิธีการสร้างฟอร์มแบบ Reactive Form

อ่านบทความเพิ่มเติมได้ที่นี่

เรามาเริ่มลุยกันเลยค้าบโผมมมมม …….

เพื่อไม่ให้เสียเวลาในการ Design ใช้วิธีการ Copy and Paste เอาครับ

Step 1 : เปิดไฟล์ app.component.html แล้วเขียนโค้ดดังนี้

<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand">Project name</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">

</ul>
</div><!--/.nav-collapse -->
</div>
</nav>

<div class="container" style="padding-top: 60px;">
<h3>Example Custom Validators</h3>
<br>
<div class="row">
<div class="col-md-5">
<form>
<div class="form-group">
<label for="username">Username</label>
<input type="text"
id="username"
class="form-control">
<span class="help-block">Please enter a valid Username!</span>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password"
id="password"
class="form-control">
</div>
<button
class="btn btn-primary"
type="submit">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> ลงทะเบียน
</button>
</form>
</div>
</div>
<hr>
</div>

<footer class="footer">
<div class="container">
<p class="text-muted">Tutorial By bamossza</p>
</div>
</footer>

รันดูผลลัพธ์

เรียบร้อยสำหรับ Design จากนั้นเรามาเริ่มลุยกันเลยค้าบบบบบ

Step 2 : เปิดไฟล์ app.component.html แล้วเขียนโค้ดดังนี้

เพิ่ม attribute >> formControlName="" >> element input>> username input
<label for="username">Username</label>
<input type="text"
id="username"
class="form-control"
formControlName="username">
>> password input
<label for="password">Password</label>
<input type="password"
id="password"
class="form-control"
formControlName="password">

Step 3 : เปิดไฟล์ app.component.ts แล้วเขียนโค้ดดังนี้

>>>> ส่วนที่ 1

ประกาศตัวแปรของฟอร์ม
registerForm: FormGroup;
ประกาศตัวแปรคำต้องห้าม
forbiddenUsernames = ['bamossza', 'admin', 'superadmin'];

>>>> ส่วนที่ 2

ngOnInit() {
this.registerForm = new FormGroup({
'username': new FormControl(null, Validators.required),
'password': new FormControl(null, Validators.required)
});
}

>>>> ส่วนที่ 3

สร้างฟังก์ชั่นสำหรับตรวจสอบคำต้องห้ามแล้ว return เป็น object ออกมา
forbiddenNames(control: FormControl): { [s: string]: boolean } {
if (this.forbiddenUsernames.indexOf(control.value) !== -1) {
return {'forbiddenNames': true};
}
return null;
}

>>>> ส่วนที่ 4

เปลี่ยนแปลงโค้ดจากส่วนที่ 2>> จาก
'username': new FormControl(null, Validators.required)
>> เป็น
'username': new FormControl(null, [Validators.required, this.forbiddenNames.bind(this)])
ก็คือเพิ่ม Validator ที่เราสร้างขึ้นใหม่เข้าไปถ้ามีอีกก็สามารถเขียนเพิ่มได้เรื่อยๆ ครับ

Step 4 : เปิดไฟล์ app.component.html แล้วเขียนโค้ดดังนี้

จากโค้ดนี้
<span class="help-block">Please enter a valid Username!</span>
เขียนโค้ดเพิ่ม
<span class="help-block"
*ngIf="!registerForm.get('username').valid
&& registerForm.get('username').touched"
>Please enter a valid Username!</span>
*เช็คว่าฟอร์มถูกต้องหรือไม่ ถ้าไม่จะแสดง Please enter a valid Username!

Step 5 : เปิดไฟล์ app.component.css แล้วเขียนโค้ดดังนี้

input.ng-invalid.ng-touched{
border: solid 1px red;
}
*ถ้าฟอร์มยังไม่ถูกต้องจะแสดงกรอบสีแดง

ทีนี้เราลองมารันดูผลลัพธ์กัน

1 >> คลิกแล้วไม่กรอกอะไรเลยจะแสดงกรอบสีแดงพร้อมข้อความ

form invalid

2 >> ลองกรอกคำว่า “Test”

form valid

3 >> ลองกรอกคำว่า “admin” หรือ “bamossza” หรือ “superadmin”

form invalid

จะเห็นได้ว่าช่องกรอก username จะถูก validators ตลอดเวลา

เรียบร้อยแล้วครับ สามารถนำไปประยุกต์ต่อได้เลยนะครับ

โค้ดรวมทั้งหมด

app.component.ts

import {Component, OnInit} from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms';

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

registerForm: FormGroup;
forbiddenUsernames = ['bamossza', 'admin', 'superadmin'];

constructor() {
}

ngOnInit() {
this.registerForm = new FormGroup({
'username': new FormControl(null, [Validators.required, this.forbiddenNames.bind(this)]),
'password': new FormControl(null, Validators.required)
});
}

forbiddenNames(control: FormControl): { [s: string]: boolean } {

if (this.forbiddenUsernames.indexOf(control.value) !== -1) {
return {'forbiddenNames': true};
}
return null;
}
}

app.component.html

<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand">Project name</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">

</ul>
</div><!--/.nav-collapse -->
</div>
</nav>

<div class="container" style="padding-top: 60px;">
<h3>Example Custom Validators</h3>
<br>
<div class="row">
<div class="col-md-5">
<form [formGroup]="registerForm">
<div class="form-group">
<label for="username">Username</label>
<input type="text"
id="username"
class="form-control"
formControlName="username">
<span class="help-block"
*ngIf="!registerForm.get('username').valid
&& registerForm.get('username').touched">Please enter a valid Username!</span>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password"
id="password"
class="form-control"
formControlName="password">
</div>
<button
class="btn btn-primary"
type="submit">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> ลงทะเบียน
</button>
</form>
</div>
</div>
<hr>
</div>

<footer class="footer">
<div class="container">
<p class="text-muted">Tutorial By bamossza</p>
</div>
</footer>

app.module.ts

import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';

import {AppComponent} from './app.component';

@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule,
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}

— — — — — — — -^^ — — — — — — — — :P

หวังว่าเป็นบทความที่มีความรู้ และสามารถพาท่านเรียนรู้ได้จนเข้าใจ

ตัวอย่างโค้ดโปรเจค ดูได้ที่นี่_CLICK

Reference
https://angular.io
https://cli.angular.io
https://angular.io/guide/form-validation

หากมีข้อผิดพลาดประการใดต้องขออภัยมา ณ ที่นี้ด้วยนะครับ
Thank you so much.

--

--