สำหรับเนื้อหาต่อไปนี้ เป็นตอนต่อเนื่องเกี่ยวกับ DataTable plugin ที่ใช้งานร่วมกับ Codeigniter
ในตอนนี้เราจะดูต่อในส่วนของการใช้ข้อมูลจาก Server-side processing ซึ่งเป็นชุดข้อมูลสุดท้าย
ที่เราได้เกริ่นไปแล้วในบทความตอนที่ผ่านมา ทบทวนได้ที่
Data sources สำหรับ DataTable ในการใช้งานร่วมกับ Codeigniter ตอนที่ 2
https://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 ได้ดังนี้
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <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
กำหนดโค้ดตามรูปแบบด้านล่าง ดังนี้
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | <?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 (); } } |
หลักๆ ส่วนที่ต้องแก้ไข ก็จะเป็นส่วนของบรรทัดที่ highlight ไว้ แต่ถ้าหากเข้าใจการทำงานโดยรวมก็สามารถ
ปรับแต่งๆได้ตามต้องการ สามารถเปลี่ยนชื่อไฟล์หรือชื่อ class เป็นชื่ออื่นๆ ได้ กรณีเรียกใช้ dataTable กับ
หลายๆ ตาราง
ค่าตัวแปรที่ถูกส่งเข้ามาที่เป็นตัวแปร $_POST เป็นค่าที่ dataTable กำหนดและส่งค่าเข้ามา คำอธิบายการ
ทำงานแสดงในโค้ด
ลองทดสอบเรียกใช้งาน จะได้ผลลัพธ์ดังรูป

ต่อไปเรามาลองปรับโค้ดอีกนิดหน่อย ให้รองรับการทำงานที่เพิ่มขึ้น สมมติว่าเราต้องการแทรกคอลัมน์ลำดับ
รายการของข้อมูลในตาราง ไม่ว่าข้อมูลนั้นๆ จะเรียงข้อมูลยังไง ลำดับข้อมูลก็จะเรียงลำดับเหมือนเดิม เราจะลอง
ประยุกต์เพิ่มเติมจากตัวอย่างด้านบน โดยเราจะเพิ่มคอลัมน์ลำดับรายการจังหวัดเข้าไป และจะมีการส่งข้อมูลที่กำหนด
เองเข้าไปใน ajax ด้วย โดยเราจะส่งหน้าของข้อมูลในขณะนั้น เข้าไปเพื่อไปสร้างเลขลำดับข้อมูล
ไฟล์เรียกใช้ปรับแต่งเพิ่มเติม ดูบรรทัดที่ highlight
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <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
ดูในส่วนที่ทำการ highlight
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | <?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
1 2 3 4 | // กำหนดฟิลด์ข้อมูลที่สามารถให้เรียงข้อมูลได้ private $column_order = array ( NULL, "province_id" , "province_name" , "province_name_eng" ); |
ต่อมาก็ดูในส่วนของการสร้างชุดข้อมูล
1 2 3 4 5 6 7 8 9 10 11 12 | $_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 บ้างแล้ว เนื้อหาต่อไป จะเป็น
การประยุกต์เกี่ยวกับอะไร รอติดตาม