PHP Ionic Angular Phonegap AJAX Javascript CSS MySQL jQuery Forum


ใช้งาน Server side processing สำหรับ DataTable ร่วมกับ Codeigniter ตอนที่ 3

25 August 2017 By
server side processing datatable codeigniter

คำสั่ง การ กำหนด รูปแบบ ตัวอย่าง เทคนิค ลูกเล่น การประยุกต์ การใช้งาน เกี่ยวกับ server side processing datatable codeigniter



สำหรับเนื้อหาต่อไปนี้ เป็นตอนต่อเนื่องเกี่ยวกับ DataTable plugin ที่ใช้งานร่วมกับ Codeigniter
ในตอนนี้เราจะดูต่อในส่วนของการใช้ข้อมูลจาก Server-side processing ซึ่งเป็นชุดข้อมูลสุดท้าย
ที่เราได้เกริ่นไปแล้วในบทความตอนที่ผ่านมา ทบทวนได้ที่
 
Data sources สำหรับ DataTable ในการใช้งานร่วมกับ Codeigniter ตอนที่ 2 
http://www.ninenik.com/content.php?arti_id=814 via @ninenik

การใช้ข้อมูลจาก Server-side processing

    สำหรับการใช้ข้อมูลจาก Server-side processing นั้นจะคล้ายๆ กับการใช้งาน ajax แต่ไม่เหมือนกัน
เลยซะทีเดียว โดยข้อมูลจาก Server-side processing จะเหมาะกับการใช้งานกับฐานข้อมูลที่มีปริมาณมากๆ
การจัดการข้อมูลไม่ว่าจะเป็นการเรียงข้อมูล การค้นหาข้อมูล การกำหนดการแสดงข้อมูลในแต่ละหน้า ล้วนจำเป็น
ต้องมีการจัดการผ่านไฟล์ Server script ที่ต้องกำหนดให้สอดคล้องกับการแสดงผล โดยการใช้งานข้อมูลจาก
Server-side processing นั้น จะมีการส่ง Ajax request ไปดึงข้อมูลใหม่ทุกๆ ครั้งที่มีการเปลี่ยนแปลงใน DataTable
ซึ่งต่างจากกรณี Ajax data ที่ดึงข้อมูลคร้้งแรกครั้งเดียว เหตุผลก็เพราะข้อมูลที่มีขนาดใหญ่
 

รูปแบบการเรียกใช้ข้อมูลจาก Server-side processing 

    สามารถกำหนดโค้ดเรียกใช้ข้อมูลผ่าน Ajax ได้ดังนี้
 
<link rel="stylesheet" href="//cdn.datatables.net/1.10.15/css/jquery.dataTables.min.css">  
<script src="//cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>

<table id="table_server_id" class="display">
    <thead>
        <tr>
            <th>Province ID</th>
            <th>Province Name TH</th>
            <th>Province Name ENG</th>
        </tr>
    </thead>
</table>
  
<script type="text/javascript">
$(function(){
    $('#table_server_id').DataTable( {
		"processing": true, // แสดงข้อความกำลังดำเนินการ กรณีข้อมูลมีมากๆ จะสังเกตเห็นง่าย
		"serverSide": true,  // ใช้งานในโหมด Server-side processing
		"order": [], // กำหนดให้ไม่ต้องการส่งการเรียงข้อมูลค่าเริ่มต้น จะใช้ค่าเริ่มต้นตามค่าที่กำหนดในไฟล์ php
		"ajax": {
			"url": "<?=base_url("ajaxdata")?>", // ไฟล์ Server script php
			"type": "POST"  // ส่งข้อมูลแบบ post
		},
    } );
});
</script>
 
การใช้งานจะคล้ายๆ กับการใช้ข้อมูลจาก Ajax data แต่จะเพิ่มในส่วนของการกำหนด option เพิ่มเติมเข้ามาได้แก่
processing , serverSide , order โดยค่าเริ่มต้นเมื่อโหลดครั้งแรก เรากำหนดเป็น array ค่าว่าง
และส่วนสุดท้ายคือ ajax option ที่กำหนด url และ type property 
ตอนนี้ส่วนของการเรียกใช้งานเราพร้อมแล้ว ต่อไปก็ส่วนสำคัญ คือส่วนของไฟล์ Server Script สร้างไฟล์คล้ายๆ
กับรูปแบบ Ajax data ดังนี้
 
ให้สร้างไฟล์ Ajaxdata.php ไว้ในโฟลเดอร์ apps > controllers 
กำหนดโค้ดตามรูปแบบด้านล่าง ดังนี้
 
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
 
class Ajaxdata extends CI_Controller {
   	private $table = "tbl_provinces"; // กำหนดชื่อตารางข้อมูล
	// กำหนดฟิลด์ข้อมูลที่สามารถให้ค้นหาข้อมูลได้
	private $column_search = array(
		"province_id","province_name","province_name_eng"
	);
	// กำหนดฟิลด์ข้อมูลที่สามารถให้เรียงข้อมูลได้
	private $column_order = array(
		"province_id","province_name","province_name_eng"
	);	
	// กำหนดฟิลด์ข้อมูลที่่ต้องการเรียงข้อมูลเริ่มต้น และรูปแบบการเรียงข้อมูล
	private $order = array("province_id"=>"asc");
    public function __construct(){
        parent::__construct();
    }
    public function index(){
		
        $data = array();
		$_draw = $this->input->post('draw'); // ครั้งที่การดึงข้อมูล ค่าของ dataTable ส่งมาอัตโนมัติ
		$_p = $this->input->post('search'); // ตัวแปรคำค้นหาถ้ามี
		$_earchValue = $_p['value']; // ค่าคำค้นหา
		$_order = $this->input->post('order'); // ตัวแปรคอลัมน์ที่ต้องการเรียงข้อมูล
		$_length = $this->input->post('length'); // ตัวแปรจำนวนรายการที่จะแสดงแต่ละหน้า
		$_start = $this->input->post('start'); // เริ่มต้นที่รายการ
        $query = $this->db->from($this->table);  // ดึงข้อมูลจากตารางที่กำหนด
		$total_rows_all = $this->db->count_all_results(null,FALSE); // เก็บค่าจำนวนรายการทั้งหมด		
        $i = 0;    
		// วนลูปฟิลด์ที่ต้องการค้นหา กรณีมีการส่งคำค้น เข้ามา
        foreach ($this->column_search as $item){
			if($_earchValue){ // ถ้ามีค่าคำค้น
				// จัดรูปแแบคำสั่ง sql การใช้งาน OR กับ LIKE
				if($i===0){ // ถ้าเป็นค่าเริ่มเต้นให้เปิดวงเล็บ (
                    $this->db->group_start(); 
                    $this->db->like($item, $_earchValue);					
				}else{
					$this->db->or_like($item, $_earchValue);
				}
				if(count($this->column_search) - 1 == $i){ // ถ้าเป็นต้วสุดท้ายให้ปิดวงเล็บ )
					$this->db->group_end();
				}
			}
			$i++;
			// ส่วนของการวนลูปนี้จะได้รูปแบบ เช่น ( fileld1 LIKE 'a' OR field2 LIKE 'a' )  เป็นต้น
		}  
		// ถ้ามีการส่งฟิลด์ที่ต้องการเรียงข้อมูลเข้ามา เช่น กรณีกดที่หัวข้อในตาราง dataTable
		if(isset($_order) && $_order!=NULL){
			// จัดรูปแบบการจัดเรียงข้อมูลจากค่าที่ส่งมา
			$_orderColumn = $_order['0']['column'];
			$_orderSort = $_order['0']['dir'];
			$this->db->order_by($this->column_order[$_orderColumn], $_orderSort);
		}else{ // กรณีไม่ได้ส่งค่าในตอนต้น ให้ใช้ค่าตามที่กำหนด
			// จัดรูปแบบการจัดเรียง  ตามที่กำหนดด้ายตัวแปร $order ด้านบน
            $order = $this->order;
            $this->db->order_by(key($order), $order[key($order)]);			
		}
		$total_rows_filter = $this->db->count_all_results(null,FALSE); // กำหนดค่าจำนวนข้อมูลหลังมีเงื่อนไขต่างๆ			
        if($_length != -1){ // กรณีมีการกำหนดว่าต้องการแสดงข้อมูลหน้าละกี่รายการ
        	$this->db->limit($_length, $_start); // จัดรูปแบบการแสดง ผลที่ได้เช่น LIMIT 10,10
		}	
        $query = $this->db->get(); // คิวรี่ข้อมูลตาเงื่อนไข
		// วนลูปนำฟิลด์รายการที่ต้องการและสอดคล้องกันมาไว้ในตัวแปร array ที่ชื่อ $data
        foreach ($query->result_array() as $row){
            $data[] = array(
                $row['province_id'],
                $row['province_name'],
                $row['province_name_eng']
            );
        }
		// กำหนดรูปแบบ array ของข้อมูลที่ต้องการสร้าง JSON data ตามรูปแบบที่ DataTable กำหนด
        $output = array(
			"draw" => $_draw, // ครั้งที่เข้ามาดึงข้อมูล
			"recordsTotal" => $total_rows_all, // ข้อมูลทั้งหมดที่มี
			"recordsFiltered" => $total_rows_filter, // ข้อมูลเฉพาะที่เข้าเงื่อนไข เช่น ค้นหา แล้ว		
             "data" => $data // รายการ array ข้อมูลที่จะใช้งาน
        );
        echo json_encode($output);
        exit();			
    }
}
 
 
หลักๆ ส่วนที่ต้องแก้ไข ก็จะเป็นส่วนของบรรทัดที่ hilight ไว้ แต่ถ้าหากเข้าใจการทำงานโดยรวมก็สามารถ
ปรับแต่งๆได้ตามต้องการ สามารถเปลี่ยนชื่อไฟล์หรือชื่อ class เป็นชื่ออื่นๆ ได้ กรณีเรียกใช้ dataTable กับ
หลายๆ ตาราง
    ค่าตัวแปรที่ถูกส่งเข้ามาที่เป็นตัวแปร $_POST เป็นค่าที่ dataTable กำหนดและส่งค่าเข้ามา คำอธิบายการ
ทำงานแสดงในโค้ด
 
ลองทดสอบเรียกใช้งาน จะได้ผลลัพธ์ดังรูป
 
 



 
 
 
ต่อไปเรามาลองปรับโค้ดอีกนิดหน่อย ให้รองรับการทำงานที่เพิ่มขึ้น สมมติว่าเราต้องการแทรกคอลัมน์ลำดับ
รายการของข้อมูลในตาราง ไม่ว่าข้อมูลนั้นๆ จะเรียงข้อมูลยังไง ลำดับข้อมูลก็จะเรียงลำดับเหมือนเดิม เราจะลอง
ประยุกต์เพิ่มเติมจากตัวอย่างด้านบน โดยเราจะเพิ่มคอลัมน์ลำดับรายการจังหวัดเข้าไป และจะมีการส่งข้อมูลที่กำหนด
เองเข้าไปใน ajax ด้วย โดยเราจะส่งหน้าของข้อมูลในขณะนั้น เข้าไปเพื่อไปสร้างเลขลำดับข้อมูล
 
ไฟล์เรียกใช้ปรับแต่งเพิ่มเติม ดูบรรทัดที่ hilight
 
<link rel="stylesheet" href="//cdn.datatables.net/1.10.15/css/jquery.dataTables.min.css">  
<script src="//cdn.datatables.net/1.10.15/js/jquery.dataTables.min.js"></script>

<table id="table_server_id" class="display">
    <thead>
        <tr>
        	<th>#</th>
            <th>Province ID</th>
            <th>Province Name TH</th>
            <th>Province Name ENG</th>
        </tr>
    </thead>
</table>
  
<script type="text/javascript">
$(function(){
     $('#table_server_id').DataTable( {
		"processing": true, // แสดงข้อความกำลังดำเนินการ กรณีข้อมูลมีมากๆ จะสังเกตเห็นง่าย
		"serverSide": true,  // ใช้งานในโหมด Server-side processing
		"order": [], // กำหนดให้ไม่ต้องการส่งการเรียงข้อมูลค่าเริ่มต้น จะใช้ค่าเริ่มต้นตามค่าที่กำหนดในไฟล์ php
		"ajax": {
			"url": "<?=base_url("ajaxdata")?>", // ไฟล์ Server script php
			"data":{   // เพิ่มตัวแปรที่ต้องกาส่งเข้าไปแบบกำหนดเอง
				"page":function(){ // ใข้ข้อมูลตัวแปรชื่อ page
					var dataTable1 = $('#table_server_id').DataTable(); // จะใช้ข้อมูลอ้างอิงจาก dataTable
					return dataTable1.page.info().page;	// ส่งค่าเลขหน้าปัจจุบันไปไว้ในตัวแปร page ค่าเรี่มต้นนับจาก 0
				}
			},
			"type": "POST"  // ส่งข้อมูลแบบ post
		},
		"columnDefs": [  // กำหนดลักษณะพิเสษเฉพาะสำหรับคอลัมน์ตารางที่ต้องการ
			{ 
				"targets": [ 0 ], // เราต้องการกำหนดคอลัมน์แรก ค่าเริ่มต้นที่ 0
				"orderable": false, // ให้ไม่ต้องสามารถเรียงข้อมูลได้ เพราะเป็นลำดับรายการเฉยๆ 
			}
		]
    } );
});
</script>
 
 
จากโค้ดจะเห็นว่าเราเพิ่มคอลัมน์สำหรับแสดงลำดับรายการของข้อมูลในตารางไว้ก่อนคอลัมน์ Province ID
และส่วนของการส่งค่า ajax เราได้เพิ่มข้อมูลที่ต้องการส่งค่าเข้าไปแบบกำหนดเอง โดยเราส่งตัวแปรชื่อ page
เป็นค่าหน้าปัจจุบันของตารางข้อมูล โดยค่าจะเริ่มนับที่เลข 0 ชุดถ้าเรากดเลขหน้า 2 ค่าที่ถูกส่งไปก็จะเป็น 1
ส่วนต่อมาก็เป็นการกำหนดลักษณะเฉพาะของคอลัมน์ในตาราง ในที่นี้เราต้องการให้คอลัมน์แรกเป็นเลขลำดับ
เฉยๆ ไม่ต้องการให้สามารถคลิกเพื่อเรียงข้อมูลได้
 
ต่อไปเราไปดูในส่วนของการปรับที่ไฟล์ Ajaxdata.php ในโฟลเดอร์ apps > controllers
ดูในส่วนที่ทำการ hilight
 
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
 
class Ajaxdata extends CI_Controller {
   	private $table = "tbl_provinces"; // กำหนดชื่อตารางข้อมูล
	// กำหนดฟิลด์ข้อมูลที่สามารถให้ค้นหาข้อมูลได้
	private $column_search = array(
		"province_id","province_name","province_name_eng"
	);
	// กำหนดฟิลด์ข้อมูลที่สามารถให้เรียงข้อมูลได้
	private $column_order = array(
		NULL,"province_id","province_name","province_name_eng"
	);	
	// กำหนดฟิลด์ข้อมูลที่่ต้องการเรียงข้อมูลเริ่มต้น และรูปแบบการเรียงข้อมูล
	private $order = array("province_id"=>"asc");
    public function __construct(){
        parent::__construct();
    }
    public function index(){
		
        $data = array();
		$_draw = $this->input->post('draw'); // ครั้งที่การดึงข้อมูล ค่าของ dataTable ส่งมาอัตโนมัติ
		$_p = $this->input->post('search'); // ตัวแปรคำค้นหาถ้ามี
		$_earchValue = $_p['value']; // ค่าคำค้นหา
		$_order = $this->input->post('order'); // ตัวแปรคอลัมน์ที่ต้องการเรียงข้อมูล
		$_length = $this->input->post('length'); // ตัวแปรจำนวนรายการที่จะแสดงแต่ละหน้า
		$_start = $this->input->post('start'); // เริ่มต้นที่รายการ
        $query = $this->db->from($this->table);  // ดึงข้อมูลจากตารางที่กำหนด
		$total_rows_all = $this->db->count_all_results(null,FALSE); // เก็บค่าจำนวนรายการทั้งหมด		
        $i = 0;    
		// วนลูปฟิลด์ที่ต้องการค้นหา กรณีมีการส่งคำค้น เข้ามา
        foreach ($this->column_search as $item){
			if($_earchValue){ // ถ้ามีค่าคำค้น
				// จัดรูปแแบคำสั่ง sql การใช้งาน OR กับ LIKE
				if($i===0){ // ถ้าเป็นค่าเริ่มเต้นให้เปิดวงเล็บ (
                    $this->db->group_start(); 
                    $this->db->like($item, $_earchValue);					
				}else{
					$this->db->or_like($item, $_earchValue);
				}
				if(count($this->column_search) - 1 == $i){ // ถ้าเป็นต้วสุดท้ายให้ปิดวงเล็บ )
					$this->db->group_end();
				}
			}
			$i++;
			// ส่วนของการวนลูปนี้จะได้รูปแบบ เช่น ( fileld1 LIKE 'a' OR field2 LIKE 'a' )  เป็นต้น
		}  
		// ถ้ามีการส่งฟิลด์ที่ต้องการเรียงข้อมูลเข้ามา เช่น กรณีกดที่หัวข้อในตาราง dataTable
		if(isset($_order) && $_order!=NULL){
			// จัดรูปแบบการจัดเรียงข้อมูลจากค่าที่ส่งมา
			$_orderColumn = $_order['0']['column'];
			$_orderSort = $_order['0']['dir'];
			$this->db->order_by($this->column_order[$_orderColumn], $_orderSort);
		}else{ // กรณีไม่ได้ส่งค่าในตอนต้น ให้ใช้ค่าตามที่กำหนด
			// จัดรูปแบบการจัดเรียง  ตามที่กำหนดด้ายตัวแปร $order ด้านบน
            $order = $this->order;
            $this->db->order_by(key($order), $order[key($order)]);			
		}
		$total_rows_filter = $this->db->count_all_results(null,FALSE); // กำหนดค่าจำนวนข้อมูลหลังมีเงื่อนไขต่างๆ			
        if($_length != -1){ // กรณีมีการกำหนดว่าต้องการแสดงข้อมูลหน้าละกี่รายการ
        	$this->db->limit($_length, $_start); // จัดรูปแบบการแสดง ผลที่ได้เช่น LIMIT 10,10
		}	
        $query = $this->db->get(); // คิวรี่ข้อมูลตาเงื่อนไข
		$_page = $this->input->post('page'); // ค่าตัวแปร page ที่เรากำหนดเองส่งหน้าปัจจุบันเข้ามา
		// วนลูปนำฟิลด์รายการที่ต้องการและสอดคล้องกันมาไว้ในตัวแปร array ที่ชื่อ $data
		$_i = 0; // ตัวแปรเลขลำดับข้อมูล
        foreach ($query->result_array() as $row){
			$_i++;
            $data[] = array(
				($_page*$_length)+$_i,
                $row['province_id'],
                $row['province_name'],
                $row['province_name_eng']
            );
        }
		// กำหนดรูปแบบ array ของข้อมูลที่ต้องการสร้าง JSON data ตามรูปแบบที่ DataTable กำหนด
        $output = array(
			"draw" => $_draw, // ครั้งที่เข้ามาดึงข้อมูล
			"recordsTotal" => $total_rows_all, // ข้อมูลทั้งหมดที่มี
			"recordsFiltered" => $total_rows_filter, // ข้อมูลเฉพาะที่เข้าเงื่อนไข เช่น ค้นหา แล้ว		
             "data" => $data // รายการ array ข้อมูลที่จะใช้งาน
        );
        echo json_encode($output);
        exit();			
    }
}
 
 
สังเกตส่วนของบรรทัดการกำหนด $column_order ค่าส่วนนี้เราต้องกำหนดลำดับให้สัมพันธ์กับคอลัมน์
ที่แสดงในตาราง DataTable จะเห็นว่าเราเพิ่ม NULL เข้าไปในค่า array ตัวแรก เพื่อเป็นการอ้างอิงคอลัมน์แรก
ของตาราง ที่เราใช้เป็นคอลัมน์แสดงลำดับรายการ ไม่ต้องการให้ทำการเรียงข้อมูลได้ จึงกำหนดค่าเป็น NULL
 
	// กำหนดฟิลด์ข้อมูลที่สามารถให้เรียงข้อมูลได้
	private $column_order = array(
		NULL,"province_id","province_name","province_name_eng"
	);
 
ต่อมาก็ดูในส่วนของการสร้างชุดข้อมูล
 
		$_page = $this->input->post('page'); // ค่าตัวแปร page ที่เรากำหนดเองส่งหน้าปัจจุบันเข้ามา
		// วนลูปนำฟิลด์รายการที่ต้องการและสอดคล้องกันมาไว้ในตัวแปร array ที่ชื่อ $data
		$_i = 0; // ตัวแปรเลขลำดับข้อมูล
        foreach ($query->result_array() as $row){
			$_i++;
            $data[] = array(
				($_page*$_length)+$_i,
                $row['province_id'],
                $row['province_name'],
                $row['province_name_eng']
            );
        }
 
เราเพิ่มชุดข้อมูลเลขลำดับเข้าไปใน $data[] ในค่า array ตัวแรก โดยการสร้างเลขลำดับหน้าจะใช้
ตัวแปรหน้า page ที่ถูกส่งเข้ามา มาช่วยในการคำนวณ ตัวอย่างเช่น ถ้าเป็นหน้าแรก และข้อมูลแสดงครั้งละ 10
ค่าการคำนวณก็จะเป็น (0*10)+1 หน้าแรกก็จะเป็นลำดับที่ 1,2,3.....ไปเรื่อยๆ พอเป็นหน้าที่สอง 
ค่าการคำนวณก็จะเป็น (1*10)+1 หน้าสองก็จะเป็นลำดับ 11,12,13....  ในลักษณะนี้ไปเรื่อยๆ
 
มาดูผลลัพธ์ที่ได้จะได้เป็นดังนี้
 
 

 
 
ลองสมมติเราทำการค้นหา โดยพิมพ์เลข 2 เข้าไป ข้อมูลก็จะไปค้นหาในฟิลด์ province_id, province_name และ
province_name_eng ซึ่งแน่นอนว่าข้อมูลที่จะแสดงก็จะเป็นรายการที่มี province_id ที่มีเลข 2 จากนั้นเรากดไป
ที่หน้าที่สอง ผลลัพธ์จะได้ดังรูป



 
 
รายการที่ตรงมีทั้งหมด 17 รายการ เมื่อเรากดไปหน้าที่ 2 ลำดับรายการก็จะเริ่มที่ลำดับที่ 11,12.... ไปจนถึง 17
โดยลำดับรายการไม่สลับไปตามข้อมูลที่มีการจัดเรียงใหม่ตามเงื่อนไขการค้นหา
 
ตอนนี้เราได้ความรู้เพิ่มเติมเกี่ยวกับการใช้งานข้อมูลจาก Server-side processing บ้างแล้ว เนื้อหาต่อไป จะเป็น
การประยุกต์เกี่ยวกับอะไร รอติดตาม

 




อ่านต่อที่บทความ









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



Tags:: codeigniter datatable server side processing




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

กรุณาล็อกอิน เพื่ออ่านเนื้อหาบทความ

ยังไม่เป็นสมาชิก

สมาชิกล็อกอิน



หริอ สมัครสมาชิก และล็อกอิน ด้วย Facebook



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


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