วิธีใช้งาน Datatable.js แบบ Join ข้อมูลหลาย Table และหลาย เงื่อนไข

วิธีใช้งาน-datatables-js
วิธีใช้งาน-datatables-js

วิธีใช้งาน Datatable.js โดยการ Query ข้อมูลขึ้นมาแสดงในรูปแบบของตารางข้อมูล มีเรื่องน่าปวดหัวที่เรามักจะเจอคือ ข้อมูลที่ดึงขึ้นมาแสดงนั้น ไม่ได้ถูกออกแบบให้อยู่ในตารางข้อมูลเดียวกัน แต่มักจะถูกเก็บไว้ในหลายตารางข้อมูล

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

วิธีใช้ datatables join ข้อมูล 2 ตาราง

ในตัวอย่างเราจะสร้างตารางข้อมูลขึ้นมา 2 ตาราง คือ bill และ expense ทั้ง 2 ตารางมี primary key ที่เชื่อมโยงกันอยู่ และต้องการให้ข้อมูลจากทั้ง 2 ตารางมาแสดงผลใน datatables ตารางละ 1 column

ส่วนของ javascript จะเขียนคำสั่งเบื้องต้นได้ดังนี้ ( main.js )


$('.reportTable').DataTable({
    "columns": [
        {"width": "10%" },
        {"width": "10%" },
    ],
    "ajax": {
        "url": "bill.php",
        "type": "POST",
        "data": function (post) {

        }
    },
    "serverSide": true,
});

และส่วนของ server side ( bill.php ) จะเขียนคำสั่งในการ join ข้อมูลและ return ค่ากลับไปแสดงผลได้ดังนี้

    require APPPATH . 'libraries/ssp.customized.class.php';
    $table = 'bill';
    $primaryKey = 'uid';
    $joinQuery = "";
    $extraWhere = "";
    $groupBy = "";
    $having = "";
  
    $table_arr = array(
        array(
            'db' => 'bill.bill_datetime',  'dt' => 0, 'field' => 'bill_datetime',
            'formatter' => function ($bill_datetime, $row) {
                return $bill_datetime;
            }
        ),
        array(
            'db' => 'expense.expense_id',     'dt' => 1, 'field' => 'expense_id',
            'formatter' => function ($expense_id, $row) {
                return $expense_id;
            }
        ),
        
    );
   
    // เขียนคำสั่ง join ข้อมูล 2 ตาราง คือ bill และ exepense ไว้ที่ query หลัก
    $joinQuery = "FROM bill AS bill JOIN expense AS expense ON (expense.expense_uid = bill_history.expense_uid)";

    echo json_encode(
        SSP::simple($this->input->post(), $sql_details, $table, $primaryKey, $table_arr, $joinQuery, $extraWhere, $groupBy, $having)
    );

การ Filter ( กรองข้อมูล ) โดยใช้ extraWhere

กรณีที่เราต้องการกรองข้อมูลที่จะแสดงผลในตาราง เช่น การกำหนดวันเริ่มต้น วันสิ้นสุดของข้อมูล หรือการกำหนดประเภทของข้อมูล เราสามารถใช้ extraWhere เข้ามาช่วยได้

เริ่มต้นเลยในส่วนของ javascript ไฟล์ main.js ให้เพิ่มตัวแปร ajax post เข้าไปด้วย ตัวอย่างจะเขียนคำสั่งเพิ่มเข้าไปในโค๊ดต้นแบบได้ดังนี้

"ajax": {
        "url": report_billsConfig.report_bills_url,
        "type": "POST",
        "data": function (post) {
            post.expense_type = 1;
            post.startDate = '2020-01-01';
            post.stopDate = '2021-01-01';
            post.length = 25;
        }
    },

ในฝั่ง server side ( bill.php ) เราจะเขียนรับตัวแปรและเพิ่ม extraWhere เข้าไป เพื่อทำการกรองข้อมูลประเภทของ expense และ วันเริ่มต้น สิ้นสุดของ bill ได้ดังนี้

$expensed_type = $_POST['expensed_type'];
    $startDate = $_POST['startDate'];
    $endDate = $_POST['endDate'];

    // แสดงผลข้อมูลแบบกำหนดวันเริ่มต้น และสิ้นสุดของข้อมูลตาราง bill
    $extraWhere .= 'DATE(bill.bill_datetime) >= "' . $startDate . '" AND DATE(bill.bill_datetime) <= "' . $endDate . '"';
    // แสดงผลข้อมูลแบบกำหนดประเภทของข้อมูลตาราง expense
    $extraWhere .= " AND expense.expensed_type = " . $expensed_type;
    
    $joinQuery = "FROM  bill AS bill JOIN expense AS expense ON (expense.expense_uid = bill.expense_uid)";

    echo json_encode(
        SSP::simple($this->input->post(), $sql_details, $table, $primaryKey, $table_arr, $joinQuery, $extraWhere, $groupBy, $having)
    );

จากตัวอย่างโค๊ดการใช้งาน datatables ด้านบน เราสามารถเพิ่มการ join มากกว่า 1 ตาราง ด้วยการเขียนเพิ่มที่ส่วนของ joinQuery และ ถ้าต้องการเพิ่มการ filter ( กรองข้อมูล ) หลายเงื่อนไข ก็สามารถเพิ่มได้ในส่วนของ extraWhere

สำหรับการใช้งาน datatables ในการรับโหลดข้อมูลจำนวนมาก สามารถอ่านวิธีการใช้งานได้ที่ Datatables.js ใช้ Ajax โหลดข้อมูลทีละหน้าเกิน 10,000 Row

Leave a Reply