เรามาทำความเข้าใจพื้นฐาน ajax อย่างง่ายกัน โดยก่อนอื่นเราต้องมีพื้นฐานเกี่ยวกับ
การส่งข้อมูลเบื้องต้นก่อน สมมติเรามีฟอร์มสำหรับส่งข้อมูล ในที่นี้เป็นฟอร์มสำหรับส่งหัวข้อ
และรายละเอียด ดังนี้
ไฟล์ demo_index.php
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Document</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> <br> <br> <div class="container"> <form id="news-form" name="news-form" action="show.php" method="post"> <div class="form-group"> <label for="news-topic" class="control-label">Topic:</label> <input type="text" class="form-control" id="news-topic" name="topic"> </div> <div class="form-group"> <label for="news-message" class="control-label">Message:</label> <textarea class="form-control" id="news-message" name="message"></textarea> </div> <button type="submit" class="btn btn-primary">Submit</button> </form> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <script type="text/javascript"> $(function(){ }); </script> </body> </html>
ไฟล์หลักสำหรับส่งข้อมูลจากฟอร์ม มี action ไปที่ไฟล์ show.php คือไฟล์ที่ทำการรับค่าที่ส่งจากฟอร์ม
ไฟล์ show.php
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Document</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> <br> <br> <div class="container"> <pre> <?php print_r($_POST); ?> </pre> <a href="demo_index.php" class="btn btn-warning">back</a> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> <script type="text/javascript"> $(function(){ }); </script> </body> </html>
ไฟล์ show.php เราใช้คำสั่ง php ที่ชื่อ print_r() ในที่นี้
<?php print_r($_POST); ?>
คือให้แสดงชื่อตัวแปร และค่าของตัวแปร $_POST ที่ถูกส่งมาทั้งหมด
ดูรูปอธิบายประกอบ เมื่อเรากรอกข้อมูลทดสอบในฟอร์มที่ไฟล์ demo_index.php จากนั้นทำการกด
Submit ข้อมูลก็ถูกส่งพร้อมเปลี่ยนหน้าเพจมายังหน้า show.php และแสดงข้อมูลที่ส่งมาดังรูป
ไม่กรอกข้อมูล แล้วกดปุ่ม Submit
ตัวแปร $_POST ถูกส่งมายังไฟล์ show.php แต่ไม่มีข้อมูล
ทดสอบเปลี่ยนเป็นกรอกข้อมูล แล้วกดปุ่ม Submit
ตัวแปร $_POST ถูกส่งมายังไฟล์ show.php โดยมีทั้งชื่อตัวแปร และข้อมูลที่กรอก
ทีนี้เราลองมาเปลี่ยนเป็นการส่งข้อมูลแบบไม่ต้องรีเฟรชหน้ากันดู โดยใช้วิธีการส่งข้อมูลแบบ POST ด้วย
jQuery Ajax อย่างง่าย ซึ่งจริงๆ แล้วสามารถทำได้หลายวิธี เราจะทำความเข้าใจไปทีละขั้น
โดยที่ไฟล์ demo_index.php เราจะแก้ไขบรรทัด
<form id="news-form" name="news-form" action="show.php" method="post">
เปลี่ยนเป็น
<form id="news-form" name="news-form" action="" method="post">
โดยเราตัดไฟล์ในส่วนของ action ออก เพราะเราจะไม่ส่งค่าข้อมูลแบบเปลี่ยนหน้าเพจหรือรีเฟรชหน้าเพจใหม่แล้ว
แต่จะส่งแบบ background หรือแบบเบื้องหลัง
ต่อไปเราดูในส่วนของโค้ด JavaScript เพิ่มโค้ด jQuery ตรวจสอบการ submit หรือส่งค่าฟอร์มด้วยรูปแบบ
// เมื่อฟอร์มที่มีไอดี news-form กำลังทำการส่งข้อมูล $("#news-form").on("submit",function(event){ // มีการส่ง event object event.preventDefault(); // ปิดค่าเริ่มต้น ในกรณีนี้คือไม่มีการรีเฟรชหรือเปลี่ยนหน้าเพจ // คำสังต่อจากบรรทัดนี้ทำงานได้ปกติ });
หรือ
// เมื่อฟอร์มที่มีไอดี news-form กำลังทำการส่งข้อมูล $("#news-form").on("submit",function(){ // มีการส่ง event object // return false; // ปิดค่าการทำงานของฟอร์ม โดยคืนค่าเป็น false ไม่มีการรีเฟรชหรือเปลี่ยนหน้าเพจ // คำสังต่อจากบรรทัดนี้ไม่ทำงาน });
ในที่นี้เราจะใช้รูปแบบแรก ด้วย event.preventDefault() อ่านเพิ่มเติมเกี่ยวกับ event.preventDefault() ได้ที่่
http://api.jquery.com/event.preventDefault/
http://api.jquery.com/event.preventDefault/
เมื่อเราทดสอบกดที่ปุ่ม submit ก็จะพบว่าไม่มีอะไรเกิดขึ้น ไม่มีการรีเฟรชหน้าหรือส่งข้อมูลแต่อย่างใดในตอนนี้
ปัญหาที่เกิดขึ้นก็คือ เราจะรู้ได้อย่างไรว่าฟอร์มมีการ submit หรือไม่ เพราะมีการทำงานอยู่เบื้องหลัง ดังนั้นการใช้งาน
ajax เราต้องรู้จักวิธีการ debug ผ่าน console ดูวิธีการได้ที่บทความ
การใช้งาน console log เพื่อ debug javascript ใน chrome firefox และ ie
https://www.ninenik.com/content.php?arti_id=692 via @ninenik
เราลองมาปรับโค้ดของเราเป็น ดังนี้
// เมื่อฟอร์มที่มีไอดี news-form กำลังทำการส่งข้อมูล $("#news-form").on("submit",function(event){ // มีการส่ง event object console.log("test 1"); event.preventDefault(); // ปิดค่าเริ่มต้น ในกรณีนี้คือไม่มีการรีเฟรชหรือเปลี่ยนหน้าเพจ // คำสังต่อจากบรรทัดนี้ทำงานได้ปกติ console.log("test 2"); });
เพื่อทดสอบว่าเมื่อเราคลิกที่ปุ่ม submit แล้ว มีการทำงานในส่วนของการตรวจจับ event หรือไม่ โดยผลลัพธ์
เมื่อเราคลิกที่ปุ่ม ก็จะได้ดังรูป สังเกตในส่วนของ console จะแสดงข้อความที่เรากำหนด นั้นแสดงว่าเมื่อเราคลิกที่่ปุ่ม
submit ฟอร์มกำลังจะทำการส่งข้อมูล เมื่อ event submit เกิดขึ้น ก็จะมีการเข้าไปทำงานในส่วนของคำสั่งที่เรากำหนด
ต่อไปเราจะมาดูการเตรียมข้อมูลในฟอร์ม สำหรับส่งข้อมูล โดยใช้ส่วนจัดการข้อมูลของ jQuery ในที่นี้จะยกตัวอย่าง
ทั้งสองตัวคือ serialize() และ serializeArray() โดยโค้ดด้านล่างประกอบ
<script type="text/javascript"> $(function(){ // เมื่อฟอร์มที่มีไอดี news-form กำลังทำการส่งข้อมูล $("#news-form").on("submit",function(event){ // มีการส่ง event object console.log("test 1"); event.preventDefault(); // ปิดค่าเริ่มต้น ในกรณีนี้คือไม่มีการรีเฟรชหรือเปลี่ยนหน้าเพจ // คำสังต่อจากบรรทัดนี้ทำงานได้ปกติ console.log("test 2"); var dataSend = $(this).serialize(); var dataSend2 = $(this).serializeArray(); console.log(dataSend); console.log(dataSend2); $.post("show.php",dataSend,function(response){ }); $.post("show.php",dataSend2,function(response){ }); }); }); </script>
จากโค้ด $(this) ก็หมายถึง $("#news-form") ดังนั้น การใช้คำสั่ง
var dataSend = $(this).serialize();
ก็จะหมายถึง การเตรียมข้อมูลจากฟอร์มไอดีชื่อ news-form
สำหรับใช้งานโดยจัดในรูปแบบ query string สมมติเรากรอก aaaa ในช่อง topic และกรอก bbbb ในช่อง
message จะได้ค่า query string ที่ถูกส่งไป จะเป็น "topic=aaaa&message=bbbb"
<input type="text" class="form-control" id="news-topic" name="topic"> <textarea class="form-control" id="news-message" name="message"></textarea>
ให้สังเกตว่าค่าที่จะส่ง จะใช้ name ของ <input> <select> <textarea> แต่ไม่รวม disabled
สำหรับ <input> checkbox / radio ที่ไม่ได้ติ้กเลือก จะไม่มีการส่งข้อมูลทั้งชื่อและค่าของข้อมูล
ในส่วนของ <input> file และ ปุ่ม button จะไม่มีการส่งค่าใดๆ เช่นกัน
สำหรับ <input> checkbox / radio ที่ไม่ได้ติ้กเลือก จะไม่มีการส่งข้อมูลทั้งชื่อและค่าของข้อมูล
ในส่วนของ <input> file และ ปุ่ม button จะไม่มีการส่งค่าใดๆ เช่นกัน
สมมติเรากรอกแค่ช่อง topic ค่าที่ส่งก็จะเป็น "topic=aaaa&message="
ปกติโดยส่วนใหญ่แล้วจะใช้ serialize() ในการเตรียมข้อมูลในฟอร์มก่อนส่งผ่าน ajax
ต่อไปเรามาดูคำสั่ง
var dataSend2 = $(this).serializeArray();
ก็จะหมายถึง การเตรียมข้อมูลจากฟอร์มไอดีชื่อ news-form
สำหรับใช้งานโดยจัดในรูปแบบ javascript array ของ object โดยแต่ละ object จะมี property ชื่อ name
และ value สมมติเรากรอก aaaa ในช่อง topic และกรอก bbbb ในช่อง message จะได้โครงสร้าง array ของ object
ดังนี้
[ { name: "topic", value: "aaaa" }, { name: "message", value: "bbbb" } ]
เงื่อนไขของ element ที่จะมีการจัดรูปแบบก่อนส่งข้อมูลก็จะคล้ายๆ กับกรณีของการใช้งาน serialize() คือ
<input> <select> <textarea> ทีมีการกำหนด name แต่ไม่รวม disabled
สำหรับ <input> checkbox / radio ที่ไม่ได้ติ้กเลือก จะไม่มีการส่งข้อมูลทั้งชื่อและค่าของข้อมูล
ในส่วนของ <input> file และ ปุ่ม button จะไม่มีการส่งค่าใดๆ เช่นกัน
สำหรับ <input> checkbox / radio ที่ไม่ได้ติ้กเลือก จะไม่มีการส่งข้อมูลทั้งชื่อและค่าของข้อมูล
ในส่วนของ <input> file และ ปุ่ม button จะไม่มีการส่งค่าใดๆ เช่นกัน
(กรณีใช้ ajax ร่วมกับอัพโหลดรูป ดูที่บทความ http://niik.in/722) ถ้า element ไหนไม่มีการกำหนด value ก็จะเป็นการส่งค่าว่างไป เช่น
[ { name: "topic", value: "aaaa" }, { name: "message", value: "" } ]
ถ้าไม่กรอกช่อง message ค่าก็จะเป็นค่าว่าง
ปกติ serializeArray() ใช้กรณีต้องการจัดการกับข้อมูลเพิ่มเติมก่อนส่ง เนื่องจากมีความสะดวกในการจัดรูปแบบ
ของข้อมูลมากกว่ากรณีการใช้งาน serialize() แต่ถ้ามองจริงๆ ก็อาจจะไม่ต่างกันมากนัก
ดูรูปภาพประกอบ เราทดสอบดูผลลัพธ์การส่งค่าผ่าน console
ถึงตอนนี้เราได้รู้จักการเตรียมข้อมูลการส่งเบื้องต้นแล้ว ต่อไปเราจะทำการแสดงค่าที่ถูกส่งไปในหน้าไฟล์ demo
โดยที่ไม่ได้รีเฟรชหน้าเพจใหม่ สิ่งที่เราต้องทำคือ สร้างส่วนที่จะแสดงข้อมูลจาก ajax ในที่นี้เรากำหนดเป็น <div>
ไว้ด้านใต้ฟอร์ม ส่งข้อมูล ดังนี้
<div class="container"> <form id="news-form" name="news-form" action="" method="post"> <div class="form-group"> <label for="news-topic" class="control-label">Topic:</label> <input type="text" class="form-control" id="news-topic" name="topic"> </div> <div class="form-group"> <label for="news-message" class="control-label">Message:</label> <textarea class="form-control" id="news-message" name="message"></textarea> </div> <button type="submit" class="btn btn-primary">Submit</button> </form> <br> <div id="place_ajax1" style="background-color:#FC9;"> </div> <hr> <div id="place_ajax2" style="background-color:#FFC;"> </div> </div>
div ไอดี place_ajax1 และ place_ajax2 คือส่วนของพื้นที่ที่เราจะแสดงข้อมูลที่ถูกส่งกลับมาจาก ajax
ต่อไปแก้ไขไฟล์ show.php ซึ่งเป็นไฟล์ที่เราจะ echo หรือแสดงข้อมูลที่ถูกส่งมา ดังนี้
<?php header("Content-type:text/html; charset=UTF-8"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); ?> <pre> <?php print_r($_POST); ?> </pre>
จะเห็นว่าเราตัดส่วนอื่นๆ ที่ไม่จำเป็นออก เอาเฉพาะส่วนของข้อมูลที่ต้องการมาแสดง คล้ายๆ กับเอา
HTML มาแทรกในไฟล์หลักทำนองนั้น
จากนั้นให้แก้ไขส่วนของ jquery code ให้แสดงค่าที่ส่งกลับมา ใน div ที่เรากำหนด เป็นดังนี้
<script type="text/javascript"> $(function(){ // เมื่อฟอร์มที่มีไอดี news-form กำลังทำการส่งข้อมูล $("#news-form").on("submit",function(event){ // มีการส่ง event object event.preventDefault(); // ปิดค่าเริ่มต้น ในกรณีนี้คือไม่มีการรีเฟรชหรือเปลี่ยนหน้าเพจ // คำสังต่อจากบรรทัดนี้ทำงานได้ปกติ var dataSend = $(this).serialize(); var dataSend2 = $(this).serializeArray(); $.post("show.php",dataSend,function(response){ $("#place_ajax1").html(response); }); $.post("show.php",dataSend2,function(response){ $("#place_ajax2").html(response); }); }); }); </script>
ทดสอบกรอกข้อมูล และสังเกตผลลัพธ์ ตามรูปด้านล่าง
จะเห็นว่าถึงรูปแบบข้อมูลก่อนส่งจะต่างกันจากการใช้งาน serialize() และ serializeArray() แต่ค่าที่
ได้จะเหมือนกัน เป็นลักษณะการส่งข้อมูลแบบ POST เหมือนกับการส่งข้อมูลแบบปกติ
ดังนั้น การจะเลือกใช้วิธีใด ก็ให้ขึ้นกับว่าต้องการจัดการกับข้อมูลมากน้อยเพียงใด หรือว่าสะดวกในการเขียนแบบใด
ก็สามารถเลือกได้ตามต้องการ ในที่เราจะเลือกใช้ serialize() และปรับโค้ดใหม่ดังนี้
<script type="text/javascript"> $(function(){ // เมื่อฟอร์มที่มีไอดี news-form กำลังทำการส่งข้อมูล $("#news-form").on("submit",function(event){ // มีการส่ง event object event.preventDefault(); // ปิดค่าเริ่มต้น ในกรณีนี้คือไม่มีการรีเฟรชหรือเปลี่ยนหน้าเพจ // คำสังต่อจากบรรทัดนี้ทำงานได้ปกติ var dataSend = $(this).serialize(); $.post("show.php",dataSend,function(response){ $("#place_ajax1").html(response); $("#news-form")[0].reset(); // เมื่อส่งข้อมูลแล้วให้ รีเซ็ตฟอร์ม }); }); }); </script>
ทดลองกรอกข้อมูล แล้วกด submit จะเห็นว่าข้อมูลจะถูกส่งไปที่ไฟล์ show.php แบบทำงานเบื้องหลัง
ผ่านรูปแบบ ajax จากนั้นจะส่งค่าที่แสดงในไฟล์ show.php กลับมาในตัว parameter ที่ชือ response
เราก็เอาค่า response นี้ไปแสดงใน div ที่เราต้องการ จากนั้นก็รีเซ็ตข้อมูลในฟอร์ม ดังรูป
ทั้งหมดนี้คือการทำความเข้าใจพื้นฐานเกี่ยวกับ ajax ใน jquery เพื่อเป็นแนวทางต่อยอดต่อไป