Pengenalan Form di Angular 4: Template-Driven Forms
() translation by (you can also view the original English article)



Form sangat penting untuk aplikasi front-end modern manapun, dan ini adalah fitur yang kita gunakan setiap hari, bahkan jika tidak menyadarinya. Form diperlukan untuk login dengan aman di pengguna ke aplikasi, mencari semua hotel yang ada di kota tertentu, memesan taksi, membuat daftar tugas, dan melakukan banyak hal lain yang biasa kita lakukan. Beberapa form hanya memiliki beberapa field input, sedangkan bentuk lainnya bisa memiliki field suatu array yang membentang ke beberapa halaman atau tab.
Dalam tutorial ini, kita akan membahas strategi yang berbeda yang tersedia untuk mengembangkan form di Angular. Terlepas dari strategi yang kamu pilih, berikut adalah hal-hal yang harus disertakan oleh library;
- Dukung pengikatan dua-arah sehingga nilai kontrol input disinkronkan dengan state komponen.
- Lacak keadaan form dan gunakan isyarat visual agar pengguna tahu apakah keadaan saat ini benar atau tidak. Misalnya, jika nama pengguna memiliki karakter yang tidak valid, border merah harus muncul di sekitar kolom input untuk username.
- Memiliki mekanisme untuk menampilkan validasi error dengan benar.
- Mengaktifkan atau menonaktifkan bagian-bagian tertentu dari form kecuali beberapa kriteria validasi terpenuhi.
Pengenalan Form di Angular
Sudut, menjadi framework front-end penuh, memiliki kumpulan library tersendiri untuk membangun form yang kompleks. Versi terbaru dari Angular memiliki dua strategi pembuatan form yang powerful. Mereka adalah:
- template-driven forms
- model-driven atau reactive forms
Kedua teknologi tersebut milik libary @angulat/forms
dan didasarkan pada class kontrol form yang sama. Namun, mereka sangat berbeda dalam filosofi, gaya pemrograman, dan teknik mereka. Memilih satu dari yang lain tergantung pada selera pribadimu dan juga pada kompleksitas form yang ingin kamu ciptakan. Menurut pendapat saya, kamu harus mencoba kedua pendekatan terlebih dahulu dan kemudian memilih yang sesuai dengan gaya dan proyek yang kamu hadapi.
Bagian pertama dari tutorial ini akan mencakup template-driven forms dengan contoh praktis: membuat form pendaftaran dengan validasi untuk semua field form. Pada bagian kedua dari tutorial ini, kita akan menelusuri kembali langkah-langkah untuk membuat form bentuk yang sama dengan menggunakan pendekatan model-driven.
Template-Driven Forms
Pendekatan template-driven adalah strategi yang dipinjam dari era AngularJS. Menurut pendapat saya, ini adalah metode paling sederhana untuk membuat form. Bagaimana cara kerjanya? Kita akan menggunakan beberapa directive Angular.
Directive memungkinkanmu untuk melampirkan tindakan ke elemen di DOM.
— Dokumentasi Angular
Angular menyediakan directive spesifik-form yang bisa kamu gunakan untuk mengikat data inputan form dan model. Directive spesifik-form menambahkan fungsionalitas dan tindakan ekstra ke bentuk HTML biasa. Hasil akhirnya adalah bahwa template menangani nilai-nilai yang mengikat dengan model dan validasi form.
Dalam tutorial ini, kita akan menggunakan template-driven forms untuk membuat halaman pendaftaran aplikasi. Form akan mencakup elemen form yang paling umum dan pemeriksaan validasi yang berbeda pada elemen formulir ini. Berikut adalah langkah-langkah yang akan anda ikuti di tutorial ini.
- Tambahkan FormsModule ke
app.module.ts
. - Buat suatu class untuk model User.
- Buat komponen dan layout awal untuk form pendaftaran.
- Gunakan directive form Angular seperti
ngModel
,ngModelGroup
, danngForm
. - Tambahkan validasi menggunakan validator bawaan.
- Tampilkan error validasi dengan penuh makna.
- Tangani pengiriman formulir menggunakan
ngSubmit
.
Mari kita mulai.
Prasyarat
Kode untuk proyek ini tersedia di repo GitHub saya. Download zip atau kloning repo untuk melihatnya beraksi. Jika kamu lebih memilih untuk memulai dari awal, pastikan kamu telah menginstal CLI Angular. Gunakan perintah ng
untuk membuat proyek baru.
1 |
$ ng new SignupFormProject |
Selanjutnya, buat komponen baru untuk SignupForm.
1 |
ng generate component SignupForm |
Ganti isi app.component.html dengan ini:
1 |
<app-signup-form> </app-signup-form> |
Berikut adalah struktur direktori untuk direktori src/. Saya telah menghapus beberapa file yang tidak penting agar semuanya tetap sederhana.
1 |
. |
2 |
├── app |
3 |
│ ├── app.component.css |
4 |
│ ├── app.component.html |
5 |
│ ├── app.component.ts |
6 |
│ ├── app.module.ts |
7 |
│ ├── signup-form |
8 |
│ │ ├── signup-form.component.css |
9 |
│ │ ├── signup-form.component.html |
10 |
│ │ └── signup-form.component.ts |
11 |
│ └── User.ts |
12 |
├── index.html |
13 |
├── main.ts |
14 |
├── polyfills.ts |
15 |
├── styles.css |
16 |
├── tsconfig.app.json |
17 |
└── typings.d.ts |
Seperti yang dapat kamu lihat, sebuah direktori untuk komponen SignupForm
telah dibuat secara otomatis. Di situlah sebagian besar kode kita akan tertuju. Saya juga telah membuat User.ts
baru untuk menyimpan model User kita.
Template HTML
Sebelum kita menyelami template komponen yang sebenarnya, kita perlu memiliki gagasan abstrak tentang apa yang sedang kita bangun. Jadi, inilah bentuk struktur yang ada dalam pikiran saya. Form pendaftaran akan memiliki beberapa field inputan, elemen select, dan elemen checkbox.
Berikut adalah template HTML yang akan kita gunakan untuk halaman registrasi kita.
Template HTML
1 |
<div class="row custom-row"> |
2 |
<div class= "col-sm-5 custom-container jumbotron"> |
3 |
|
4 |
<form class="form-horizontal"> |
5 |
<fieldset>
|
6 |
<legend>SignUp</legend> |
7 |
|
8 |
<!--- Email Block --->
|
9 |
<div class="form-group"> |
10 |
<label for="inputEmail">Email</label> |
11 |
<input type="text" |
12 |
id="inputEmail" |
13 |
placeholder="Email"> |
14 |
</div>
|
15 |
<!--- Password Block --->
|
16 |
<div class="form-group"> |
17 |
<label for="inputPassword">Password</label> |
18 |
<input type="password" |
19 |
id="inputPassword" |
20 |
placeholder="Password"> |
21 |
</div>
|
22 |
|
23 |
<div class="form-group"> |
24 |
<label for="confirmPassword" >Confirm Password</label> |
25 |
<input type="password" |
26 |
id="confirmPassword" |
27 |
placeholder="Password"> |
28 |
</div>
|
29 |
|
30 |
<!--- Select gender Block --->
|
31 |
<div class="form-group"> |
32 |
<label for="select">Gender</label> |
33 |
<select id="select"> |
34 |
<option>Male</option> |
35 |
<option>Female</option> |
36 |
<option>Other</option> |
37 |
</select>
|
38 |
</div>
|
39 |
|
40 |
<!--- Terms and conditions Block --->
|
41 |
<div class="form-group checkbox"> |
42 |
<label>
|
43 |
<input type="checkbox"> Confirm that you've read the Terms and |
44 |
Conditions |
45 |
</label>
|
46 |
</div>
|
47 |
|
48 |
<!--- Buttons Block --->
|
49 |
<div class="form-group"> |
50 |
<button type="reset" class="btn btn-default">Cancel</button> |
51 |
<button type="submit" class="btn btn-primary">Submit</button> |
52 |
</div>
|
53 |
</fieldset>
|
54 |
</form>
|
55 |
</div>
|
56 |
</div>
|
Class CSS yang digunakan dalam template HTML adalah bagian dari library Bootstrap yang digunakan untuk membuat semuanya menjadi menarik. Karena ini bukan tutorial desain, saya tidak akan banyak membicarakan aspek CSS dari form kecuali jika diperlukan.
Dasar Pengaturan Form
Untuk menggunakan directive template-driven form, kita perlu mengimpor FormsModule
dar @angular/forms
dan menambahkannya ke array imports
di app.module.ts
.
app/app.module.ts
1 |
import { FormsModule } from '@angular/forms'; |
2 |
|
3 |
@NgModule({ |
4 |
.
|
5 |
.
|
6 |
imports: [ |
7 |
BrowserModule, |
8 |
FormsModule
|
9 |
],
|
10 |
.
|
11 |
.
|
12 |
})
|
13 |
export class AppModule { } |
Selanjutnya, buat class yang akan menampung semua properti entitas User. Kita bisa menggunakan antarmuka dan menerapkannya di komponen atau menggunakan kelas TypeScript untuk modelnya.
app/User.ts
1 |
export class User { |
2 |
|
3 |
id: number; |
4 |
email: string; |
5 |
//Both the passwords are in a single object
|
6 |
password: { |
7 |
pwd: string; |
8 |
confirmPwd: string; |
9 |
};
|
10 |
gender: string; |
11 |
terms: boolean; |
12 |
|
13 |
constructor(values: Object = {}) { |
14 |
//Constructor initialization
|
15 |
Object.assign(this, values); |
16 |
}
|
17 |
|
18 |
}
|
Sekarang, buat sebuah instance dari class di komponen SignupForm. Saya juga telah mendeklarasikan sebuah properti tambahan untuk jenis kelamin.
app/signup-form/signup-form.component.ts
1 |
import { Component, OnInit } from '@angular/core'; |
2 |
// Import the User model
|
3 |
import { User } from './../User'; |
4 |
|
5 |
@Component({ |
6 |
selector: 'app-signup-form', |
7 |
templateUrl: './signup-form.component.html', |
8 |
styleUrls: ['./signup-form.component.css'] |
9 |
})
|
10 |
export class SignupFormComponent implements OnInit { |
11 |
|
12 |
//Property for the gender
|
13 |
private gender: string[]; |
14 |
//Property for the user
|
15 |
private user:User; |
16 |
|
17 |
ngOnInit() { |
18 |
|
19 |
this.gender = ['Male', 'Female', 'Others']; |
20 |
//Create a new user object
|
21 |
this.user = new User({ |
22 |
email:"", password: { pwd: "" , confirm_pwd: ""}, |
23 |
gender: this.gender[0], terms: false}); |
24 |
}
|
25 |
|
26 |
}
|
Untuk file signup-form.component.html, saya akan menggunakan template HTML yang sama yang dibahas di atas, namun dengan sedikit perubahan. Form pendaftaran memiliki files select dengan daftar opsi. Meskipun itu berhasil, kita akan melakukannya dengan cara Angular dengan melakukan perulangan pada daftar menggunakan directive ngFor
.
app/signup-form/signup-form.component.html
1 |
<div class="row custom-row"> |
2 |
<div class= "col-sm-5 custom-container jumbotron"> |
3 |
|
4 |
<form class="form-horizontal"> |
5 |
<fieldset>
|
6 |
<legend>SignUp</legend> |
7 |
. |
8 |
. |
9 |
<!--- Gender Block -->
|
10 |
<div class="form-group"> |
11 |
<label for="select">Gender</label> |
12 |
<select id="select"> |
13 |
|
14 |
<option *ngFor = "let g of gender" |
15 |
[value] = "g"> {{g}} |
16 |
</option>
|
17 |
</select>
|
18 |
</div>
|
19 |
. |
20 |
. |
21 |
</fieldset>
|
22 |
</form>
|
23 |
</div>
|
24 |
</div>
|
Selanjutnya, kita ingin mengikat data form ke objek class user sehingga ketika kamu memasukkan data pendaftaran ke dalam form, objek User baru dibuat yang menyimpan data sementara. Dengan cara ini, kamu dapat menjaga view tetap sinkron dengan model, dan ini disebut binding.
Ada beberapa cara untuk mewujudkannya. Izinkan saya mengenalkanmu pada ngModel
dan ngForm
.
ngForm dan ngModel
ngForm dan ngModel adalah directive Angular yang penting untuk membuat template-driven forms. Mari kita mulai dengan ngForm
dulu. Berikut adalah kutipan tentang ngForm dari dokumentasi Angular.
DirectiveNgForm
melengkapi elemenform
dengan fitur tambahan. Ini memegang kendali yang kamu buat untuk elemen dengan directivengModel
dan atributname
, dan memonitor properti mereka, termasuk keabsahannya. Ini juga memiliki propertivalid
sendiri yang mana hanya benar jika setiap kontrol yang terkandung itu benar.
Pertama, perbarui form dengan directive ngForm
:
app/signup-form/signup-form.component.html
1 |
<form
|
2 |
class="form-horizontal" |
3 |
#signupForm = "ngForm"> |
4 |
. |
5 |
. |
6 |
</form>
|
#signupForm
adalah variabel referensi template yang mengacu pada directive ngForm
yang mengatur keseluruhan form. Contoh di bawah ini menunjukkan penggunaan objek referensi ngForm
untuk validasi.
app/signup-form/signup-form.component.html
1 |
<button
|
2 |
type="submit" |
3 |
class="btn btn-success" |
4 |
[disabled]="!signupForm.form.valid"> |
5 |
Submit |
6 |
</button>
|
Di sini, signupForm.form.valid
akan mengembalikan nilai false kecuali semua form lolos dari masing-masing pemeriksaan validasi. Tombol submit akan dinonaktifkan sampai form telah valid.
Seperti untuk mengikat template dan modelnya, ada banyak cara untuk melakukan ini, dan ngModel
memiliki tiga sintaks yang berbeda untuk mengatasi situasi ini. Mereka adalah:
- [(ngModel)]
- [(ngModel)]
- ngModel
Mari kita mulai dengan yang pertama.
Two-Way Binding Menggunakan [(ngModel)]
[(ngModel)]
melakukan two-way binding untuk membaca dan menulis nilai kontrol inputan. Jika directive [(ngModel)]
digunakan, field inputan mengambil nilai awal dari class komponen yang terikat dan memperbaruinya kembali setiap kali ada perubahan pada nilai kontrol inputan yang terdeteksi (pada penekanan keyboard dan tombol tekan). Gambar di bawah menggambarkan proses two-way binding dengan lebih baik.



Berikut adalah kode untuk field inputan email:
1 |
<div class="form-group"> |
2 |
<label for="inputEmail">Email</label> |
3 |
<input type="text" |
4 |
[(ngModel)] = "user.email" |
5 |
id="inputEmail" |
6 |
name="email" |
7 |
placeholder="Email"> |
8 |
</div> |
[(ngModel)] = "user.email"
mengikat properti email pengguna ke nilai inputan. Saya juga menambahkan atribut name dan menetapkan name ="email"
. Ini penting, dan kamu akan mendapatkan error jika kamu tidak menyatakan atribut nama saat menggunakan ngModel.
Demikian pula, tambahkan [(ngModel)]
dan atribut name unik ke setiap elemen form. Formulirmu akan terlihat seperti ini sekarang:
app/signup-form/signup-form.component.html
1 |
. |
2 |
. |
3 |
. |
4 |
<div ngModelGroup="password"> |
5 |
<div class="form-group" > |
6 |
<label for="inputPassword">Password</label> |
7 |
<input type="password" |
8 |
[(ngModel)] = "user.password.pwd" name="pwd" |
9 |
placeholder="Password"> |
10 |
</div>
|
11 |
|
12 |
<div class="form-group"> |
13 |
<label for="confirmPassword" >Confirm Password</label> |
14 |
<input type="password" |
15 |
[(ngModel)] = "user.password.confirmPwd" name="confirmPwd" |
16 |
placeholder="Confirm Password"> |
17 |
</div>
|
18 |
</div>
|
19 |
<div class="form-group"> |
20 |
<label for="select">Gender</label> |
21 |
<select id="select" |
22 |
[(ngModel)] = "user.gender" name = "gender"> |
23 |
|
24 |
<option *ngFor = "let g of gender" |
25 |
[value] = "g"> {{g}} |
26 |
</option>
|
27 |
</select>
|
28 |
</div>
|
29 |
|
30 |
. |
31 |
. |
32 |
. |
ngModelGroup
digunakan untuk mengelompokkan field form yang sama sehingga kita dapat menjalankan validasi hanya pada field form tersebut. Karena kedua field password itu terkait, kita akan menempatkannya di bawah satu ngModelGroup. Jika semuanya bekerja seperti yang diharapkan, properti user
yang terikat komponen harus bertanggung jawab untuk menyimpan semua nilai kontrol form. Untuk melihat ini beraksi, tambahkan berikut ini setelah tag form:
1 |
{{user | json}} |
Salurkan properti pengguna melalui JsonPipe
untuk membuat model sebagai JSON di browser. Ini sangat membantu untuk debugging dan logging. Kamu seharusnya melihat output JSON seperti ini.



Nilainya mengalir dari form ke model. Bagaimana sebaliknya? Cobalah menginisialisasi objek pengguna dengan beberapa nilai.
app/signup-form/signup-form.component.ts
1 |
this.user = new User({ |
2 |
//initialized with some data
|
3 |
email:"thisisfromthemodel@example.com", |
4 |
password: { pwd: "" , confirm_pwd: ""}, |
5 |
gender: this.gender[0] |
6 |
|
7 |
});
|
Dan mereka otomatis akan muncul di view:
1 |
{ "email": "thisisfromthemodel@example.com", |
2 |
"password": { "pwd": "", "confirm_pwd": "" }, |
3 |
"gender": "Male" |
4 |
}
|
Two-way binding [(ngModel)]
membantumu membuat form dengan mudah. Namun, ada kekurangan tertentu; Oleh karena itu, ada pendekatan alternatif yang menggunakan ngModel
atau [ngModel]
.
Menambahkan ngModel ke Mix
Saat ngModel
digunakan, sebenarnya kita bertanggung jawab untuk memperbarui properti komponen dengan nilai kontrol inputan dan sebaliknya. Data inputan tidak secara otomatis mengalir ke dalam komponen properti pengguna.
Jadi ganti semua instance [(ngModel)] = " "
dengan ngModel
. Kita akan menyimpan atribut name
karena ketiga versi ngModel memerlukan atribut name
untuk dapat bekerja.
app/signup-form/signup-form.component.html
1 |
<div class="form-group"> |
2 |
<label for="inputEmail">Email</label> |
3 |
<input type="text" |
4 |
ngModel
|
5 |
id="inputEmail" |
6 |
name="email" |
7 |
placeholder="Email"> |
8 |
</div> |
Dengan ngModel
, nilai atribut nama akan menjadi kunci dari objek referensi ngForm signupForm
yang telah kita buat tadi. Jadi, misalnya, signupForm.value.email
akan menyimpan nilai kontrol untuk id email.
Ganti {{user | json}}
dengan {{signupForm.value | json}}
karena di situlah semua state disimpan sekarang.
One-Way Binding Menggunakan [ngModel]
Bagaimana jika kamu perlu mengatur keadaan awal dari komponen class yang terikat? Itulah yang [ngModel]
lakukan untukmu.



Di sini data mengalir dari model ke view. Buat perubahan berikut pada sintaks untuk menggunakan one-way binding:
app/signup-form/signup-form.component.html
1 |
<div class="form-group"> |
2 |
<label for="inputEmail">Email</label> |
3 |
<input type="text" |
4 |
[ngModel] = "user.email" |
5 |
id="inputEmail" |
6 |
name="email" |
7 |
placeholder="Email"> |
8 |
</div>
|
Jadi pendekatan mana yang harus kamu pilih? Jika kamu menggunakan [(ngModel)]
dan ngForm
bersama-sama, kamu akhirnya akan memiliki dua state untuk dipertahankan—user
dan signupForm.value
—dan itu bisa berpotensi membingungkan.
1 |
{ "email": "thisisfromthemodel@example.com", |
2 |
"password": { "pwd": "thisispassword", "confirm_pwd": "thisispassword" }, |
3 |
"gender": "Male" |
4 |
} //user.value |
5 |
|
6 |
{ "email": "thisisfromthemodel@example.com", |
7 |
"password": { "pwd": "thisispassword", "confirm_pwd": "thisispassword" }, |
8 |
"gender": "Male" |
9 |
} //signupForm.value |
Oleh karena itu, saya akan merekomendasikan menggunakan metode one-way binding. Tetapi itu sesuatu yang bisa kamu putuskan.
Validasi dan Menampilkan Pesan Error
Berikut adalah persyaratan kita untuk validasinya.
- Semua kontrol form diwajibkan.
- Nonaktifkan tombol submit sampai semua field inputan terisi.
- Field email harus berisi id email secara ketat.
- Field password harus memiliki panjang minimum 8.
- Baik password dan konfirmasi harus sesuai.



Yang pertama itu mudah. Kamu harus menambahkan atribut validasi required
ke setiap elemen form seperti ini:
app/signup-form/signup-form.component.html
1 |
<input type="text" |
2 |
[ngModel] = "user.email" name="email" |
3 |
#email = "ngModel" |
4 |
placeholder="Email" |
5 |
required> |
Terlepas dari atribut required
, saya juga telah mengekspor variabel referensi template #email
baru. Hal ini agar kamu bisa mengakses kotak inputan kontrol Angular dari dalam template itu sendiri. Kita akan menggunakannya untuk menampilkan error dan peringatan. Sekarang gunakan tombol properti yang dinonaktifkan untuk menonaktifkan tombol:
app/signup-form/signup-form.component.html
1 |
<button
|
2 |
type="submit" |
3 |
class="btn btn-success" |
4 |
[disabled]="!signupForm.form.valid"> |
5 |
Submit |
6 |
</button>
|
Untuk menambahkan pembatas pada email, gunakan atribut pattern yang sesuai dengan field inputan. Pattern digunakan untuk menentukan reguler expressions seperti di bawah ini:
1 |
pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$" |
Untuk field password, yang harus kamu lakukan adalah menambahkan atribut minlength=" "
:
app/signup-form/signup-form.component.html
1 |
<input type="password" |
2 |
ngModel
|
3 |
id="inputPassword" |
4 |
name="pwd" |
5 |
#pwd = "ngModel" |
6 |
placeholder="Password" |
7 |
minlength="8" |
8 |
required> |
Untuk menampilkan error, saya akan menggunakan directive kondisional ngIf
pada elemen div. Mari kita mulai dengan field kontrol inputan untuk email:
app/signup-form/signup-form.component.html
1 |
<div class="form-group"> |
2 |
<label for="inputEmail">Email</label> |
3 |
<input type="text" |
4 |
[ngModel] = "user.email" name="email" |
5 |
#email = "ngModel" id="inputEmail" |
6 |
placeholder="Email" |
7 |
pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,3}$" |
8 |
required> |
9 |
</div>
|
10 |
|
11 |
<!-- This is the error section -->
|
12 |
|
13 |
<div *ngIf="email.invalid && (email.dirty || email.touched)" |
14 |
class="alert alert-danger"> |
15 |
<div *ngIf = "email.errors?.required"> |
16 |
Email field can't be blank |
17 |
</div>
|
18 |
<div *ngIf = "email.errors?.pattern && email.touched"> |
19 |
The email id doesn't seem right |
20 |
</div>
|
21 |
</div>
|
Ada banyak hal yang terjadi di sini. Mari kita mulai dengan baris pertama dari bagian kesalahan.
1 |
<div *ngIf="email.invalid && (email.dirty || email.touched)" |
2 |
class="alert alert-danger"> |
Ingat bahwa variabel #email
yang kita ekspor tadi? Ini berisi beberapa informasi tentang state kontrol inputan masukan dari field email. Ini termasuk: email.valid
, email.invalid
, email.dirty
, email.pristine
, email.touched
, email.untouched
, dan email.errors
. Gambar di bawah menggambarkan masing-masing sifat tersebut secara rinci.



Jadi elemen div dengan *ngIf
akan diberikan hanya jika email tidak valid. Namun, pengguna akan disambut dengan error tentang field inputan yang kosong bahkan sebelum mereka sempat mengubah form.
Untuk menghindari skenario ini, kita menambahkan kondisi kedua. Kesalahan akan ditampilkan hanya setelah kontrol telah dikunjungi atau nilai kontrol telah diubah.
Elemen-elemen div bersarang digunakan untuk mencakup semua kasus error validasi. Kita menggunakan email.errors
untuk memeriksa semua kemungkinan error validasi dan kemudian menampilkannya kembali ke pengguna dalam bentuk pesan khusus. Sekarang, ikuti prosedur yang sama untuk elemen form lainnya. Berikut adalah cara saya membuat kode validasi untuk password.
app/signup-form/signup-form.component.html
1 |
<div ngModelGroup="password" #userPassword="ngModelGroup" required > |
2 |
<div class="form-group"> |
3 |
<label for="inputPassword">Password</label> |
4 |
<input type="password" |
5 |
ngModel name="pwd" |
6 |
id="inputPassword" placeholder="Password" |
7 |
minlength ="8" required> |
8 |
</div>
|
9 |
|
10 |
<div class="form-group"> |
11 |
<label for="confirmPassword" >Confirm Password</label> |
12 |
<input type="password" |
13 |
ngModel name="confirmPwd" |
14 |
id="confirmPassword" placeholder="Confirm Password"> |
15 |
</div>
|
16 |
|
17 |
|
18 |
<div *ngIf="(userPassword.invalid|| userPassword.value?.pwd != userPassword.value?.confirmPwd) && (userPassword.touched)" |
19 |
class="alert alert-danger"> |
20 |
|
21 |
<div *ngIf = "userPassword.invalid; else nomatch"> |
22 |
Password needs to be more than 8 characters |
23 |
</div>
|
24 |
<ng-template #nomatch > |
25 |
Passwords don't match |
26 |
</ng-template>
|
27 |
</div>
|
28 |
</div>
|
Ini mulai terlihat agak berantakan. Angular memiliki sekumpulan atribut validator yang terbatas: required
, minlength
, maxlength
, dan pattern
. Untuk menutupi skenario lain seperti perbandingan password, Kamu harus bergantung pada kondisional ngIf
bersarang seperti yang saya lakukan di atas. Atau idealnya, buat sebuah fungsi validator khusus, yang akan saya bahas di bagian ketiga dari seri ini.
Dalam kode di atas, saya telah menggunakan sintaks ngIf else
yang diperkenalkan di versi Angular terbaru. Begini cara kerjanya:
1 |
<div *ngIf="isValid;else notvalid"> |
2 |
Valid content... |
3 |
</div>
|
4 |
|
5 |
<ng-template #notValid>Not valid content...</ng-template> |
Mengirimkan Form Menggunakan ngSubmit
Kita sudah hampir menyelesaikan form. Sekarang kita harus bisa mengirimkan form, dan mengatur data form yang harus diserahkan ke metode komponen, katakanlah onFormSubmit()
.
app/signup-form/signup-form.component.ts
1 |
<form novalidate |
2 |
(ngSubmit)="onFormSubmit(signupForm)" |
3 |
#signupForm="ngForm"> |
4 |
... |
Sekarang, untuk komponennya:
app/signup-form/signup-form.component.ts
1 |
...
|
2 |
public onFormSubmit({ value, valid}: { value: User, valid: boolean }) { |
3 |
this.user = value; |
4 |
console.log( this.user); |
5 |
console.log("valid: " + valid); |
6 |
}
|
7 |
...
|
Demo Akhir
Berikut adalah versi terakhir dari aplikasi. Saya telah menambahkan beberapa class bootstrap untuk membuat form menjadi menarik.
Rangkuman
Kita semua sudah selesai disini. Pada tutorial ini, kita telah membahas semua hal yang perlu kamu ketahui tentang membuat form di Angular dengan menggunakan pendekatan template-driven.Form template-driven populer untuk kesederhanaan dan kemudahan penggunaannya.
Namun, jika kamu perlu membuat sebuah form dengan banyak elemen form, pendekatan ini akan menjadi berantakan. Jadi, pada tutorial selanjutnya, kita akan membahas cara model-driven untuk membuat form yang sama.
Bagikan pemikiranmu pada komentar di bawah ini.