ต่อเนื่องจากบทความตอนที่แล้ว ที่เราทดสอบสร้างฟอร์ม ทำการเพิ่ม ลบ แก้ไข
และแสดงรายการข้อมูล จากบทความ
ประยุกต์ การใช้งาน Form ทำการเพิ่ม ลบ แก้ไข ใน Angular App
https://www.ninenik.com/content.php?arti_id=776 via @ninenik
ในการส่งข้อมูล ทั้งกรณีเพิ่มข้อมูลใหม่หรืออัพเดทแก้ไขข้อมูล เรามีการเรียกใช้คำสั่ง
ผ่าน event click จากปุ่ม button
<button type="button" class="btn btn-sm btn-success" (click)="doSubmitStaff()" >Submit</button>
ไม่ได้ผ่าน event submit จากฟอร์มตามปกติทั่วไป ทีนี้เราจะทำการตรวจสอบ และส่งข้อมูล
ผ่าน event submit แทน เบื้องต้นให้แก้ไขในส่วนของ <button> เปลี่ยน type เป็น submit
และเอา click event ออก จะได้เป็น
<button type="submit" class="btn btn-sm btn-success">Submit</button>
ยกส่วนของโค้ดไฟล์ staff-form.component.html ในส่วนของฟอร์มมาพิจารณา
ดังนี้
<div [hidden]="newstaff" class="container"> <div> <form> <div class="form-group"> <label for="name">Name</label> <input type="text" class="form-control input-sm" id="name" required [(ngModel)]="staff.name" name="name" > </div> <div class="form-group"> <label for="age">Age</label> <input type="text" class="form-control input-sm" id="age" [(ngModel)]="staff.age" name="age"> </div> <div class="form-group"> <label for="department">Department</label> <select class="form-control input-sm" id="department" required [(ngModel)]="staff.department" name="department"> <option *ngFor="let department of departments" [value]="department">{{department}}</option> </select> </div> <button type="submit" class="btn btn-sm btn-success">Submit</button> <button type="button" class="btn btn-sm btn-danger" (click)="doShowList()" >Cancel</button> </form> </div> </div>
เมื่อเราทดสอบกดปุ่ม Submit โดยไม่กรอกข้อมูลใดๆ ในฟอร์ม จะพบว่ามีการแจ้ง
ให้กรอกข้อมูลใน <input> และ <select> ที่เรากำหนด "required" attribute นั่นคือเรา
จำเป็นต้องกำหนดค่าให้กับสอง element นี้ก่อนฟอร์มจึงจะเข้า event submit และส่งค่าได้
การแจ้งเตือนแสดงดังรูป
ก่อนลงรายละเอียดเพิ่มเติม ขออธิบายย้อนกลับมาก่อนว่า ในกรณีที่เรามีการใช้งานฟอร์ม และ
จะมีการจัดการฟอร์มโดยใช้ Template driven forms ซึ่งได้มีการ import "FormsModule"
มาใช้งานใน app ของเรา ตามบทความด้านล่างนี้แล้วนั้น
เตรียมใช้งาน Template driven forms ใน Angular เบื้องต้น
https://www.ninenik.com/content.php?arti_id=774 via @ninenik
เมื่อมีการเรียกใช้ฟอร์ม ใน template หรือไฟล์ template
Angular จะทำการสร้าง ตัวแปร instance ของ FormControl class ขึ้นมาใช้งานกับ ngForm directive
(Directives ก็คือส่วนที่ขยายเพิ่มเติมจาก HTML ที่ Angular สร้างขึ้นมาเพื่อจัดการกับ DOM )
โดย ngForm directive นั้น Angular สร้างขึ้นมาโดยอัตโนมัติไว้กับแท็ก <form>
และจะมีส่วนในการจัดการ element ต่างๆในฟอร์ม element ใดๆ ที่มีการใช้งาน ngModel directive
และ มีการกำหนด "name" attribute ไว้ ngForm จะทำการตรวจสอบค่า property ของ element
รวมถึงความถูกต้องของ element นั้นๆ
นอกจากนั้น ngForm ยังมีการตรวจสอบ property ของตัวมันเอง โดยจะมีค่าเป็น true ถ้า element
ด้านในที่ใช้งาน ngModel มีความถูกต้องของข้อมูล ดูรูปภาพด้านล่างประกอบ
ฟอร์มจะทำการส่งข้อมูล หรือเข้า event submit เมื่อกรอกข้อมูลครบถ้วนถูกต้อง
การใช้ ngModel ในการตรวจสอบสภาวะเงื่อนไข และความถูกต้องของ control
ngModel directive จะทำการสร้าง ตัวแปร instance ของ FormControl class ของ element
ซึ่งจะขอเรียกวา control ในฟอร์ม คล้ายกับ ngForm ที่สร้างไว้ในแท็ก <form>
โดยนอกจาก ngModel จะใช้กับ element (เช่น <input> <select>) ในฟอร์มเพื่อเชื่อมข้อมูล
แบบไปกลับกับตัวแปรแล้ว ยังใช้ในการตรวจสอบด้วยว่าผู้ใช้ มีการกระทำเกิดขึ้นกับ element
ยกตัวอย่าง เช่น มีการเปลี่ยนแปลงค่า หรือค่าของ element ไม่ถูกต้อง สิ่งที่เกิดขึ้น ทำให้เกิด
state หรือสภาวะเงื่อนไขของ control ขึ้น
ngModel จะทำการอัพเดท control ตามสภาวะเงื่อนไข ที่เกิดขึ้น โดยการระบุ ด้วย Angular CSS class
ตามตารางดังนี้
State หรือ สภาวะเงื่อนไข | Class ถ้า true | Class ถ้า false |
---|---|---|
ถ้ามี event หรือการกระทำใดๆ จากผู้ใช้กับ control | ng-touched | ng-untouched |
ถ้ามีการเปลี่ยนแปลงค่าของ control | ng-dirty | ng-pristine |
ถ้าค่าของ control มีความถูกต้อง | ng-valid | ng-invalid |
ขออธิบายตามความหมายของชื่อ css class อย่างง่าย
- touched ก็คือสัมผัสหรือแตะต้อง หรือมีการกระทำใดๆ เกิดขึ้นแล้ว
- untouched ก็คือยังไม่สัมผัสหรือยังไม่แตะต้อง หรือยังไม่มีการกระทำใดๆ เกิดขึ้น
- dirty ก็คือสกปรก หรือไม่บริสุทธิ์ มีร่องรอยมีการขีดเขียน อะไรแนวนี้
- pristine ก็คือยังบริสุทธิ์ ไม่มีการเปลี่ยนแปลงใดๆ เกิดขึ้น
- valid ก็คือมีความถูกต้อง ผ่านแล้ว
- invalid ก็คือไม่ถูกต้อง ไม่ผ่าน
อันนี้แปลเพื่อให้เข้าใจง่ายๆ
โดยเราสามารถใช้ประโยชน์จาก class name เหล่านี้ในการเปลี่ยนแปลงรูปแบบ
การแสดงของ control ได้ ซึ่งก็หมายถึงจัดรูปแบบ css ของ element ที่ใช้งาน
ngModel directive นั่นเอง
เรามาลอง view source ดูว่า Angular กำหนด class อะไรลงไปใน control แต่ละตัวที่มีการ
ใช้งาน ngForm และ ngModel กันบ้าง ดังรูป
ตามรูป เราขอดูแค่สองจุดพอ คือ ส่วนของแท็ก <form> และ <input> ตัวแรกที่เป็น name
เราจะเห็นว่าแรกเริ่มเมื่อเปิดฟอร์มขึ้นมา
ฟอร์มนั้นยังไม่มีการกระทำใดๆ เกิดขึ้น มี class ชื่อ ng-untouched
ยังไม่มีการเปลี่ยนแปลงค่าใดๆ มี class ชื่อ ng-pristine
และฟอร์มนี้ยังไม่ผ่านการตรวจสอบ มี class ชื่อ ng-invalid
ในส่วนของแท็ก <input> ก็เช่นเดียวกัน
input ยังไม่มีการกระทำใดๆ เกิดขึ้น มี class ชื่อ ng-untouched
input ยังไม่มีการกรอกข้อมูล หรือเปลี่ยนค่าใดๆ มี class ชื่อ ng-pristine
input และเนื่องจาก input ตัวนี้มีการกำหนด "required" attribute ซึ่งจำเป็นต้องกรอกข้อมูล
ดังนั้น input นี้จึงยังไม่ผ่านการตรวจสอบ มี class ชื่อ ng-invalid
เรามาลองสมมติกรอกข้อมูลชื่อลงไปดูตามรูป
สังเกตว่าส่วนของ <form> ยังมี class เป็น ng-invalid เพราะยังมีส่วนอื่นที่เรายังไม่ได้กรอก
ดังนั้นฟอร์มนี้ก็ยังไม่ผ่าน แต่ที่เปลี่ยนแปลงคือ เปลี่ยนจาก "ng-pristine" class เป็น "ng-dirty" class
และเปลี่ยนจาก "ng-untouched" class เป็น "ng-touched" class นั่นก็เพราะมีการกระทำเกิดขึ้นในฟอร์ม
แล้ว และฟอร์มมีการเปลี่ยนแปลง
เช่นเดียวกัน ถ้าเราดูในส่วนของ <input> ที่เราเพิ่งกรอกข้อมูลไป จะเห็นว่า มีการเปลี่ยนแปลง
จาก "ng-invalid" class เป็น "ng-valid" ทั้งนี้เพราะเงื่อนไขความถูกต้องของ <input> คือต้องกรอก
ข้อมูลก่อน ดังนั้นเมื่อเรากรอกข้อมูลแล้ว แสดงว่าส่วนของ <input> นี้ผ่านแล้ว ส่วนอีกสอง class ที่เปลี่ยน
ก็เช่นเดียวกับฟอร์ม คือมีการกระทำเกิดขึ้นกับ <input> และค่าใน <input> มีการเปลี่ยนแปลง
ค่า "ng-valid" class ของ element ในฟอร์มถ้าทุกตัวเป็น "ng-valid" หรือก็คือค่าของตัวแปร instance
ของ control เป็น true ทุกตัว ก็จะทำให้ ค่าของ instance ของ form control เป็น true ด้วย
มีค่า instance ของ form control เป็น true ก็แสดงว่าฟอร์มนั้นผ่านการตรวจสอบค่าแล้ว สามารถส่งค่า
ไปทำงานในขี้นตอนต่อไปได้
สำหรับ Angular CSS class เหล่านี้นอกจาก เราจะใช้ในการตรวจสอบความถูกต้องของฟอร์มหรือ element
ต่างๆ ในฟอร์มแล้ว เรายังสามารถนำมาใช้กำหนดรูปแบบการแสดง ให้เห็นความแตกต่างของแต่ละสถาวะ
เงื่อนไขในฟอร์มได้ ยกตัวอย่างเช่น ถ้า element ใดที่ยังไม่ valid หรือยังไม่ผ่าน เรากำหนดให้มี border
ด้านซ้ายของ element นั้นเป็นสีแดง ถ้าผ่านแล้วให้เป็นสีเขียว แบบนี้เป็นต้น
เรามาลองทดสอบโดยเรียกใช้ ไฟล์ staff-form.component.css ผ่าน Metadata ที่ชื่อ
styleUrls โดยเพิ่มกลับในไฟล์ staff-form.component.ts อีกครั้งดังนี้
styleUrls: ['./staff-form.component.css']
หมายเหตุ: เราสามารถที่จะสร้างไฟล์ใหม่ แล้วเรียกผ่านไฟล์ index.html แทนการใช้งาน Metadata
ที่ชื่อ styleUrls ก็ได้ แต่ในที่นี้จะใช้เป็น Metadata
จากนั้นไฟล์ staff-form.component.css ให้เรากำหนด style ให้กับ Angular CSS class
ที่เราต้องการจัดการ ดังนี้
ไฟล์ staff-form.component.css
/* ให้ element ทุกตัวที่มี "ng-valid" class และมี attribute ชื่อ "required" กับ element ทุกตัวที่มี "ng-valid" class และ "required" class ให้มีขอบซ้ายมีอหนา 5px มีสีเขียว */ .ng-valid[required], .ng-valid.required { border-left: 5px solid #42A948; } /* ให้ element ทุกตัวที่มี "ng-invalid" class ยกเว้น แท็ก <form> ให้มีขอบซ้ายมีอหนา 5px มีสีแดง */ .ng-invalid:not(form) { border-left: 5px solid #a94442; }
เรามาดูผลลัพธ์หน้าฟอร์ม
พอเราทดสอบกรอกข้อมูลในช่อง name จะเห็นผลลัพธ์ดังรูปถัดมาดังนี้
และนี่ก็คือประโยชน์ของการใช้งาน Angular CSS class เพื่อเน้นให้เห็นชัดว่าส่วนไหนของฟอร์ม
มีการกรอกข้อมูลหรือผ่านการตรวจสอบเรียบร้อยแล้ว ก่อนทำการกดปุม Submit ข้อมูล
ในตอนหน้าเราจะมาดูในเรื่องของตัวแปร instnace ของ form control ในฟอร์ม และ element เพิ่มเติม
รวมถึงการส่งข้อมูลไปพร้อมกับการ Submit ฟอร์ม ซึ่งจะแตกต่าง
จากการใช้งานจากกรณีกำหนดการเชื่อมข้อมูลแบบไปกลับระหว่างฟอร์มกับตัวแปร ที่เคยกล่าวไปแล้ว
ในบทความเรื่อง
ประยุกต์ การใช้งาน Form ทำการเพิ่ม ลบ แก้ไข ใน Angular App
https://www.ninenik.com/content.php?arti_id=776 via @ninenik
โดยจะมีการใช้งาน template variable ร่วมกับ ngModel รอติดตาม