เนื้อหานี้จะเป็นแนวทางสำหรับทำการดึงข้อมูล มาแสดงในตารางแบบ ajax โดยให้ข้อมูล
แสดงรายการแบ่งเป็นหน้าๆ และมีการวนลูปสลับหน้าไปเรื่อยๆ จนครบและกลับมาหน้าเริ่มต้น
โดยกำหนดจังหวะเวลาที่ต้องการแสดงในแต่ละหน้าตามต้องการ ในตัวอย่างสมมติให้เปลี่ยน
หน้าใหม่ทุกๆ 10 วินาที และผู้ใช้สามารถที่จะเลือกกดดูหน้ารายการที่ต้องการได้
โดยเนื้อหานี้จะเป็นการเอาโค้ดเก่ามาปรับเล็กน้อย และประยุกต์ใช้งานจากบทความ
(ทบทวนบทความได้ที่)
แจกโค้ด ajax เพิ่ม ลบ แก้ไข แบ่งหน้า ร่วมกัน bootstrap modal
https://www.ninenik.com/content.php?arti_id=770 via @ninenik
ดูตัวอย่างท้ายบทความ
ไฟล์ dbconnect.php
<?php $mysqli = new mysqli("localhost", "root","","test"); /* check connection */ if ($mysqli->connect_errno) { printf("Connect failed: %s\n", $mysqli->connect_error); exit(); } if(!$mysqli->set_charset("utf8")) { printf("Error loading character set utf8: %s\n", $mysqli->error); exit(); }
ไฟล์ jsondata.php
<?php header("Content-type:application/json; charset=UTF-8"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); require_once("dbconnect.php"); ////////////////////////////// BEGIN GET LISTITEM ////////////////////////////////////// ////////// ส่วนของการคิวรี่แสดงรายการทั้งหมด พร้อมการแบ่งหน้า if(isset($_POST['action']) && $_POST['action']=="list"){ $per_page = 10; // ตัวแปรเก็บจำนวนรายการที่่ต้องการแสดงในแต่ละหน้า (เปลี่ยนค่าได้) // รายการต่อไปนี้ไม่ต้องเปลี่ยนค่า $total = 0; // ตัวแปรจำนวนข้อูลทั้งหมด $start_page = 0; // ตัวแปรเก็บตัวกำหนด offset ใน LIMIT คำส่ัง sql $cur_page = 1; // ตำแปรเก็บหน้าปัจจุบัน $chk_page = 0; // ตำแปรเก็บหน้าตรวจสอบ // คำสั่ง sql เปลี่ยนค่าตามต้องการ $sql = " SELECT * FROM province_th WHERE 1 "; // รายการต่อไปนี้ไม่ต้องเปลี่ยนค่า $result = $mysqli->query($sql); if($result && $result->num_rows > 0){ // มีรายการข้อมูล $total = $result->num_rows; // นับจำนวนรายการทั้งหมดแล้วเก็บในตัวแปร $total } // มีการส่งหน้าที่ต้องการแสดงมา if(isset($_POST['page']) && $_POST['page']>0){ // เปลี่ยนค่าตัวแปรตามเงื่อนไขค่าที่ส่งมา $chk_page = $_POST['page']; $cur_page = $_POST['page']+1; $start_page = $_POST['page']*$per_page; } $sql.=" LIMIT ".$start_page.",".$per_page." "; $i=0; $result = $mysqli->query($sql); if($result && $result->num_rows > 0){ while($row = $result->fetch_assoc()){ $i++; // เปลี่ยนค่าตามต้องการ item_id ในที่นี้จะเป็นเลขลำดับ ไม่จำเป็นต้องแก้ไข // ส่วนค่าอื่นๆ เปลี่ยนไปตามฟิลด์หรือรูปแบบข้อมูลที่ต้องการ $json_data['data'][] = array( "item_id" => ($chk_page*$per_page)+$i, "prov_id" => $row['province_id'], "prov_name" => $row['province_name'] ); } // รายการต่อไปนี้ไม่ต้องเปลี่ยนค่า ใช้สำหรับส่งค่าไปใช้ในการกำหนดหน้าข้อมูลที่แสดง if($result->num_rows > 0){ $json_data['curpage'] = $cur_page; $json_data['perpage'] = $per_page; $json_data['total'] = $total; $json_data['allpage'] = ceil($total/$per_page); } } // ถ้ามีข้อมูล จะด้ตัวแปร $json_data สำหรับสร้างเป็น json data } ////////////////////////////// END GET LISTITEM ////////////////////////////////////// // แปลงตัวแปร $json_data array เป็นรูปแบบ json string data if(isset($json_data)){ $json= json_encode($json_data); if(isset($_GET['callback']) && $_GET['callback']!=""){ echo $_GET['callback']."(".$json.");"; }else{ echo $json; } }
โดยโค้ดไฟล์ jsondata.php นี้ส่วนที่เราจะต้องปรับก็คือ เปลี่ยนเป็นตารางข้อมูลที่ต้องการในสวนบรรทัด
$sql = " SELECT * FROM province_th WHERE 1 ";
และเปลี่ยนจำนวนของรายการที่ต้องการแสดง หรือฟิลด์ของตารางที่ต้องการใช้งานในส่วน
$json_data['data'][] = array( "item_id" => ($chk_page*$per_page)+$i, "prov_id" => $row['province_id'], "prov_name" => $row['province_name'] );
ในตัวอย่างเราใช้แค่ id ของจังหวัด และ ชื่อจังหวัด ส่วนตัวที่เป็น item_id ไม่ต้องแก้ไขก็ได้ จะเป็นลำดับของ
รายการนับจาก 1 2 ..... ไปเรื่อยๆ
ไฟล์ demo_autorefresh.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" style="width:500px;"> <br><br> <table class="table table-bordered table-striped"> <tr> <td>#</td> <td>ID</td> <td>Name</td> </tr> <tbody class="show-list-data"> <tr class="list-data"> <td></td> <td></td> <td></td> </tr> </tbody> </table> <nav aria-label="Page navigation"> <ul class="pagination"> <li> <a href="javascript:void(0);" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> <li><a href="javascript:void(0);"></a></li> <li> <a href="javascript:void(0);" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> </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"> var dataList = {} var init_page=0; var total_page=0; $(function(){ dataList.getList = function(s_page,show_page){ var haveData = null; $.post("jsondata.php",{ action:'list', page:s_page },function(response){ if(response != null && response.data.length > 0){ $(".pagination").removeClass("hidden"); $(".show-list-data").removeClass("hidden"); var rowData = $(".list-data").clone(true); $(".show-list-data").html(""); var rowListData = ""; $.each(response.data,function( i , v ){ rowListData = ""; rowListData+="<tr class=\"list-data\">"; rowListData+=$(rowData.find("td:eq(0)").text(response.data[i].item_id).end() .find("td:eq(1)").text(response.data[i].prov_id).end() .find("td:eq(2)").text(response.data[i].prov_name).end()).html(); rowListData+="</tr>"; $(".show-list-data").append(rowListData); total_page = response.allpage; }); // end loop if(show_page==true){ $(".pagination").find("li:first").unbind("click"); $(".pagination").find("li:last").unbind("click"); var rowPage = $('<li><a href="javascript:void(0);"></a></li>'); $(".pagination").find("li:not(:first):not(:last)").remove(); $(".pagination").find("li").removeClass("active"); var rowListPage = ""; for(i = 1; i <= response.allpage; i++){ rowListPage+="<li>"; rowListPage+=$(rowPage.find("a").text(i).end() .find("a").attr("href","javascript:dataList.getList('"+(i-1)+"',null)").end()).html(); rowListPage+="</li>"; if(i == response.allpage && rowListPage !=""){ $(".pagination").find("li:eq(0)").after(rowListPage); $(".pagination").find("li:eq(1)").addClass("active"); $(".pagination").find("li:not(':first'):not(':last')").on("click",function(){ $(".pagination").find("li").removeClass("active"); init_page = $(".pagination").find("li:not(':first'):not(':last')").index(this); $(this).addClass("active"); }); $(".pagination").find("li:first").on("click",function(){ var indexObj = $(".pagination").find("li.active").prev("li").index(); if(indexObj>0){ $(".pagination").find("li.active").prev("li").triggerHandler("click"); dataList.getList(indexObj-1,null); } }); $(".pagination").find("li:last").on("click",function(){ var indexObj = $(".pagination").find("li.active").next("li").index(); if(indexObj<=response.allpage){ $(".pagination").find("li.active").next("li").triggerHandler("click"); dataList.getList(indexObj-1,null); } }); } } } } }); if(haveData==null){ $(".show-list-data").addClass("hidden"); $(".pagination").addClass("hidden"); } } // ทำคำสั่งดึงข้อมูลมาแสดงโดยเริ่มต้นส่ง init_page เท่า 0 เพื่อดึงข้อมูลหน้าแรก dataList.getList(init_page,true); // กำหนดให้ทำงนทุกๆ 10 วิ (1000 = 1 วิ) setInterval(function(){ $(".pagination").find("li").removeClass("active"); if(init_page<total_page-1){ init_page++; }else{ init_page=0; } dataList.getList(init_page,null); $(".pagination").find("li:not(':first'):not(':last')").eq(init_page).addClass("active"); },10000); }); </script> </body> </html>
การประยุกต์นี้ต้องใช้งานกับ bootstrap css framework เพราะมีการจัดการ หรือใช้ค่าของ css class
สั่งที่ต้องปรับในไฟล์มี ดังนี้
1. แถวของจำนวนคอมลัมน์ของหัวข้อมูลในตาราง
เพิ่มจำนวน <td> ตามคอมลัมน์ของเราเอง
<tr> <td>#</td> <td>ID</td> <td>Name</td> </tr>
ในตัวอย่างเรามีแค่ 3 คอมลัมน์ ถ้ามีมากกว่านี้ให้ปรับจุดนี้
2. แถวของจำนวนคอลัมน์ของข้อมูลในตาราง
เพิ่มจำนวน <td> ตามคอมลัมน์ของเราเอง ให้สอดคล้องกับจำนวนหัวข้อ
<tr class="list-data"> <td></td> <td></td> <td></td> </tr>
3. ส่วนของโค้ดที่นำรายการข้อมูล ทีไปดึงมาแสดงใน ตาราง ตามบรรทัด
rowListData+=$(rowData.find("td:eq(0)").text(response.data[i].item_id).end() .find("td:eq(1)").text(response.data[i].prov_id).end() .find("td:eq(2)").text(response.data[i].prov_name).end()).html();
ตัว selector td:eq(0) คือข้อมูลของคอลัมน์แรกที่แสดงในตาราง ไล่ไปเรื่อยๆ อย่างคอลัมน์แรก
เราให้โชว์ลำดับรายการ ซึ่งมีค่าเป็น response.data[i].item_id โดย
item.id จะเป็นชื่อที่เรากำหนดในไฟล์ jsondata.php
ตัว selector td:eq(1) คือข้อมูลของคอลัมน์ที่สองที่แสดงในตาราง ซึ่งในตัวอย่างเราเป็น id ของจังหวัดในฐานข้อมูล
ใช้ค่าจากตัวแปร response.data[i].prov_id
prov_id.id จะเป็นชื่อที่เรากำหนดในไฟล์ jsondata.php
ทำเช่นนี้ไปเรื่อยๆ จนครบทุกรายการตามจำนวนที่เราต้องการ สมมติเราเพิ่มาเป็น 4 คอมลัมน์
โค้ดก็จะเป็นลักษณะดังนี้
rowListData+=$(rowData.find("td:eq(0)").text(response.data[i].item_id).end() .find("td:eq(1)").text(response.data[i].prov_id).end() .find("td:eq(2)").text(response.data[i].prov_name).end() .find("td:eq(3)").text(response.data[i].xxxx).end()).html();
xxx ก็คือตัวค่าที่เพิ่มเข้ามา ตามที่เรากำหนด แบบนี้เป็นต้น
4. ปรับความถี่ของการโหลดข้อมูลแต่ละหน้า
setInterval(function(){ $(".pagination").find("li").removeClass("active"); if(init_page<total_page-1){ init_page++; }else{ init_page=0; } dataList.getList(init_page,null); $(".pagination").find("li:not(':first'):not(':last')").eq(init_page).addClass("active"); },10000);
ในตัวอย่างเราใช้ 10000 หรือก็้คือ 10 วินาที หากต้องการเป็นค่าอื่น ก็เปลี่ยนเป็นตัวเลขตามต้องการ
แต่อยาลืมว่า การใช้ค่าที่น้อยเกินไป จะทำให้ข้อมูลมีการโหลดในจังหวะที่ถี่และเร็วเกินไป อาจจะทำให้ server ทำงานหนัก
ควรกำหนดให้ช่วงที่พอเหมาะ และเข้ากับรูปแบบของข้อมูล
ปล. จริงๆ การใช้ ฟังก์ชั่น setTimeout() ในการวนทำงานเพื่อไปดึงข้อมูลมาแสดงนั้น เป็นรูปแบบเดิมๆ ในการดึงข้อมูล
แบบ realtime ซึ่งยังสามารถใช้งานได้ดี ถ้าเป็นการใช้งานที่มีจำนวนผู้ใช้ไม่มาก แต่กรณีมีผู้ใช้จำนวนมากๆ การใช้งาน
ด้วยคำสั่งนี้จะทำให้ server ทำงานหนัก
ปัจจุบันสามารถใช้งานการทำงานในลักษณะนี้โดยใช้ nodejs หรือ socket.io ถ้ามีโอการสจะได้นำมาแนะนำในต่อๆ ไป