32
www.itsci.mju.ac.th/sayan HANDLING FORMS IN ANGULAR APPS SAYAN UNANKARD 2/2559 8

HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

www . i t s c i .m ju . ac . t h / sayan

HANDLING FORMS IN ANGULAR APPS

SAYAN UNANKARD2/2559

8

Page 2: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

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>

2

{value : {

stuname : ‘sayan’,stuemail : ‘[email protected]

}valid : true

}

Page 3: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

2 APPROACHES

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

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

3

Page 4: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

TEMPLATE-DRIVEN

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

4

Page 5: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

TEMPLATE-DRIVEN

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

5

<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 ไม่ได้ก าหนดลงไปในตัวอย่าง

Page 6: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

TEMPLATE-DRIVEN

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

6

<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>

Page 7: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

TEMPLATE-DRIVEN

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

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

Method onSubmit() ใน ไฟล์app.component.ts

7

<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);

}

}

Page 8: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

TEMPLATE-DRIVEN

8

Page 9: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

TEMPLATE-DRIVEN

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

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

9

<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);

}

}

Page 10: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

VALIDATION TO CHECK USER INPUT

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

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

10

<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 >

Page 11: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

VALIDATION TO CHECK USER INPUT

11

Page 12: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

VALIDATION TO CHECK USER INPUT

โดยในส่วนของ DOM elements จะมีการเพิ่ม attributes เช่น ng-invalid ใน input object นั้น ๆ ที่ผู้ใช้กรอกข้อมูลไม่ตรงรูปแบบ

12

Page 13: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

VALIDATION TO CHECK USER INPUT

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

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

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

13

<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>

Page 14: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

VALIDATION TO CHECK USER INPUT

14

Page 15: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

SET DEFAULT VALUE

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

15

<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;

...

}

Page 16: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

USING NGMODEL 2-WAYS BINDING

ในกรณีที่ต้องการเพิ่มค าตอบของค าถามลับ (Secret Question) สามารถก าหนดให้เป็น 2-way binding ได้ โดยใช้ ngModel ดังนี้

16

<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 = '';

...

}

Page 17: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

USING NGMODEL 2-WAYS BINDING

17

Page 18: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

HANDLING RADIO BUTTON

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

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

18

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>

Page 19: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

BUTTON CLICK

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

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

19

suggestUserName() {

const suggestedName = 'Superuser';

this.signfrm.form.patchValue({

username: suggestedName

});

}

}

<button class="btn btn-default" type="button"

(click)="suggestUserName()">Suggest an Username</button>

Page 20: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

USING FORM DATA

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

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

20

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();

}

Page 21: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

USING FORM DATA

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

21

<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>

Page 22: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

EXERCISE

22

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

Page 23: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

REACTIVE APPROACH

Reactive approach เป็นอีกวิธีการในการจัดการ Form ใน Angular

23

<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>

Page 24: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

REACTIVE APPROACH

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

24

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

],

...

})

Page 25: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

REACTIVE APPROACH

การก าหนดค่าระหว่าง HTML และ Typescript สามารถท าได้ดังนี้ที่ไฟล์ app.component.ts ประกาศตัวแปร signupForm เป็นตัวแปรประเภท FormGroupจากนั้นสร้าง method ngOnInit() ส าหรับก าหนดค่าเริ่มต้นของ FormControl ต่าง ๆ ในหน้าจอ

25

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')

});

}

}

Page 26: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

REACTIVE APPROACH

ในส่วนของหน้าจอ html จะต้องระบุชื่อของ form control ให้ตรงกันกับในคลาส

26

<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>

Page 27: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

REACTIVE APPROACH

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

27

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

onSubmit(){

console.log(this.signupForm);

}

Page 28: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

REACTIVE APPROACH FOR VALIDATION

การก าหนด Validation ส าหรับตรวจสอบเงื่อนไขการกรอกข้อมูลสามารถท าได้โดยก าหนด Validator เช่น Validator.required หรือ Validator.email เป็นต้น

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

28

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>

Page 29: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

ARRAY OF FORM CONTROL

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

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

29

<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>

Page 30: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

ARRAY OF FORM CONTROL

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

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

30

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);

}

Page 31: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

31

Page 32: HANDLING FORMS IN SAYAN UNANKARD ANGULAR APPS 2… Angular2.pdf · using ngmodel 2-ways binding ในกรณีที่ต้องการเพิ่มค าตอบของค

ARRAY OF FORM CONTROL

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

32

<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>