Custom Server-Side Datatables With CodeIgniter

Untuk Datatable yang kita gunakan kali ini menggunakan Datatables Server Side dengan database MySQL.

Alasan menggunakan server-side processing adalah ketika menggunakan banyak sekali data (di atas 1000 baris) user tidak perlu menunggu semua data (baris) di proses di server dan ditampilkan ke view, dan mengakibatkan website kita terasa lambat.

Tutorial kali ini kita membahas tentang penggunaan server-side datatable dengan custom parameter.

Requirement

  • CodeIgniter 3.x
  • Bootstrap
  • JQuery
  • Datatables

Creating TableĀ  and Datatable Function View

buat tabel di file views

<table class="table table-bordered table-hover" id="tabeldata">
        <thead class="thead-inverse">
         <tr>
          <th style="width: 50px">NO</th>
          <th>NAMA</th>
          <th>KOTA</th>
          <th>EMAIL</th>
          <th>TELP</th>
          <th>#</th>
         </tr>
        </thead>
        <tbody></tbody>
</table>

tabel kita beri atribut id=”tabeldata” yang nantinya digunakan sebagai selector pada js untuk menampilkan data dari database menggunakan AJAX JQuery.

Next, kita akan menggunaan fungsi untuk generate data dari database dengan AJAX JQuery

$('#tabeldata').DataTable({
      "destroy": "true",
      "processing": true,
      "serverSide": true,
      "order": [],
      "ordering": false,
      "responsive": true,
      "lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "Semua"]],
      "language": {
       "infoFiltered": "",
       "processing": "<tr><td colspan='6' class='text-center'><i class='fa fa-spin fa-refresh'></i> Loading Data...</td></tr>"
      },
      "ajax": {
       "url": "<?= site_url() . "data/getdata" ?>",
       "type": "POST",
       "dataType": "json",
       tryCount: 0,
       retryLimit: 3,
       'data': function (data) {
        data.filter_kota = $("#filter-data").find("[name=val_filter_kota]").val();
       },
       "dataFilter": function (response) {
        return response;
       },
      },
     });

sebelumnya kita mendefinisikan data sebagai fungsi di sini:

'data': function (data) {
   data.filter_kota = $("#filter-data").find("[name=val_filter_kota]").val();
},

karena kita menambahkan custom parameter sebagai value untuk filter data dari database, maka kita perlu menambahkan <form> di atas tabel sebagai filter tambahan data.

<div class="row">
 <div class="col-lg-6">
   <form id="filter-data">
    <label class="label label-info small"><i class="fa fa-filter"></i> Filter Kota</label><br>
     <select class="form-control select-filter-kota">
      <option value="*"> Semua Kota</option>
      <option value="Malang"> Malang</option>
      <option value="Surabaya"> Surabaya</option>
      <option value="Jakarta"> Jakarta</option>
     </select>
     <input type="hidden" name="val_filter_kota">
   </form>
 </div>
</div>

untuk sementara ini, file view sudah selesai dan kita akan lanjutkan ke bagian Controller

Creating Controller

Buat file controller sesuai dengan request dari AJAX Datatables, Data.php dan fungsi getdata()

<?php

defined('BASEPATH') OR exit('No direct script access allowed');

class Data extends CI_Controller {

 public function __construct() {
  parent::__construct();
  $this->load->model('m_data');
 }

function listData() {
  $list = $this->m_data->get_datatables();
  $data = array();
  $no   = $_POST['start'];
  $nos  = $no + 1;
  foreach ($list as $key => $val) {
   $id    = $val->id;
   $row   = [];
   $row[] = "<td>". $val->nama ."</td>";
   $row[] = "<td>". $val->kota ."</td>";
   $row[] = "<td>". $val->email ."</td>";
   $row[] = "<td>". $val->telp ."</td>";
   $row[] = "<td><a href='". site_url() ."detail/". $id ."'><i class='fa fa-search'></i> Detail</a></td>";
   );
   $data[] = $row;
  }
  $output = array(
    "draw"            => $_POST['draw'],
    "recordsTotal"    => $this->m_data->count_all_(),
    "recordsFiltered" => $this->m_data->count_filtered_(),
    "data"            => $data,
  );
  //output dalam format JSON
  echo json_encode($output);
 }

}

Pada file controllers/Data.php kita menginisiasi Model M_Data.php dan return value yang kita dapat diiterasi menggunakan foreach dan ditampung ke dalam variabel $data sebagai array(). Sedangkan untuk variabel $row sendiri merupakan array dari baris data yang akan kita lempar ke tabel di view sebelumnya.

Creating Models

Buat model dengan nama M_Data.php sesuai dengan nama yang kita inisiasi di controllers/Data.php tadi

<?php

class M_data extends CI_Model {

 public function __construct() {
  parent::__construct();
 }

 function get_datatables() {
  $this->select = "*";
  $sql          = $this->manualQuery($this->input->post(), true, true);
  $query        = $this->db->query($sql);
  return $query->result();
 }

 function manualQuery($params, $page = false, $filter = false) {
  $this->column_search = ['nama','email','telp'];
  $sql  = "SELECT * FROM `tabel_data` ";
  $filt = "";
  if ($filter) {
   if (!empty($params['param'])) {
    $flt  = "params = '" . $params['params'] . "' ";
    $filt .= (empty($filt) ? " " . $flt : " AND " . $flt);
   }

   if (!empty($params['search']['value'])) {
    $flt = " ";
    $flt .= " (";
    $e   = end($searchArr);
    foreach ($searchArr as $val) {
     $flt .= $val . " LIKE '%" . $params['search']['value'] . "%'";
     if ($val != $e) {
      $flt .= " OR ";
     }
    }
    $flt  .= ")";
    $filt .= (empty($filt) ? " " . $flt : " AND " . $flt);
   }

   $customFilter = "kota";
   if (!empty($params['filter_kota']) && $params['filter_kota'] !== "*") {
    $flt  = $customFilter . " = '" . $params['filter_kota'] . "' ";
    $filt .= (empty($filt) ? " " . $flt : " AND " . $flt);
   } 

   $filt = (empty($filt) ? "" : " WHERE " . $filt);
   $sql  .= $filt . " ";
  }
  if ($page && $params['length'] != "-1") {
   $sql .= " LIMIT " . $params['length'] . " OFFSET " . $params['start'];
  }

  return $sql;
 }

 function count_filtered_() {
  $sql = $this->manualQuery($this->input->post(), false, true);
  return count($this->db->query($sql)->result());
  // return $sql;
 }

 public function count_all_() {
  $this->select = " COUNT(0) as total ";
  $sql          = $this->manualQuery($this->input->post(), false, false);
  return count($this->db->query($sql)->result());
 }

}

All done.

Parameters?