ประยุกต์ PHP ฟังก์ชั่น กับ Bootstrap 4 Pagination Component

เขียนเมื่อ 5 ปีก่อน โดย Ninenik Narkdee
ค้นหาข้อมูล bootstrap 4 แบ่งหน้า pagination

คำสั่ง การ กำหนด รูปแบบ ตัวอย่าง เทคนิค ลูกเล่น การประยุกต์ การใช้งาน เกี่ยวกับ ค้นหาข้อมูล bootstrap 4 แบ่งหน้า pagination



เนื้อหาเกี่ยวกับการสร้าง php ฟังก์ชั่น สำหรับจัดการการแบ่งหน้ารายการข้อมูล
ที่ดึงมาจากฐานข้อมูล เราเคยมีตัวอย่างไปแล้วในบทความ
    แนวทาง การค้นหาจาก หลายรูปแบบ และแบ่งหน้า อย่างง่าย http://niik.in/573 
 
และเนื้อหาต่อไปนี้ ก็จะมีรูปแบบคล้ายๆ กัน แต่เป็นการประยุก์เพิ่มเติม โดยสร้างฟังก์ชั่นสำหรับแบ่ง
หน้าโดยใช้งานร่วมกับ Pagination Component ของ Bootstrap 4 โดยในที่นี้จะนำเสนอใน
2 รูปแบบ คือแบบแรกเป็นการดึงข้อมูลมาแสดง โดยมีแค่เพียงการแบ่งหน้าข้อมูลเท่านั้น 
และแบบที่สอง คือมีการแบ่งหน้าข้อมูล และรองรับการค้นหา 
    แนวทางการประยุกต์จะยึดเนื้อหาของบทความจากลิ้งค์ด้านบนเป็นแนวทาง คือเป็นการดึงราย
การข้อมูลจังหวัดในประเทศไทย มาแสดงในตาราง
 

รูปแบบที่ 1 แสดงแบบแบ่งหน้าอย่างเดียว

 
ไฟล์ demo_001.php ไฟล์เริ่มต้นใช้งาน bootstrap
 
<!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" >
    <style type="text/css">
		html{
			font-family:tahoma, Arial,"Times New Roman";
			font-size:14px;
		}
		body{
			font-family:tahoma, Arial,"Times New Roman";
			font-size:14px;
		}    
    </style>
</head>
<body>

<br>
<br>
<div class="container">

</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(){
	
});
</script>
</body>
</html>
 
ไฟล์ 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();  
}
 
ไฟล์ pagination_function.php
 
<?php
function page_navi($total_item, $cur_page, $per_page=10, $query_str="", $min_page=5){

$total_page = ceil($total_item/$per_page);
$cur_page = (isset($cur_page))?$cur_page:1;
$diff_page = NULL;
if($cur_page>$min_page){
	$diff_page = $total_page-$cur_page;
}
$limit_page = $min_page;
$f_num_page = ($cur_page<=$min_page)?1:(floor($cur_page/$min_page)*$min_page)+1;
if($diff_page>$min_page){
	$limit_page = ($min_page + $f_num_page)-1;
}else{
	if(isset($diff_page)){
		$limit_page = $total_page;
	}else{
		$limit_page = $min_page;
	}
}
$show_page = ($total_page<=$min_page)?$total_page:$limit_page;
$l_num_page = 1;
$prev_page = $cur_page-1;
$next_page = $cur_page+1;
$temp_query_str = $query_str;
$query_str = "";
if($temp_query_str && is_array($temp_query_str) && count($temp_query_str)>0){
	array_pop($temp_query_str);
	$query_str = http_build_query($temp_query_str);
	if($query_str!=""){
		$query_str = "?".$query_str;	
	}
}
$mark_char = ($query_str!="")?"&":"?";

  echo '<nav>
      <ul class="pagination justify-content-center">
        <li class="page-item">
		<a class="page-link" href="'.$query_str.$mark_char.'page=1"> First</a>
		</li>
		';
	echo '
        <li class="page-item '.(($cur_page==1)?"disabled":"").'">
          <a class="page-link"  href="'.$query_str.$mark_char.'page='.$prev_page.'"> Previous</a> 
        </li>	
	';	
	for($i = $f_num_page; $i<=$show_page;$i++){
	echo '     
        <li class="page-item '.(($i==$cur_page)?"active":"").'"> 
          <a class="page-link" href="'.$query_str.$mark_char.'page='.$i.'"> '.$i.' </a> 
        </li>     
	';
	}
	echo '
        <li class="page-item '.(($next_page>$total_page)?"disabled":"").'"> 
			<a class="page-link"  href="'.$query_str.$mark_char.'page='.$next_page.'"> Next</a> 
        </li>   	
	';	
	echo '
        <li class="page-item">
          <input type="number" class="form-control" min="1" max="'.$total_page.'"
                  style="width:80px;" onClick="this.select()" onchange="window.location=\''.$query_str.$mark_char.'page=\'+this.value"  value="'.$cur_page.'" />
        </li>	
	';
	echo '
        <li class="page-item"> 
			<a class="page-link"  href="'.$query_str.$mark_char.'page='.$total_page.'"> Last</a> 
        </li>   	
      </ul>
    </nav>		
	';		
}
?>
 
ในฟังก์ชั่น page_navi() เรามีการใช้งาน paginaton component ของ bootstrap มาจัดรูปแบบ โดยตัว
ฟังก์ชั่นสำหรับแบ่งหน้าที่เราขึ้น จะมีรูปแบบตามรูปด้านล่าง
 


 
 
สามารถเลื่อนไปหน้าแรก ไปหน้าสุดท้าย หรือเลือกหน้าที่ต้องการ หรือไปหน้าก่อนหน้า หรือหน้าถัดไป
สามารถเลือกเปลี่ยนเลขหน้าที่ช่อง input เพื่อไปหน้าที่ต้องการได้
 
ตัวฟังก์ชั่น จะรับค่า parameter ต่างๆ ตามรูปแบบดังนี้
 
page_navi($total_item, $cur_page, $per_page=10, $query_str="", $min_page=5)
 
  • $total_item จำนวนรายการข้อมูลทั้งหมด 
  • $cur_page หน้าปัจจุบัน
  • $per_page=10 จำนวนรายการทีแสดงในแต่ละหน้า ถ้าไม่มีการส่งค่าจะใช้ค่าเท่ากับ 10
  • $query_str="" สำหรับรองรับการส่งค่าเพิ่มเติมกรณีมีการค้นหา ถ้าไม่มีการกำหนดจะเป็นค่าว่าง
  • $min_page=5 จำนวนเลขหน้าอย่างน้อยที่ต้องการแสดง ถ้าไม่กำหนด จะแสดงเลขหน้าไม่เกิน 5 ปุ่ม
 
ต่อไปเราจะนำไฟล์ต่างๆ มารวมกัน และประยุกต์ดึงข้อมูลจากฐานข้อมูลจังหวัดมาแสดง และแบ่งหน้า
จะได้ไฟล์ demo_001.php ปรับโค้ดเป็นดังนี้
 
ไฟล์ demo_001.php
 
<?php
require_once("dbconnect.php");
require_once("pagination_function.php");
?>
<!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" >
    <style type="text/css">
		html{
			font-family:tahoma, Arial,"Times New Roman";
			font-size:14px;
		}
		body{
			font-family:tahoma, Arial,"Times New Roman";
			font-size:14px;
		}    
    </style>
</head>
<body>

<br>
<br>
<div class="container">

<div class="table-responsive-sm">
<table class="table table-bordered table-striped table-hover table-sm">
  <thead >
    <tr class="table-primary">
      <th class="text-center" scope="col" width="30">#</th>
      <th class="text-left" scope="col">ชื่อจังหวัด</th>
    </tr>
  </thead>
  <tbody>
<?php
$num = 0;
$sql = "
SELECT * FROM province_th WHERE 1 
";  
$result=$mysqli->query($sql);
$total=$result->num_rows;

$e_page=10; // กำหนด จำนวนรายการที่แสดงในแต่ละหน้า   
$step_num=0;
if(!isset($_GET['page']) || (isset($_GET['page']) && $_GET['page']==1)){   
	$_GET['page']=1;   
	$step_num=0;
	$s_page = 0;	
}else{   
	$s_page = $_GET['page']-1;
	$step_num=$_GET['page']-1;	
	$s_page = $s_page*$e_page;
}   
$sql.=" ORDER BY province_id  LIMIT ".$s_page.",$e_page";
$result=$mysqli->query($sql);
if($result && $result->num_rows>0){  // คิวรี่ข้อมูลสำเร็จหรือไม่ และมีรายการข้อมูลหรือไม่
    while($row = $result->fetch_assoc()){ // วนลูปแสดงรายการ
		$num++;
?>
    <tr>
      <th class="text-center" scope="row"><?=($step_num*$e_page)+$num?></th>
      <td class="text-left" ><?=$row['province_name']?></td>
    </tr>
<?php
    }   
}
?>      
  </tbody>
</table>

<?php
page_navi($total,(isset($_GET['page']))?$_GET['page']:1,$e_page);
?>
</div>

<br>
</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(){
	
});
</script>
</body>
</html>
 
บรรทัดที่เราสามารถแก้ไข กรณีนำไปประยุกต์ใช้ คือบรรทัดที่ highlight ไว้ ได้แก่
บรรทัดที่ 40-42 เป็นส่วนของคำสั่ง SQL ที่ต้องการ ในตัวอย่างเรากำหนด WHERE 1 ไว้เพื่อรองรับ
การเพิ่มเงื่อนไขที่อาจจะมีในอนาคต
บรรทัดที่ 46 จำนวนรายการที่จะแสดงในแต่ละหน้า 
บรรทัดที่ 57 เงื่อนไขการเรียงข้อมูล เปลี่ยนไปตามรูปแบบที่ต้องการ แต่ให้คง LIMIT ".$s_page.",$e_page ไว้
 
ในส่วนบรรทัดที่ 75 การเรียกใช้งานฟังก์ชั่นแบ่งหน้า page_navi()
 
page_navi($total,(isset($_GET['page']))?$_GET['page']:1,$e_page);
 
เรามีการส่งค่าไปทั้งหมด 3 ค่า คือ 
$total
    จำนวนรายการทั้งหมด
 
(isset($_GET['page']))?$_GET['page']:1 
    หน้าปัจจุบัน ใช้การเช็คว่ามีการส่งค่าหน้าหรือไม่ ถ้า
ยังไม่มีการส่งค่าหน้าผ่านตัวแปร $_GET'page'] ให้หน้าเริ่มต้นเป็นหน้าที่ 1
 
$e_page
    จำนวนรายการที่แสดงแต่ละหน้า เราใช้ค่าจากตัวแปรที่กำหนดด้านบท คือ 10 รายการต่อหน้า
 
 

ทดสอบตัวอย่างและผลลัพธ์ได้ที่ https://www.ninenik.com/demo/bootstrap4/demo_001.php

 
สมมติเราเพิ่มจำนวนการแสดงปุ่มเลขหน้า เข้าไปเป็น 10 ด้วยการเรียกใช์ดังนี้
 
page_navi($total,(isset($_GET['page']))?$_GET['page']:1,$e_page,'',10);
 
จะได้ผลลัพธ์ในส่วนของการแบ่งหน้าเป็นดังนี้
 


 
 
เนื่องเรามีรายชื่อจังหวัดทั้งหมดเพียง 77 จังหวัด แสดงหน้าละ 10 เราจะสามารถแบ่งได้ทั้งหมด 8 หน้า
ดังนั้นเมื่อเรากำหนดให้แสดงปุ่มเลขหน้าอย่างน้อย 10 ปุ่ม จำนวนปุ่มที่แสดงจริง จึงเท่ากับ 8 ตาม
จำนวนหน้าทั้งหมดที่มีอยู่จริง
    แต่กรณีแรก เราไม่ได้มีการกำหนดจำนวนปุ่ม ทำให้มีการใช้ค่าเริ่มต้นคือ 5 เราจึงเห็นจำนวนปุ่มแสดง
แค่เพียง 5 รายการ และถ้าเรากดไปที่หน้าที่ 6 ก็จะแสดงปุ่มหน้าที่ 6-8 โดยเริ่มปุ่มแรกที่ปุ่มหน้าที่ 6 
ตามรูปด้านล่างประกอบ
 


 
 


 

รูปแบบที่ 2 แสดงแบบแบ่งหน้า และการค้นหาข้อมูล

 
รูปแบบที่สองนี้ ก็จะเป็นการประยุกต์เพิ่มเติมจากรูปแบบแรก คือ การแบ่งหน้า จะรองรับกรณีการค้นหาข้อมูล
ด้วยเงื่อนไขต่างๆ ด้วย ซึ่งเมื่อมีการค้นหาข้อมูล รายการข้อมูล ก็จะแปรเปลี่ยนไปตามเงื่อนไขของตัวแปร
ที่ส่งเข้ามา ให้เราใช้ตัวอย่างจากไฟล์แรก แล้วเปลี่ยนชื่อไฟล์เป็น demo_002.php แล้วปรับโค้ดใหม่
เป็นดังนี้
 
ไฟล์ demo_002.php
 
<?php
require_once("dbconnect.php");
require_once("pagination_function.php");
?>
<!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" >
    <style type="text/css">
		html{
			font-family:tahoma, Arial,"Times New Roman";
			font-size:14px;
		}
		body{
			font-family:tahoma, Arial,"Times New Roman";
			font-size:14px;
		} 
		.margin_top_5{
			margin-top: 5px;	
		}
    </style>
</head>
<body>

<br>
<br>
<div class="container">

<form name="form1" method="get" action="">
<div class="form-group row">
    <label for="keyword" class="col-sm-4 col-form-label text-right">
    พิมพ์บางคำ บางตัว หรือไม่พิมพ์ก็ได้ 
    </label>
    <div class="col-sm-3">
      <input type="text" class="form-control" name="keyword" id="keyword"  
       value="<?=(isset($_GET['keyword']))?$_GET['keyword']:""?>">
    </div>
</div>    
<div class="form-group row">
    <label for="myselect" class="col-sm-4 col-form-label text-right">
    เลือกอย่างหนึ่งอย่างใด หรือไม่เลือกก็ได้
    </label>
    <div class="col-sm-3">
        <select class="custom-select" name="myselect" id="myselect">
            <option value="">เลื่อกเงื่่อนไข</option>
            <option value="ก" <?=(isset($_GET['myselect']) && $_GET['myselect']=="ก")?" selected":""?> >ขึ้นต้นด้วย ก</option>
            <option value="อุ" <?=(isset($_GET['myselect']) && $_GET['myselect']=="อุ")?" selected":""?> >ขึ้นต้นด้วย อุ</option>
        </select>
    </div>
</div>    
<div class="form-group row">
    <label for="" class="col-sm-4 col-form-label text-right">
    เลือกอย่างหนึ่งอย่างใด หรือไม่เลือกก็ได้
    </label>
    <div class="col-sm-3">
        <div class="custom-control custom-radio custom-control-inline margin_top_5">
          <input type="radio" id="myradio1" name="myradio" value="จ" 
          <?=(isset($_GET['myradio']) && $_GET['myradio']=="จ")?" checked":""?> class="custom-control-input">
          <label class="custom-control-label" for="myradio1">มี "จ"</label>
        </div>
        <div class="custom-control custom-radio custom-control-inline margin_top_5">
          <input type="radio" id="myradio2" name="myradio" value="ม" 
          <?=(isset($_GET['myradio']) && $_GET['myradio']=="ม")?" checked":""?> class="custom-control-input">
          <label class="custom-control-label" for="myradio2">มี "ม"</label>
        </div>
        <div class="custom-control custom-radio custom-control-inline margin_top_5">
          <input type="radio" id="myradio3" name="myradio" value="ส" 
          <?=(isset($_GET['myradio']) && $_GET['myradio']=="ส")?" checked":""?> class="custom-control-input">
          <label class="custom-control-label" for="myradio3">มี "ส"</label>
        </div>        
    </div>        
</div>
<div class="form-group row">
    <label for="" class="col-sm-4 col-form-label text-right">
    เลือกอย่างหนึ่งอย่างใด หรือเลือกทั้งสอง หรือไม่เลือกก็ได้
    </label>
    <div class="col-sm-3">
        <div class="custom-control custom-checkbox custom-control-inline margin_top_5">
          <input type="checkbox" id="mycheckbox1" name="mycheckbox1" value="นี"
          <?=(isset($_GET['mycheckbox1']) && $_GET['mycheckbox1']=="นี")?" checked":""?>  class="custom-control-input">
          <label class="custom-control-label" for="mycheckbox1">ลงท้ายด้วย "นี"</label>
        </div>
        <div class="custom-control custom-checkbox custom-control-inline margin_top_5">
          <input type="checkbox" id="mycheckbox2" name="mycheckbox2" value="คร" 
          <?=(isset($_GET['mycheckbox2']) && $_GET['mycheckbox2']=="คร")?" checked":""?> class="custom-control-input">
          <label class="custom-control-label" for="mycheckbox2">ลงท้ายด้วย "คร"</label>
        </div>  
    </div>        
</div>
<div class="form-group row">
    <div class="col-sm-4 offset-sm-4">
      <button type="submit" class="btn btn-primary" name="btn_search" id="btn_search">ค้นหา</button>
      &nbsp;&nbsp;
      <a href="demo_002.php" class="btn btn-danger">ล้างค่า</a>
    </div>
</div>
</form>

<div class="table-responsive-sm">
<table class="table table-bordered table-striped table-hover table-sm">
  <thead >
    <tr class="table-primary">
      <th class="text-center" scope="col" width="30">#</th>
      <th class="text-left" scope="col">ชื่อจังหวัด</th>
    </tr>
  </thead>
  <tbody>
<?php
$num = 0;
$sql = "
SELECT * FROM province_th WHERE 1 
";  

//////////////////// MORE QUERY 
// เงื่อนไขสำหรับ radio
if(isset($_GET['myradio']) && $_GET['myradio']!=""){
	// ต่อคำสั่ง sql 
	$sql.=" AND province_name LIKE '%".trim($_GET['myradio'])."%' ";	
}

// เงื่อนไขสำหรับ input text
if(isset($_GET['keyword']) && $_GET['keyword']!=""){
	// ต่อคำสั่ง sql 
	$sql.=" AND province_name LIKE '%".trim($_GET['keyword'])."%' ";	
}

// เงื่อนไขสำหรับ select
if(isset($_GET['myselect']) && $_GET['myselect']!=""){
	// ต่อคำสั่ง sql 
	$sql.=" AND province_name LIKE '".trim($_GET['myselect'])."%' ";	
}

// เงื่อนไขสำหรับ checkbox
if((isset($_GET['mycheckbox1']) && $_GET['mycheckbox1']!="") 
|| (isset($_GET['mycheckbox2']) && $_GET['mycheckbox2']!="")){
	// ต่อคำสั่ง sql 
	if($_GET['mycheckbox1']!="" && $_GET['mycheckbox2']!=""){
		 $sql.=" 
		 AND (province_name LIKE '%".trim($_GET['mycheckbox1'])."' 
		 OR province_name LIKE '%".trim($_GET['mycheckbox2'])."' )
		 ";	
	}elseif($_GET['mycheckbox1']!=""){
		 $sql.=" AND province_name LIKE '%".trim($_GET['mycheckbox1'])."' ";	                
	}elseif($_GET['mycheckbox2']!=""){
		 $sql.=" AND province_name LIKE '%".trim($_GET['mycheckbox2'])."' ";	                
	}else{
		
	}
}
//////////////////// MORE QUERY 
$result=$mysqli->query($sql);
$total=$result->num_rows;

$e_page=10; // กำหนด จำนวนรายการที่แสดงในแต่ละหน้า   
$step_num=0;
if(!isset($_GET['page']) || (isset($_GET['page']) && $_GET['page']==1)){   
	$_GET['page']=1;   
	$step_num=0;
	$s_page = 0;	
}else{   
	$s_page = $_GET['page']-1;
	$step_num=$_GET['page']-1;	
	$s_page = $s_page*$e_page;
}   
$sql.=" ORDER BY province_id  LIMIT ".$s_page.",$e_page";
$result=$mysqli->query($sql);
if($result && $result->num_rows>0){  // คิวรี่ข้อมูลสำเร็จหรือไม่ และมีรายการข้อมูลหรือไม่
    while($row = $result->fetch_assoc()){ // วนลูปแสดงรายการ
		$num++;
?>
    <tr>
      <th class="text-center" scope="row"><?=($step_num*$e_page)+$num?></th>
      <td class="text-left" ><?=$row['province_name']?></td>
    </tr>
<?php
    }   
}
?>      
  </tbody>
</table>

<?php
page_navi($total,(isset($_GET['page']))?$_GET['page']:1,$e_page,$_GET);
?>
</div>

<br>

<br>
</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(){
	
});
</script>
</body>
</html>
 
สำหรับในรูปแบบที่สอง สิ่งที่เราเพิ่มเข้ามาก็คือส่วนของฟอร์ม ที่เป็นเงื่อนไขเพิ่มเติมในการค้นหา
หรือใช้ในการกรองข้อมูล โดยเราจะใช้วิธีการส่งค่าแบบ GET 
    เมื่อมีฟอร์มแล้ว เราก็ต้องมีส่วนของการกำหนดเงื่อนไขคำสั่ง sql เพิ่มเติม โดยใช้ค่าจาก element
ต่างๆ ในฟอร์มที่ส่งมา ใช้เป็นตัวกำหนดเงื่อนไข ตามบรรทัดที่ 117-153
    ส่วนสุดท้ายที่เพิ่มเข้ามาเล็กน้อย ในการส่ง parameter เข้าไปในฟังก์ชั่นแบ่งหน้าคือตัวแปร $_GET
ตามรูปแบบการเรียกใช้งานในบรรทัดที่ 186
 

ทดสอบตัวอย่างและผลลัพธ์ได้ที่ https://www.ninenik.com/demo/bootstrap4/demo_002.php

 
แนวทางการประยุกต์ข้างต้น เราสามารถนำไปดัดแปลงเพิ่มเติม เช่น อาจจะสร้างในรูปแบบ class ไว้ใช้งาน
หรือปรับแต่ง เพิ่มเติมได้ตามต้องการ หวังว่าแนวทางนี้ จะทำให้เราสามารถนำไปใช้งานในส่วนของ
การแบ่งหน้าได้สะดวกและง่ายขึ้น





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







เนื้อหาที่เกี่ยวข้อง









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











เว็บไซต์ของเราให้บริการเนื้อหาบทความสำหรับนักพัฒนา โดยพึ่งพารายได้เล็กน้อยจากการแสดงโฆษณา โปรดสนับสนุนเว็บไซต์ของเราด้วยการปิดการใช้งานตัวปิดกั้นโฆษณา (Disable Ads Blocker) ขอบคุณครับ