Datatable:ประยุกต์สร้างลิงค์ภายใน datatable พร้อมส่ง primary key เพื่อนำไป query ข้อมูลและแสดง sub table

By -

บ่อยครั้งในการเขียนเว็บ เรามักจะแสดงข้อมูลออกมาในรูปแบบของตาราง โดยเฉพาะข้อมูลเชิงสถิติ ซึ่งวันนี้ผมจะมาแนะนำการประยุกต์ สร้างลิงค์ภายใน datatable พร้อมกับส่งค่า primary key เพื่อนำไป query ข้อมูลและแสดง sub table

เพื่อไม่ให้เป็นการเสียเวลา เรามาทำความเข้าใจกับโปรแกรมนี้กันก่อนครับ
ก่อนอื่นผมขออธิบายหลักการทำงานของโปรแกรมก่อน

โดยโปรแกรมนี้จะเป็นโปรแกรมง่ายๆ ที่แสดงข้อมูลจำนวนประชากรทั้งหมด ของแต่ละจังหวัด เมื่อคลิ๊กที่ชื่อจังหวัด จะแสดง sub table ขึ้นมา แสดงรายละเอียดว่าแต่ละเขตนั้น มีจำนวนประชากรทั้งหมดเท่าไหร่

เรามาเริ่มเขียนโปรแกรมกันเลยดีกว่า

อันดับแรก ให้เราสร้าง database กันก่อนครับ
เพื่อความรวดเร็วให้ท่าน ดาวน์โหลด แตก zip แล้ว import เลยครับ

database ชื่อ tutorialdev_demo1
โดยมีโครงสร้าง table ดังนี้

Table : province (รายชื่อจังหวัด)

Name Type Description
province_id int(11) รหัสจังหวัด
province_name varchar(50) ชื่อจังหวัด

Table : amphoe (รายชื่ออำเภอ)

Name Type Description
province_id int(11) รหัสจังหวัด
amphoe_id int(11) รหัสอำเภอ
amphoe_name varchar(50) ชื่ออำเภอ

Table : population (ข้อมูลจำนวนประชากร)

Name Type Description
province_id int(11) รหัสจังหวัด
amphoe_id int(11) รหัสอำเภอ
population_male int(11) จำนวนประชากรชาย
population_female int(11) จำนวนประชากรหญิง

เมื่อจัดการกับ database เรียบร้อย ก็มาถึงขั้นตอนการลงโค๊ดครับ

สร้างโฟลเดอร์โปรเจค ตั้งชื่อว่า tutorialdev_demo1
สร้างไฟล์ connectdb.php เพื่อใช้ติดต่อกับฐานข้อมูล

<?php
error_reporting(0);
function runSQL($rsql) {
	$hostname = "localhost";
	$username = "root";
	$password = "";
	$dbname   = "tutorialdev_demo1";
	$connect = mysql_connect($hostname,$username,$password) or die ("Error: could not connect to database");
	$db = mysql_select_db($dbname);
	mysql_query("set character set utf8");     
	$result = mysql_query($rsql) or die ('Error: could not query data' . $rsql); 
	return $result;
	mysql_close($connect);
}

function countRec($fname,$tname,$where) {
	$sql = "SELECT count($fname) FROM $tname $where";
	$result = runSQL($sql);
	while ($row = mysql_fetch_array($result)) {
		return $row[0];
	}
}
?>

สร้างไฟล์ datatable_show_population.php เพื่อสร้าง datasource เพื่อนำไปใช้แสดงข้อมูลประชากรทั้งหมดของแต่ละจังหวัด รูปแบบข้อมูลจะเป็น json ครับ

<?php
	header("Content-type: text/html; charset=UTF-8");
	header('Cache-Control: no-cache');
	header('Pragma: no-cache');
	header('Expires: 0');
	include("connectdb.php");
	$where = "";
	$sql = "SELECT province.province_id AS province_id,province_name,SUM(population_male) AS population_male,SUM(population_female) AS population_female FROM population INNER JOIN province ON province.province_id = population.province_id GROUP BY province.province_id $where";
	$result = runSQL($sql);
	$numrow = countRec('province_id','province',$where);
	if($numrow>0){
		$json = "";
		$json .= "{";
		$json .= "\"aaData\":[";
		$rc = false;
		while ($row = mysql_fetch_array($result)) {
			if ($rc) $json .= ",";
			$json .= "[";
			$json .= "\"".$row['province_name']."\"";
			$json .= ",\"".number_format($row['population_male'])."\"";
			$json .= ",\"".number_format($row['population_female'])."\"]";
			$rc = true;
		}
			$json .= "]";
			$json .= "}";
			echo $json;
	}
?>

เสร็จแล้วลองรันไฟล์ datatable_show_population.php เพื่อดูผลลัพท์ครับ ว่าได้ชุดข้อมูลที่เป็น json จริงรึป่าว

{"aaData":[["กรุงเทพมหานคร","162","218"],["สมุทรปราการ","270","242"],["นนทบุรี","231","242"],["ปทุมธานี","174","204"],["อ่างทอง","255","254"]]}

เมื่อเตรียม datasource ให้กับ datatable เรียบร้อยแล้ว ก็ได้เวลาสร้างหน้า display ข้อมูล

ก่อนอื่นให้ท่านไป ดาวน์โหลด js และ css ที่จำเป็นต้องใช้ในโปรแกรมก่อนครับ

เสร็จแล้วให้แตก zip แล้วนำไฟล์ ไปวางไว้ในโฟล์เดอร์โปรเจคครับ

จากนั้นสร้างไฟล์ index.php เพื่อแสดง datatable

<?php
	header("Content-type: text/html; charset=UTF-8");
	header('Cache-Control: no-cache');
	header('Pragma: no-cache');
	header('Expires: 0');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<title>tutorialdev demo1</title>
<link rel="stylesheet" type="text/css" media="screen" href="css/stylesheet.css" />
<link rel="stylesheet" href="css/redmond/jquery-ui-1.8.14.custom.css">
<style type="text/css" title="currentStyle">
	@import "css/demo_table_jui.css";
	@import "css/TableTools_JUI.css";
</style>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" language="javascript" src="js/jquery.dataTables.min.js"></script>
<style type="text/css">
.right{
  text-align: right;
}
 
.left{
  text-align: left;
}

.center{
  text-align: center;
}

</style>
<script type="text/javascript">

$(document).ready(function(){
	var initParams = {
		"oLanguage": {   
			"oPaginate": {       
				"sFirst": "หน้าแรก",
				"sLast": "หน้าสุดท้าย",
				"sNext": "ถัดไป",
				"sPrevious": "ก่อนหน้า"
			},
			"sLengthMenu": "แสดง _MENU_ รายการ ต่อหน้า",  
			"sZeroRecords": "ไม่พบข้อมูลที่ค้นหา", 
			"sInfo": "แสดง _START_ ถึง _END_ จากทั้งหมด _TOTAL_ รายการ",
			"sEmptyTable": "ไม่พบรายการข้อมูล",
			"sLoadingRecords": "ระบบกำลังประมวลผล กรุณารอซักครู่",
			"sProcessing": "ประมวลผลข้อมูล",
			"sInfoEmpty": "ไม่พบรายการข้อมูลที่แสดง",
			"sInfoFiltered": "(จากทั้งหมด _MAX_ รายการ)",  
			"sSearch": "ค้นหา :"
		},
		"aoColumns" : [  
			{ sClass: "left" },  
			{ sClass: "right" },
			{ sClass: "right" }
		],
		"bJQueryUI": true,
		"sPaginationType": "full_numbers",
		"bProcessing": true,
		"iDisplayLength": 10,
		"sAjaxSource": "datatable_show_population.php"
	};
	var oTable = $('#datatable').dataTable(initParams);
});

</script>
</head>
<body>
<div class="main-content resize" >
	<h1>tutorialdev_demo1</h1>
	<p></p>
</div>
<table cellpadding="0" cellspacing="0" border="0" class="display" id="datatable" width="100%">
	<thead>
		<tr>
			<th width="100" class="center">จังหวัด</th>
			<th width="100" class="center">ชาย</th>
			<th width="100" class="center">หญิง</th>
		</tr>
	</thead>
	<tbody>
	</tbody>
</table>
</body>
</html>

เสร็จแล้วลองรันไฟล์ index.php เพื่อดูผลลัพท์ครับ

จะเห็นว่าเราได้ตารางแสดงข้อมูลจำนวนทั้งหมดของประชากรแต่ละจังหวัดแล้ว แต่ยังไม่สามารถคลิ๊กที่ชื่อจังหวัดเพื่อเข้าไปดูรายละเอียดของแต่ละเขตได้

ขั้นตอนต่อไป ให้ไปเพิ่ม function openWindow ที่ไฟล์ index.php

<?php
	header("Content-type: text/html; charset=UTF-8");
	header('Cache-Control: no-cache');
	header('Pragma: no-cache');
	header('Expires: 0');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<title>tutorialdev demo1</title>
<link rel="stylesheet" type="text/css" media="screen" href="css/stylesheet.css" />
<link rel="stylesheet" href="css/redmond/jquery-ui-1.8.14.custom.css">
<style type="text/css" title="currentStyle">
	@import "css/demo_table_jui.css";
	@import "css/TableTools_JUI.css";
</style>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" language="javascript" src="js/jquery.dataTables.min.js"></script>
<style type="text/css">
.right{
  text-align: right;
}
 
.left{
  text-align: left;
}

.center{
  text-align: center;
}

</style>
<script type="text/javascript">

$(document).ready(function(){
	var initParams = {
		"oLanguage": {   
			"oPaginate": {       
				"sFirst": "หน้าแรก",
				"sLast": "หน้าสุดท้าย",
				"sNext": "ถัดไป",
				"sPrevious": "ก่อนหน้า"
			},
			"sLengthMenu": "แสดง _MENU_ รายการ ต่อหน้า",  
			"sZeroRecords": "ไม่พบข้อมูลที่ค้นหา", 
			"sInfo": "แสดง _START_ ถึง _END_ จากทั้งหมด _TOTAL_ รายการ",
			"sEmptyTable": "ไม่พบรายการข้อมูล",
			"sLoadingRecords": "ระบบกำลังประมวลผล กรุณารอซักครู่",
			"sProcessing": "ประมวลผลข้อมูล",
			"sInfoEmpty": "ไม่พบรายการข้อมูลที่แสดง",
			"sInfoFiltered": "(จากทั้งหมด _MAX_ รายการ)",  
			"sSearch": "ค้นหา :"
		},
		"aoColumns" : [  
			{ sClass: "left" },  
			{ sClass: "right" },
			{ sClass: "right" }
		],
		"bJQueryUI": true,
		"sPaginationType": "full_numbers",
		"bProcessing": true,
		"iDisplayLength": 10,
		"sAjaxSource": "datatable_show_population.php"
	};
	var oTable = $('#datatable').dataTable(initParams);
});

//-----------------------------เพิ่มใหม่-----------------------------\\
function openWindow(params) {
	window.open('index_aa.php' + params,'new1','location=0,toolbar=0,directories=0,status=0,menubar=0,scrollbars=1,resizable=0,width=800,height=800');
}
//-----------------------------เพิ่มใหม่-----------------------------\\
 
</script>
</head>
<body>
<div class="main-content resize" >
	<h1>tutorialdev_demo1</h1>
	<p></p>
</div>
<table cellpadding="0" cellspacing="0" border="0" class="display" id="datatable" width="100%">
	<thead>
		<tr>
			<th width="100" class="center">จังหวัด</th>
			<th width="100" class="center">ชาย</th>
			<th width="100" class="center">หญิง</th>
		</tr>
	</thead>
	<tbody>
	</tbody>
</table>
</body>
</html>

จากนั้น เปิดไฟล์ datatable_show_population.php แก้ไขตามนี้

<?php
	header("Content-type: text/html; charset=UTF-8");
	header('Cache-Control: no-cache');
	header('Pragma: no-cache');
	header('Expires: 0');
	include("connectdb.php");
	$where = "";
	$sql = "SELECT province.province_id AS province_id,province_name,SUM(population_male) AS population_male,SUM(population_female) AS population_female FROM population INNER JOIN province ON province.province_id = population.province_id GROUP BY province.province_id $where";
	$result = runSQL($sql);
	$numrow = countRec('province_id','province',$where);
	if($numrow>0){
		$json = "";
		$json .= "{";
		$json .= "\"aaData\":[";
		$rc = false;
		while ($row = mysql_fetch_array($result)) {
			if ($rc) $json .= ",";
			$json .= "[";
//-----------------------------แก้ไข-----------------------------\\
			//$json .= "\"".$row['province_name']."\"";
			$json .= "\""."<a href=javascript:openWindow('?id=".$row['province_id']."')>".$row['province_name']."</a>"."\"";
//-----------------------------แก้ไข-----------------------------\\
			$json .= ",\"".number_format($row['population_male'])."\"";
			$json .= ",\"".number_format($row['population_female'])."\"]";
			$rc = true;
		}
			$json .= "]";
			$json .= "}";
			echo $json;
	}
?>

เมื่อแก้ไขเสร็จแล้ว ลองรันดูผลลัพท์ครับ

จะเห็นว่าสามารถคลิ๊กที่ชื่อจังหวัดได้แล้ว แต่ว่าตอนนี้ยังไม่เสร็จ เรายังต้องสร้างไฟล์ display อีกไฟล์ เพื่อใช้แสดง sub table

เหมือนเดิมครับ สร้างไฟล์ datatable_show_population_aa.php เพื่อสร้าง datasource ให้กับ sub table

<?php
	header("Content-type: text/html; charset=UTF-8");
	header('Cache-Control: no-cache');
	header('Pragma: no-cache');
	header('Expires: 0');
	include("connectdb.php");
        //รับ pk ที่มาจากหน้า display
	$id = $_GET['id'];
	$where = "INNER JOIN amphoe ON amphoe.amphoe_id = population.amphoe_id AND amphoe.province_id = population.province_id WHERE population.province_id = $id";
	$sql = "SELECT amphoe.amphoe_id AS amphoe_id,amphoe_name,population_male,population_female FROM population $where";
	$result = runSQL($sql);
	$numrow = countRec('amphoe.amphoe_id','population',$where);
	if($numrow>0){
		$json = "";
		$json .= "{";
		$json .= "\"aaData\":[";
		$rc = false;
		while ($row = mysql_fetch_array($result)) {
			if ($rc) $json .= ",";
			$json .= "[";
			$json .= "\"".$row['amphoe_name']."</a>"."\"";
			$json .= ",\"".number_format($row['population_male'])."\"";
			$json .= ",\"".number_format($row['population_female'])."\"]";
			$rc = true;
		}
			$json .= "]";
			$json .= "}";
			echo $json;
	}
?>

จากนั้นสร้างไฟล์ index_aa.php เพื่อใช้แสดง sub table

<?php
        //รับค่าพารามิเตอร์ มาจาก function
	$id = $_GET['id'];
	header("Content-type: text/html; charset=UTF-8");
	header('Cache-Control: no-cache');
	header('Pragma: no-cache');
	header('Expires: 0');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<style type="text/css" title="currentStyle">
	@import "css/demo_table_jui.css";
	@import "css/TableTools_JUI.css";
</style>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" language="javascript" src="js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" href="css/redmond/jquery-ui-1.8.14.custom.css">
<style type="text/css">
.right{
  text-align: right;
}
 
.left{
  text-align: left;
}

.center{
  text-align: center;
}
</style>
<script type="text/javascript">

$(document).ready(function(){
//รับ pk จากฟอร์ม
	var params = $("#params").val();
	var initParams = {
		"oLanguage": {   
			"oPaginate": {       
				"sFirst": "หน้าแรก",
				"sLast": "หน้าสุดท้าย",
				"sNext": "ถัดไป",
				"sPrevious": "ก่อนหน้า"
			},
			"sLengthMenu": "แสดง _MENU_ รายการ ต่อหน้า",  
			"sZeroRecords": "ไม่พบข้อมูลที่ค้นหา", 
			"sInfo": "แสดง _START_ ถึง _END_ จากทั้งหมด _TOTAL_ รายการ",
			"sEmptyTable": "ไม่พบรายการข้อมูล",
			"sLoadingRecords": "ระบบกำลังประมวลผล กรุณารอซักครู่",
			"sProcessing": "ประมวลผลข้อมูล",
			"sInfoEmpty": "ไม่พบรายการข้อมูลที่แสดง",
			"sInfoFiltered": "(จากทั้งหมด _MAX_ รายการ)",  
			"sSearch": "ค้นหา :"
		},
		"aoColumns" : [  
			{ sClass: "left" },  
			{ sClass: "right" },
			{ sClass: "right" }
		],
		"bJQueryUI": true,
		"sPaginationType": "full_numbers",
		"bProcessing": true,
		"iDisplayLength": 10,
       //เลือก datatable_show_population_aa.php ให้เป็น datasource พร้อมส่งค่าพารามิเตอร์
		"sAjaxSource": 'datatable_show_population_aa.php' + params
	};
	var oTable = $('#datatable').dataTable(initParams);
});

</script>
</head>
<body>
<table cellpadding="0" cellspacing="0" border="0" class="display" id="datatable" width="100%">
	<thead>
		<tr>
			<th width="100" class="center">อำเภอ</th>
			<th width="100" class="center">ชาย</th>
			<th width="100" class="center">หญิง</th>
		</tr>
	</thead>
	<tbody>
	</tbody>
</table>
//สร้าง input ประเภท hidden เพื่อส่งค่า pk ผ่านฟอร์ม
<input type="hidden" value="<?php echo "?id=$id"; ?>" name="params" id="params" />
</body>
</html>

เมื่อเสร็จแล้วให้ลองรันไฟล์ index.php เพื่อดูผลลัพท์เลยครับ

เมื่อคลิ๊กไปที่ชื่อจังหวัดแล้ว จะมี sub table ขึ้นมา เพื่อแสดงรายละเอียดของแต่ละเขตแล้ว

จะเห็นว่า datatable นั้นสามารถที่จะประยุกต์ใช้งานได้หลากหลายแบบมากมาย
ยังไงผมก็หวังว่า บทความนี้จะเป็นประโยชน์กับหลายๆ ท่านนะครับ

ท่านสามารถดาวน์โหลด source code ได้ ที่นี่

mitsumasa