handling forms in sayan unankard angular apps … · 2017-09-08 · 2 approaches •...

32
www.itsci.mju.ac.th/sayan HANDLING FORMS IN ANGULAR APPS SAYAN UNANKARD 1/2560 3

Upload: others

Post on 03-Jun-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

w w w . i t s c i . m j u . a c . t h / s a y a n

HANDLING FORMS IN ANGULAR APPS

SAYAN UNANKARD1/2560

3

Page 2: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

ANGULAR AND FORMS

<form>

<label>name</label>

<input type=“text” name=“stuname”>

<label>email</label>

<input type=“text” name=“stuemail”>

<button type=“submit”>Save</button>

</form>

{

value : {

stuname : ‘sayan’,

stuemail : ‘[email protected]

}

valid : true

}

2

Page 3: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

2 APPROACHES

• Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก DOM

• Reactive โปรแกรมเมอรตองเขียนโครงสรางดวย Typescript เพ่ือไปจัดการ DOM เอง

3

Page 4: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

TEMPLATE-DRIVEN

ตองการสรางหนาจอสําหรับกรอกขอมูลดังน้ี

4

Page 5: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

TEMPLATE-DRIVEN

ในสวนของ app.component.html สราง tag form โดยที่ไมตองระบุ action และ method

ดังนี้

<form><div id="user-data"><label for="username">Username</label><input type="text" id="username" class="form-control"><button class="btn btn-default" type="button">Suggest an

Username</button><label for="email">Mail</label><input type="email" id="email" class="form-control"><label for="secret">Secret Questions</label><select id="secret" class="form-control">

<option value="pet">Your first Pet?</option><option value="teacher">Your first teacher?</option>

</select></div><button class="btn btn-primary" type="submit">Submit</button>

</form>

หมายเหตุ css ไมไดกําหนดลงไปในตัวอยาง5

Page 6: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

TEMPLATE-DRIVEN

ในการควบคุม Form สามารถกําหนด attribute โดยระบุ ngModel และ name เขาไปใน DOM

objects ดังนี้

<input type="text" id="username" class="form-control"ngModel name="username">

<input type="email" id="email" class="form-control“ngModel name="email">

<select id="secret" class="form-control" [ngModel]="defaultQuestion" name="secret">

<option value="pet">Your first Pet?</option><option value="teacher">Your first teacher?</option>

</select>

6

Page 7: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

TEMPLATE-DRIVEN

ในสวนของปุม submit สามารถกําหนดใหเรียกใช method ที่สรางขึ้นมาได ดังนี้

เมื่อมีการกดปุม submit ใหไปเรียกใช method onSubmit() โดยสงคาตัวแปร frm เขาไป ซึ่งตัว

แปร frm ถูกกําหนดคาใหเปน ngForm

Method onSubmit() ใน ไฟล

app.component.ts

<form (ngSubmit)="onSubmit(frm)" #frm="ngForm">

import { Component} from '@angular/core';import { NgForm } from '@angular/forms';

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

})export class AppComponent {title = 'app works!';

onSubmit(frm : NgForm){console.log(frm);

}}

7

Page 8: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

TEMPLATE-DRIVEN

8

Page 9: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

TEMPLATE-DRIVEN

ตัวแปรประเภท local reference โดยใช @ViewChild แทนการสงพารามิเตอรใน onSubmit()

โดยเพิ่มตัวแปร @ViewChild() ในไฟล app.component.ts

<form (ngSubmit)="onSubmit()" #frm="ngForm">

import { Component, ViewChild } from '@angular/core';import { NgForm } from '@angular/forms';

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

})export class AppComponent {title = 'app works!';@ViewChild('frm') signfrm : NgForm;

onSubmit(){console.log(this.signfrm);

}} 9

Page 10: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

VALIDATION TO CHECK USER INPUT

สามารถกําหนดรูปแบบการตรวจสอบการปอนขอมูลของผูใชได โดยการเพิ่ม attribute เชน

required หรือ email เขาไปใน INPUT objects

ในกรณีที่กรอกขอมูลไมถูกตองตามรูปแบบที่กําหนด attribute ที่ชื่อวา valid จะมีคาเปน false

<input type="text" id="username" class="form-control"ngModel name="username" required >

<input type="email" id="email" class="form-control"ngModel name="email" required email >

<input type="fullname" id="fullname" class="form-control"ngModel name="fullname" required pattern="[a-zA-Z ]*" >

10

Page 11: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

VALIDATION TO CHECK USER INPUT

11

Page 12: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

VALIDATION TO CHECK USER INPUT

โดยในสวนของ DOM elements จะมีการเพ่ิม attributes เชน ng-invalid ใน input object นั้น ๆ

ที่ผูใชกรอกขอมูลไมตรงรูปแบบ

12

Page 13: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

VALIDATION TO CHECK USER INPUT

สามารถกําหนดใหปุม submit disabled ถาผูใชกรอกขอมูลไมถูกตองตามรูปแบบที่กําหนด

อีกทั้งยังสามารถกําหนดขอความแจงเตือนผูใชไดดังนี้

เพิ่มตัวแปร reference #email และใชคําส่ัง ngIf ในการตรวจสอบ properties ของ email วา

valid หรือไม และ email เคยเขาไปกรอกแลวหรือไม

<button class="btn btn-primary" type="submit" [disabled]="!frm.valid">Submit</button>

<label for="email">Mail</label><input type="email" id="email" class="form-control" ngModel name="email" required email #email="ngModel">

<span class="help-block" *ngIf="!email.valid && email.touched">Please enter a valid email!</span>

13

Page 14: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

VALIDATION TO CHECK USER INPUT

14

Page 15: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

SET DEFAULT VALUE

การกําหนดคาเริ่มตนของ dropdown list ก็สามารถทําไดโดยการกําหนด property ดังนี้

<select id="secret"class="form-control" [ngModel]="defaultQuestion" name="secret">

<option value="pet">Your first Pet?</option><option value="teacher">Your first teacher?</option>

</select>

import { Component, ViewChild } from '@angular/core';import { NgForm } from '@angular/forms';

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

})export class AppComponent {defaultQuestion = 'pet';@ViewChild('frm') signfrm : NgForm;

...}

15

Page 16: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

USING NGMODEL 2-WAYS BINDING

ในกรณีที่ตองการเพ่ิมคําตอบของคําถามลับ (Secret Question) สามารถกําหนดใหเปน 2-way

binding ได โดยใช ngModel ดังนี้<div class="form-group">

<textarea name="questionAnswer" rows=3 class="form-control" [(ngModel)]="answer"></textarea>

</div><p>Your reply : {{answer}}</p>

import { Component, ViewChild } from '@angular/core';import { NgForm } from '@angular/forms';...

export class AppComponent {defaultQuestion = 'pet';@ViewChild('frm') signfrm : NgForm;answer = '';

...}

16

Page 17: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

USING NGMODEL 2-WAYS BINDING

17

Page 18: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

HANDLING RADIO BUTTON

การจัดการ Radio button สามารถทําไดเชนเดียวกับ input อ่ืน ๆ โดยสามารถกําหนดคาดังน้ี

Loop แสดง radio buttom ตามคาใน genders array

export class AppComponent {@ViewChild('frm') signfrm : NgForm;defaultQuestion = 'pet';answer = '';genders = ['male', 'female'];

onSubmit(){console.log(this.signfrm);

}}

<div class="radio" *ngFor="let gender of genders"><label><input type="radio" name="gender" ngModel [value]="gender" required>{{ gender }}

</label></div>

18

Page 19: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

BUTTON CLICK

การจัดการเมื่อมีการคลิกปุมที่ไมใช submit สามารถสราง method แลวเรียกใชดวยคําส่ัง (click)

ไดดังนี้

คําสั่ง this.signfrm.form.patchValue() เปนการเปล่ียนแปลงคาเฉพาะสวนที่ตองการ เพ่ือไมให

กระทบกับสวนอ่ืน ๆ ที่กรอกขอมูลไปแลว

suggestUserName() {const suggestedName = 'Superuser';this.signfrm.form.patchValue({username: suggestedName

});}

}

<button class="btn btn-default" type="button" (click)="suggestUserName()">Suggest an Username</button>

19

Page 20: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

USING FORM DATA

การเรียกใชงานขอมูลจาก Form object สามารถทําไดโดยการประกาศตัวแปร เพ่ือเก็บคาขอมูล

จาก Form ไดดังนี้ โดยที่ชื่อตัวแปรไมจําเปนตองตรงกับชื่อของ form objects

การอานคาจาก Form สามารถทําไดโดยอางตัวแปร this.ชื่อตัวแปร form.value.ชื่อ form object

user = {username: '',email: '',secretQuestion: '',answer: '',gender: ''

};

onSubmit(){this.submitted = true;this.user.username = this.signfrm.value.username;this.user.email = this.signfrm.value.email;this.user.secretQuestion = this.signfrm.value.secret;this.user.answer = this.signfrm.value.questionAnswer;this.user.gender = this.signfrm.value.gender;

this.signfrm.reset();} 20

Page 21: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

USING FORM DATA

สามารถเรียกดูคาจากตัวแปรท่ีรับคามาจาก form object ไดโดยแสดงผานทางหนาจอ ดังนี้

<hr><div class="row" *ngIf="submitted"><div class="col-xs-12"><h3>Your Data</h3><p>Username: {{ user.username }}</p><p>Mail: {{ user.email }}</p><p>Secret Question: Your first {{ user.secretQuestion }}</p><p>Answer: {{ user.answer }}</p><p>Gender: {{ user.gender }}</p>

</div></div>

21

Page 22: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

EXERCISE

จงสรางหนาจอตอไปนี้โดยใช Angular4

22

Page 23: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

REACTIVE APPROACH

Reactive approach เปนอีกวิธีการในการจัดการ Form ใน Angular <form><div class="form-group"><label for="username">Username</label><input type="text" id="username"class="form-control">

</div><div class="form-group"><label for="email">email</label><input type="text" id="email"class="form-control">

</div><div class="radio"

*ngFor="let gender of genders"><label><input type="radio"[value]="gender">{{ gender }}

</label></div><button class="btn btn-primary" type="submit">Submit</button>

</form>

23

Page 24: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

REACTIVE APPROACH

ในสวนของ app.module.ts การทํางานดวย Reactive ไมจําเปนตองใช FormsModule แตจะใช

ReactiveFormsModule แทน

import { BrowserModule } from '@angular/platform-browser';import { NgModule } from '@angular/core';import { FormsModule } from '@angular/forms';import { ReactiveFormsModule } from '@angular/forms';import { HttpModule } from '@angular/http';import { AppComponent } from './app.component';

@NgModule({declarations: [AppComponent

],imports: [BrowserModule,FormsModule,HttpModule,ReactiveFormsModule

],...

}) 24

Page 25: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

REACTIVE APPROACH

การกําหนดคาระหวาง HTML และ Typescript สามารถทําไดดังนี้

ที่ไฟล app.component.ts ประกาศตัวแปร signupForm เปนตัวแปรประเภท FormGroup

จากนั้นสราง method ngOnInit() สําหรับกําหนดคาเร่ิมตนของ FormControl ตาง ๆ ในหนาจอ

export class AppComponent implements OnInit {genders = ['male', 'female'];signupForm: FormGroup;

ngOnInit() {this.signupForm = new FormGroup({'username': new FormControl(null),'email': new FormControl(null),'gender': new FormControl('male')

});}

}

25

Page 26: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

REACTIVE APPROACH

ในสวนของหนาจอ html จะตองระบุชื่อของ form control ใหตรงกันกับในคลาส<form [formGroup]="signupForm"><div class="form-group"><label for="username">Username</label><input type="text" id="username" formControlName="username"class="form-control">

</div><div class="form-group"><label for="email">email</label><input type="text" id="email" formControlName="email"class="form-control">

</div><div class="radio" *ngFor="let gender of genders"><label><input type="radio" formControlName="gender"[value]="gender">{{ gender }}

</label></div><button class="btn btn-primary" type="submit">Submit</button>

</form>

26

Page 27: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

REACTIVE APPROACH

ในกรณีที่ตองการเพิ่มการเรียกใชเมื่อมีการกดปุม submit สามารถกําหนด property ของ form ได

ดังนี้

<form [formGroup]="signupForm" (ngSubmit)="onSubmit()">

onSubmit(){console.log(this.signupForm);

}

27

Page 28: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

REACTIVE APPROACH FOR VALIDATION

การกําหนด Validation สําหรับตรวจสอบเงื่อนไขการกรอกขอมูลสามารถทําไดโดยกําหนด

Validator เชน Validator.required หรือ Validator.email เปนตน

ในกรณีที่ตองการแสดงขอความแจงเตือนสามารถกําหนดไดดังนี้

ngOnInit() {this.signupForm = new FormGroup({'username': new FormControl(null, Validators.required),'email': new FormControl(null, [Validators.required, Validators.email]),'gender': new FormControl('male')

});}

<span *ngIf="!signupForm.get('email').valid && signupForm.get('email').touched"

class="help-block">Please enter a valid email!</span>

28

Page 29: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

ARRAY OF FORM CONTROL

ในกรณีที่ตองการสราง Form Control ที่มีลักษณะ Dynamic ตามความตองการของผูใช เชน หาก

ผูใชตองการเพ่ิมขึ้นมูลงานอดิเรก (Hobby) สามารถที่จะกรอกไดหลายรายการ

ขั้นตอนที่ 1 สราง formArrayName ชื่อวา hobbies โดยมีปุม Add และ loop แสดง Textbox

ตามจํานวนคร้ังที่กดปุม

<div formArrayName="hobbies"><h4>Your Hobbies</h4><button class="btn btn-default" type="button"

(click)="onAddHobby()">Add Hobby</button><div class="form-group" *ngFor="let hobbyControl of

signupForm.get('hobbies').controls; let i = index"><input type="text" class="form-control" [formControlName]="i">

</div></div>

29

Page 30: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

ARRAY OF FORM CONTROL

ที่ method ngOnInit() เพ่ิมตัวแปร hobbies มีชนิดเปน FormArray

ขั้นตอนที่ 2 เพ่ิม method สําหรับกดปุม Add Hobby

ngOnInit() {this.signupForm = new FormGroup({'username': new FormControl(null, Validators.required),'email': new FormControl(null, [Validators.required, Validators.email]),'gender': new FormControl('male'),'hobbies': new FormArray([])

});}

onAddHobby() {const control = new FormControl(null, Validators.required);(<FormArray>this.signupForm.get('hobbies')).push(control);

}

30

Page 31: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

31

Page 32: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS … · 2017-09-08 · 2 APPROACHES • Template-Driven โดยที่ Angular จะสรุปจาก (infers) form objects จาก

ARRAY OF FORM CONTROL

ในสวนของการนําคาไปใชงานสามารถทําได ดังนี้

<hr><div class="row" *ngIf="submitted"><div class="col-xs-12"><h3>Your Data</h3><p>Username: {{ signupForm.value.username }}</p><p>Mail: {{ signupForm.value.email }}</p><p>Gender: {{ signupForm.value.gender }}</p><p>Hobbies: </p><div *ngFor="let hobby of signupForm.value.hobbies">

{{hobby}}</div>

</div>

32