จากเนื้อหาตอนที่แล้ว เราได้รู้จักแนวทางการตรวจสอบฟอร์ม ที่เราสร้างฟังก์ชั่นขึ้นมาใช้งานแล้ว ในเนื้อหาต่อไปนี้
จะขอเพิ่มเติมการใช้งาน รูปแบบการตรวจสอบ ที่มีมาให้ใน bootstrap ดูตัวอย่างได้ที่ DEMO 1 ท้ายบทความ
เนื้อหาตอนที่แล้ว
เทคนิคแนวทางตรวจสอบฟอร์ม form validation ใน bootstrap 4 อย่างง่าย http://niik.in/873
https://www.ninenik.com/content.php?arti_id=873 via @ninenik
สิ่งแรกที่ต้องทำคือ เพิ่ม property "novalidate" ให้กับ form โดย "novalidate" จะเป็นการยกเลิกการ
ตรวจสอบฟอร์มจาก browser มาเป็นตรวจสอบฟอร์มแบบกำหนดเอง และอีกส่วนคือ
กำหนด id เช่น "myform1" ไว้อ้างอิงเพื่อเรียกใช้งาน
<form id="myform1" name="form1" method="post" action="" novalidate> </form>
และนี้คือรูปแบบ javascipt ที่เราใช้ผ่าน jquery เป็นดังนี้
<script type="text/javascript"> $(function(){ $("#myform1").on("submit",function(){ var form = $(this)[0]; if (form.checkValidity() === false) { event.preventDefault(); event.stopPropagation(); } form.classList.add('was-validated'); }); }); </script>
ต่อไป element ใดๆ ที่เราต้องการตรวจสอบ ให้เพิ่ม property "required" เข้าไป เช่น
<input type="text" class="form-control" name="input_name" id="input_name" autocomplete="off" value="" required>
และส่วนสุดท้ายของฟอร์ม ก็คือเพิ่ม ข้อความแจ้งเตือน กรณีที่ element นั้นๆ ไม่ผ่านเงื่อนไขการตรวจสอบ โดยจะ
ต้องเพิ่มต่อเข้าไป หลังจาก element ที่เรากำหนด "required" property ก็จะได้เป็น
<input type="text" class="form-control" name="input_name" id="input_name" autocomplete="off" value="" required> <div class="invalid-feedback"> กรุณากรอกชื่อ นามสกุล </div>
โดย Bootstrap จะใช้ class "invalid-feedback" เพื่อแสดงการแจ้งเตือนเมื่อไม่ผ่านการตรวจสอบ มาดูหน้าตาตัวอย่าง
ผลลัพธ์เบื้องต้นกัน
เมื่อเรากดปุ่ม ส่งข้อมูล โดยที่ยังไม่ได้กรอกข้อมูลที่จำเป็น ก็จะขึ้นแจ้ง พร้อมแสดงข้อความแจ้งเตือน ที่ถูกซ่อนเอาไว้
และเมือเรากรอกข้อมูล ก็จะทำให้ผ่านเงื่อนไขการตรวจสอบ ส่วนของ element นั้นๆ มีสถานะเป็น valid หรือผ่านการ
ตรวจสอบ อย่างเห็นได้ชัด ตามตัวอย่างรูปด้านล่าง
สมมติเราต้องการตรวจสอบเพิ่มเติม นอกจากค่าว่างหรือไม่ว่าง เราสามารถใช้ pattern สำหรับกรณีเป็น input type
( text, date, search, url, tel, email และ password )
มาประกรอบได้ ซึ่งถ้ามีความเข้าใจในการใช้งาน regular expression จะสามารถประยุกต์ส่วนนี้ได้เป็นอย่างดี ยกตัวอย่าง
เราต้องการให้ตรวจสอบว่ากรอกข้อมูลในรูปแบบมือถือ 10 หลักถูกต้องหรือไม่ด้วย ก็จะเป็นดังนี้
<input type="text" class="form-control" pattern="^0([8|9|6])([0-9]{8}$)" name="input_tel" id="input_tel" autocomplete="off" value="" required> <div class="invalid-feedback"> กรุณากรอกเบอร์มือถือตัวเลข 10 หลัก </div>
สมมติเรากรอกรูปแบบเบอร์มือถือไม่ถูกต้อง
จะเห็นว่า จะไม่ใช่เพียงการตรวจสอบ ว่าเป็นค่าว่างหรือไม่เท่านั้น แต่ยังตรวจสอบรูปแบบของข้อมูลว่าตรงตามรูปแบบที่
กำหนดใน pattern หรือไม่ เมื่อเรากรอกรูปแบบถูกต้อง ก็จะเป็นดังรูปด้านล่าง
ถ้ากรณีต้องการตรวจสอบอีเมล เราสามารถกำหนดด้วย pattern กับ input type="text" หรือ input type="email"
ตัวอย่างการใช้งานการตรวจสอบอีเมล
<div class="form-group row"> <label for="input_email" class="col-sm-3 col-form-label text-right">อีเมล</label> <div class="col"> <input type="text" class="form-control" name="input_email" id="input_email" pattern="^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$" autocomplete="off" value="" required> <div class="invalid-feedback"> กรุณากรอกอีเมล </div> </div> </div>
ต่อไปกรณีสมมติเป็นตัวเลข OTP หรือเป็นตัวเลขอย่างเดียว อาจจะเป็น 5 หลักก็ได้ เราสามารถกำหนดเป็นดังนี้
<div class="form-group row"> <label for="input_otp" class="col-sm-3 col-form-label text-right">รหัส OTP</label> <div class="col"> <input type="text" class="form-control" name="input_otp" id="input_otp" pattern="[0-9]{5}" autocomplete="off" value="" required> <div class="invalid-feedback"> กรุณากรอกรหัส OTP เป็นตัวเลข 5 หลัก </div> </div> </div>
อย่างไรก็ตาม กรณีที่จำเป็นที่ต้องกรอกข้อมุลเป็นตัวเลข ถ้าเป็นโหมดมือถือ การใช้งาน input type="number" จะทำ
ให้ผู้ใช้สะดวกในการกรอกข้อมูล เพราะแป้นมือถือจะเป็นตัวเลข ทำให้กรอกข้อมูลง่าย แต่ด้วยว่า pattern ไม่สามารถ
ใช้งานกับ type="number" ได้ หากจะใช้งาน เราจำเป็นต้อง เพิ่มเติม javascript เข้าไป มาดูตัวอย่าง
สมมติกรณีแรก กรอกตัวเลข ค่าตั้ง x-y โดย x คือค่าน้อยสุด และ y คือค่ามากสุด เราสามารถกำหนดเป็นดังนี้
<input type="number" class="form-control" name="input_otp" id="input_otp" min="1" max="10" autocomplete="off" value="" required>
จะผ่านเงื่อนไขนี้ ต้องกรอกตัวเลขค่าตั้งแต่ 1 แต่ไม่เกิน 10 ค่าใดก็ได้
ต่อมาแบบที่กรอกเป็นตัวเลข แต่มีการกำหนดจำนวนตัวอักษร เช่น กรณีเป็นรหัส OTP เป็นตัวเลข 5 หลัก ซึ่งหมายความ
ว่า เราสามารถกรอกเป็นตัวเลข 00000 - 99999 ในกรณีนี้ เราจำเป็นต้องใช้ javascript เข้ามาช่วยเพิ่มเติม คือ ห้ามกรอก
เกิน 5 ตัว และ ค่าต้องเป็นไปตามเงื่อนไข เราจะได้เป็นดังนี้
<input type="number" class="form-control" name="input_otp" id="input_otp" maxlength="5" min="1" max="99999" oninput="this.value.length<this.maxLength?this.min=Math.pow(10, this.value.length):this.min=0" onkeypress="return (this.value.length>=this.maxLength)?false:true" autocomplete="off" value="" required>
หากต้องการเปลี่ยนเป็น 6 ตัว ให้เราเปลี่ยนตรง maxlength="5" เป็น maxlength="6" และเปลี่ยนตรง
max="99999" ให้เป็น max="999999" หรือก็คือ มีเลข 9 เท่ากับ 6 ตัว
ต่อไปมาดูในส่วนของกรณีที่เป็น radio หรือ checkbox กันบ้าง โดยจะใช้งานคล้ายกัน จะยกตัวอย่างเฉพาะ radio
กรณีที่ต้องเลือกค่าใดค่าหนึ่งของ radio ก็จะกำหนดคล้าย input
คือเพิ่ม property "required" เข้าไป พร้อมกับกำหนด <div class="invalid-feedback">ข้อความแจ้ง</div>
เข้าไปต่อจาก label ของ radio ตัวสุดท้าย ยกตัวอย่าง
<div class="form-group row"> <legend class="col-form-label col-sm-3 pt-0 text-right">เพศ</legend> <div class="col"> <div class="form-check"> <input class="form-check-input" type="radio" name="radio_gender" id="radio_gender_1" value="male" required> <label class="form-check-label" for="radio_gender_1"> ชาย </label> </div> <div class="form-check"> <input class="form-check-input" type="radio" name="radio_gender" id="radio_gender_2" value="female" required> <label class="form-check-label" for="radio_gender_2"> หญิง </label> <div class="invalid-feedback"> กรุณาเลือกเพศ </div> </div> </div> </div>
กรณีไม่ผ่านเงื่อนไข
กรณีผ่านเงื่อนไข
จำไว้เสมอว่า การกำหนด ตำแหน่งของ <div class="invalid-feedback"></div> ถ้าเราวางไว้ไม่ติดกับ element หรือ
ไม่ติดกับ label ตัวแจ้งอาจจะไม่แสดง
ส่วนของ textarea และ select ก็จะกำหนดคล้าย input ตัวอย่างดูได้ที่โค้ดเต็ม
<!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>Document</title> <link rel="stylesheet" href="https://unpkg.com/bootstrap@4.1.0/dist/css/bootstrap.min.css" > </head> <body> <div class="container"> <br> <form id="myform1" name="form1" method="post" action="" novalidate> <div class="form-group row"> <label for="input_name" class="col-sm-3 col-form-label text-right">ชื่อ นามสกุล</label> <div class="col"> <input type="text" class="form-control" name="input_name" id="input_name" autocomplete="off" value="" required> <div class="invalid-feedback"> กรุณากรอกชื่อ นามสกุล </div> </div> </div> <div class="form-group row"> <label for="input_tel" class="col-sm-3 col-form-label text-right">เบอร์มือถือ</label> <div class="col"> <input type="text" class="form-control" pattern="^0([8|9|6])([0-9]{8}$)" name="input_tel" id="input_tel" autocomplete="off" value="" required> <div class="invalid-feedback"> กรุณากรอกเบอร์มือถือตัวเลข 10 หลัก </div> </div> </div> <div class="form-group row"> <label for="input_email" class="col-sm-3 col-form-label text-right">อีเมล</label> <div class="col"> <input type="text" class="form-control" name="input_email" id="input_email" pattern="^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$" autocomplete="off" value="" required> <div class="invalid-feedback"> กรุณากรอกอีเมล </div> </div> </div> <div class="form-group row"> <label for="input_otp" class="col-sm-3 col-form-label text-right">รหัส OTP</label> <div class="col"> <input type="number" class="form-control" name="input_otp" id="input_otp" maxlength="5" min="1" max="99999" oninput="this.value.length<this.maxLength?this.min=Math.pow(10, this.value.length):this.min=0" onkeypress="return (this.value.length>=this.maxLength)?false:true" autocomplete="off" value="" required> <div class="invalid-feedback"> กรุณากรอกรหัส OTP เป็นตัวเลข 5 หลัก </div> </div> </div> <div class="form-group row"> <legend class="col-form-label col-sm-3 pt-0 text-right">เพศ</legend> <div class="col"> <div class="form-check"> <input class="form-check-input" type="radio" name="radio_gender" id="radio_gender_1" value="male" required> <label class="form-check-label" for="radio_gender_1"> ชาย </label> </div> <div class="form-check"> <input class="form-check-input" type="radio" name="radio_gender" id="radio_gender_2" value="female" required> <label class="form-check-label" for="radio_gender_2"> หญิง </label> <div class="invalid-feedback"> กรุณาเลือกเพศ </div> </div> </div> </div> <div class="form-group row"> <label for="textarea_address" class="col-sm-3 col-form-label text-right">ที่อยู่</label> <div class="col"> <textarea class="form-control" name="textarea_address" id="textarea_address" rows="3" required></textarea> <div class="invalid-feedback"> กรุณากรอกที่อยู่ </div> </div> </div> <div class="form-group row"> <label for="select_province" class="col-sm-3 col-form-label text-right">จังหวัด</label> <div class="col"> <select class="custom-select" name="select_province" id="select_province" required> <option value="">เลือกจังหวัด</option> <option value="กรุงเทพ">กรุงเทพ</option> </select> <div class="invalid-feedback"> กรุณาเลือกจังหวัด </div> </div> </div> <div class="form-group row"> <label for="input_zipcode" class="col-sm-3 col-form-label text-right">รหัสไปรษณีย์</label> <div class="col"> <input type="number" class="form-control" name="input_zipcode" id="input_zipcode" autocomplete="off" value="" min="10000" max="99999" required> <div class="invalid-feedback"> กรุณากรอกรหัสไปรณีย์ </div> </div> </div> <div class="form-group row"> <div class="col-sm-3 offset-sm-3 text-right pt-3"> <button type="submit" name="btn_submit" id="btn_submit" value="1" class="btn btn-primary btn-block">ส่งข้อมูล</button> </div> </div> </form> </div> <script src="https://unpkg.com/jquery@3.3.1/dist/jquery.min.js"></script> <script src="https://unpkg.com/bootstrap@4.1.0/dist/js/bootstrap.min.js"></script> <script type="text/javascript"> $(function(){ $("#myform1").on("submit",function(){ var form = $(this)[0]; if (form.checkValidity() === false) { event.preventDefault(); event.stopPropagation(); } form.classList.add('was-validated'); }); }); </script> </body> </html>
ดูผลลัพธ์ได้ที่ DEMO 1
ก่อนจบ ขอเพิ่มบางกรณีเกี่ยวกับ checkbox ซึ่งโดยทั่วไปแล้ว เราจะกำหนดคล้าย radio แต่ลักษณะของ radio นั้น
คือเลือกอย่างใด อย่างหนึ่ง ก็จะเข้าเงื่อนไข แต่ของ checkbox ที่มีให้เลือกหลายรายการ และต้องเลือกอย่างน้อย
1 รายการ เมื่อเราใส่ property "required" เข้า จะกลายเป็นว่า เราต้องเลือกทุกรายการ ถึงจะผ่านเงื่อนไข ตามตัวอย่าง
ต่อไปนี้
<div class="form-group row"> <legend class="col-form-label col-sm-3 pt-0 text-right">ความสนใจ</legend> <div class="col"> <div class="form-check"> <input class="form-check-input" type="checkbox" name="checkbox_hobby1" id="hobby1" value="การออกกำลังกาย" required> <label class="form-check-label" for="hobby1"> การออกกำลังกาย </label> </div> <div class="form-check"> <input class="form-check-input" type="checkbox" name="checkbox_hobby2" id="hobby2" value="อ่านหนังสือ" required> <label class="form-check-label" for="hobby2"> อ่านหนังสือ </label> <div class="invalid-feedback"> กรุณาเลือกความสนใจ </div> </div> </div> </div>
กรณีลักษณะนี้ เราจำเป็นต้องเพิ่มหรือประยุกต์เพิ่มเต็ม เพื่อให้การตรวจสอบฟอร์มของ bootstrap ทำงานได้
โดยเราต้องการให้ เมื่อเลือกอย่างน้อย 1 รายการ ก็ให้ผ่านเงื่อนไข เทคนิคที่เราจะใช้คือ เพิ่ม class "required"
<input class="form-check-input required" type="checkbox" name="checkbox_hobby1" id="hobby1" value="การออกกำลังกาย" required>
เข้าไป ในกลุ่มของ checkbox นั้น จากนั้น ใช้ jquery ตรวจสอบว่า ถ้ามีการเลือกแล้วอย่างน้อย 1 รายการ
ให้ทำการเอา property "required" ออก เราก็จะได้ในส่วนของ javascript เป็นดังนี้
<script type="text/javascript"> $(function(){ var checkbox_required = false; $(":checkbox.required").on("click",function(){ var is_checked = $(this).prop("checked"); if(is_checked){ $(":checkbox.required").prop('required',false); checkbox_required = true; }else{ if($(":checkbox.required:checked").length==0){ checkbox_required = false; $(":checkbox.required").prop('required',true); } } }); $("#myform1").on("submit",function(){ var form = $(this)[0]; if (form.checkValidity() === false || checkbox_required===false) { event.preventDefault(); event.stopPropagation(); } form.classList.add('was-validated'); }); }); </script>
ตัวอย่างโค้ดแบบเต็ม
<!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>Document</title> <link rel="stylesheet" href="https://unpkg.com/bootstrap@4.1.0/dist/css/bootstrap.min.css" > </head> <body> <div class="container"> <br> <form id="myform1" name="form1" method="post" action="" novalidate> <div class="form-group row"> <label for="input_name" class="col-sm-3 col-form-label text-right">ชื่อ นามสกุล</label> <div class="col"> <input type="text" class="form-control" name="input_name" id="input_name" autocomplete="off" value="" required> <div class="invalid-feedback"> กรุณากรอกชื่อ นามสกุล </div> </div> </div> <div class="form-group row"> <legend class="col-form-label col-sm-3 pt-0 text-right">ความสนใจ</legend> <div class="col"> <div class="form-check"> <input class="form-check-input required" type="checkbox" name="checkbox_hobby1" id="hobby1" value="การออกกำลังกาย" required> <label class="form-check-label" for="hobby1"> การออกกำลังกาย </label> </div> <div class="form-check"> <input class="form-check-input required" type="checkbox" name="checkbox_hobby2" id="hobby2" value="อ่านหนังสือ" required> <label class="form-check-label" for="hobby2"> อ่านหนังสือ </label> <div class="invalid-feedback"> กรุณาเลือกความสนใจ </div> </div> </div> </div> <div class="form-group row"> <div class="col-sm-3 offset-sm-3 text-right pt-3"> <button type="submit" name="btn_submit" id="btn_submit" value="1" class="btn btn-primary btn-block">ส่งข้อมูล</button> </div> </div> </form> </div> <script src="https://unpkg.com/jquery@3.3.1/dist/jquery.min.js"></script> <script src="https://unpkg.com/bootstrap@4.1.0/dist/js/bootstrap.min.js"></script> <script type="text/javascript"> $(function(){ var checkbox_required = false; $(":checkbox.required").on("click",function(){ var is_checked = $(this).prop("checked"); if(is_checked){ $(":checkbox.required").prop('required',false); checkbox_required = true; }else{ if($(":checkbox.required:checked").length==0){ checkbox_required = false; $(":checkbox.required").prop('required',true); } } }); $("#myform1").on("submit",function(){ var form = $(this)[0]; if (form.checkValidity() === false || checkbox_required===false) { event.preventDefault(); event.stopPropagation(); } form.classList.add('was-validated'); }); }); </script> </body> </html>