PHP Ionic Angularjs Phonegap AJAX Javascript CSS MySQL jQuery Forum


ดึงรายการแบบ realtime พร้อมแบ่งหน้า ด้วย ajax ร่วมกับ bootstrap css

20 March 2017 By
realtime ajax bootstrap แบ่งหน้า


เนื้อหานี้จะเป็นแนวทางสำหรับทำการดึงข้อมูล มาแสดงในตารางแบบ ajax โดยให้ข้อมูล
แสดงรายการแบ่งเป็นหน้าๆ และมีการวนลูปสลับหน้าไปเรื่อยๆ จนครบและกลับมาหน้าเริ่มต้น
โดยกำหนดจังหวะเวลาที่ต้องการแสดงในแต่ละหน้าตามต้องการ ในตัวอย่างสมมติให้เปลี่ยน
หน้าใหม่ทุกๆ 10 วินาที และผู้ใช้สามารถที่จะเลือกกดดูหน้ารายการที่ต้องการได้
    โดยเนื้อหานี้จะเป็นการเอาโค้ดเก่ามาปรับเล็กน้อย และประยุกต์ใช้งานจากบทความ
 
(ทบทวนบทความได้ที่)
แจกโค้ด ajax เพิ่ม ลบ แก้ไข แบ่งหน้า ร่วมกัน bootstrap modal 
http://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">&laquo;</span>
      </a>
    </li>
    <li><a href="javascript:void(0);"></a></li>
    <li>
      <a href="javascript:void(0);" aria-label="Next">
        <span aria-hidden="true">&raquo;</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 ถ้ามีโอการสจะได้นำมาแนะนำในต่อๆ ไป

 


   เพิ่มเติมเนื้อหา ครั้งที่ 1 วันที่ 20-03-2017


กรณีที่เราต้องการแสดงรูปภาพ ในตารางด้วย สามารถกำหนดได้ดังนี้

เพิ่มชื่อไฟล์รูปภาพ ในไฟล์ jsondata.php 

$json_data['data'][] = array(
    "item_id" 			=> ($chk_page*$per_page)+$i,
    "prov_id" 				=> $row['province_id'],
    "prov_name" 		=> $row['province_name'],
    "prov_pic" 		=> 'img1.jpg'
);

ตัวอย่างด้านบนกำหนดแบบตายตัว ถ้าดึงจากฐานข้อมูล ก็ใช้ตัวแปร $row['ฟิลด์ที่เก็บชื่อไฟล์รูปภาพ'] 

เพิ่มคอลัมน์ รูปภาพ และแทรกแท็ก img พร้อมกับกำหนดด style ให้กับรูปตามต้องการ

<table class="table table-bordered table-striped">
	<tr>
		<td>#</td>
        <td>ID</td>
		<td>Name</td>
        <td>img</td>
	</tr>
    <tbody class="show-list-data">
        <tr class="list-data">
            <td></td>
            <td></td>
            <td></td>
            <td><img src="" style="width:50px;"></td>
        </tr>
    </tbody>
</table>



สุดท้ายก็ส่วนดึงข้อมูลมาแสดง ถ้ามีความรู้เกี่ยวกับการใช้ selector ใน jquery ก็จะสามารถประยุกต์เป็นตัวอื่นๆ ได้

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) > img").attr("src",response.data[i].prov_pic).end()).html();	

บรรทัดสุดท้ายหมายถึง หาแท็กรูปภาพที่อยู่ในคอลัมน์ td ตัวสุดท้าย แล้วเปลี่ยน attribute ค่า src เป็นชื่อไฟล์รูปภาพที่เราส่ง
ค่ากลับมา  ถ้ามี path หรือโฟลเดอร์เก็บรูป ก็ให้บวกค่า string  เข้าไป ประมาณนี้

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) > img").attr("src",'pic/'+response.data[i].prov_pic).end()).html();	










Tags:: แบ่งหน้า ajax realtime bootstrap




เนื้อหาพิเศษ เฉพาะสำหรับสมาชิก

กรุณาล็อกอิน และลงชื่อติดตาม


สมัครสมาชิกได้ที่        ล็อกอินได้ที่   



อย่าลืมกด Like กด Share เป็นกำลังใจ ในการสร้างบทความใหม่ๆ น่ะครับ


URL สำหรับอ้างอิง