sejator/ci4-datatables
最新稳定版本:v1.0.5
Composer 安装命令:
composer require sejator/ci4-datatables
包简介
Library DataTables server-side untuk CodeIgniter 4
README 文档
README
Library helper untuk integrasi jQuery DataTables (server-side) di CodeIgniter 4, dengan fokus:
✅ Aman
✅ Mudah dipakai
✅ Siap production
Fitur Utama
- Pagination (server-side)
- Searching (global search)
- Filtering (where & conditional)
- Ordering
- Debug SQL lengkap
- Search aman (whitelist kolom)
1️⃣ Penggunaan Dasar
use Sejator\DataTables\DataTables; return DataTables::from('users') ->select('id, name, email, status') ->searchable(['name', 'email']) // 🔒 whitelist kolom search ->make();
📌 Catatan Penting
searchable()sangat direkomendasikan- Kolom di luar whitelist tidak akan ikut di-search
- Tanpa
searchable(), library akan fallback ke request DataTables (kurang aman)
2️⃣ Dengan Filter (Where & Conditional)
Filter statis
return DataTables::from('users') ->select('id, name, email, status') ->where('status', 'active') ->searchable(['name', 'email']) ->make();
Filter dinamis (opsional)
$status = $this->request->getGetPost('status'); return DataTables::from('users') ->select('*') ->when($status, fn ($q, $v) => $q->where('status', $v)) ->searchable(['name', 'email']) ->make();
✔ Jika $status kosong (null, ''), filter tidak diterapkan
3️⃣ Debug SQL Lengkap (Mode Debug)
Digunakan untuk melihat seluruh query yang dipakai DataTables:
- Query data
- Count total
- Count filtered
return DataTables::from('users') ->select('id, name, email, status') ->where('status', 'active') ->searchable(['name', 'email']) ->debug() ->make();
Output JSON Debug:
{
"debug": true,
"queries": {
"data": "SELECT id, name, email, status FROM users WHERE status = 'active' LIMIT 10 OFFSET 0",
"count_all": "SELECT COUNT(*) FROM users",
"count_filtered": "SELECT COUNT(*) FROM users WHERE status = 'active'"
}
}
📌 Kegunaan debug
- Validasi pagination
- Cek search & filter
- Audit performa query
- Troubleshooting hasil DataTables
4️⃣ Dump SQL Langsung (Development Only)
Digunakan saat development untuk dump SQL dan menghentikan eksekusi.
DataTables::from('users') ->select('*') ->where('status', 'inactive') ->ddSql();
Output:
SELECT * FROM users WHERE status = 'inactive'
⚠️ Jangan dipakai di production
5️⃣ Logging Query ke Log CI4
Query akan dicatat ke file log CI4:
📁 writable/logs/log-YYYY-MM-DD.php
DataTables::from('users') ->select('*') ->where('status', 'pending') ->logSql() ->make();
Contoh log:
DEBUG - DataTables SQL: SELECT * FROM users WHERE status = 'pending'
6️⃣ Search Aman (Whitelist Column)
📌 Wajib digunakan jika query menggunakan JOIN atau alias kolom.
Tanpa searchable(), DataTables dapat menghasilkan query tidak valid atau fitur pencarian tidak sesuai.
->searchable(['name', 'email'])
✔ Mencegah:
- SQL injection via DataTables request
- Search ke kolom yang tidak diinginkan
❌ Tanpa searchable():
- Semua kolom
searchable=truedari frontend akan dipakai - Kurang aman & sulit dikontrol
7️⃣ Ringkasan Method Penting
| Method | Fungsi |
|---|---|
from($table) |
Tentukan tabel |
select() |
Kolom yang diambil |
where() |
Filter data |
when() |
Filter kondisional |
searchable() |
Whitelist kolom search |
orderBy() |
Sorting manual |
debug() |
Tampilkan SQL lengkap |
ddSql() |
Dump SQL & stop |
logSql() |
Log SQL ke CI4 |
make() / draw() |
Eksekusi DataTables |
withRelation() |
Load relasi tanpa JOIN (lazy & nested) |
📌 make() dan draw() setara (pilih salah satu untuk konsistensi)
🔄 reset()
Digunakan untuk mengembalikan DataTables ke kondisi awal.
📌 Wajib dipakai jika instance digunakan lebih dari sekali
$dt = DataTables::from('users'); $dt->where('status', 'active')->make(); $dt->reset() ->where('status', 'inactive') ->make();
8️⃣ Relasi Data (withRelation)
Fitur withRelation() digunakan untuk memuat data relasi tanpa JOIN, sehingga:
✅ Aman untuk pagination ✅ Tidak menduplikasi row ✅ Performa lebih baik ✅ Cocok untuk server-side DataTables
Relasi akan dimuat setelah query utama dieksekusi dan disisipkan ke setiap row hasil.
8.1️⃣ Penggunaan Dasar
return DataTables::from('izin') ->select('id, tanggal_mulai, status') ->withRelation( 'izin_id', // foreign key di tabel relasi 'id', // primary key di tabel utama 'izin_histori', 'izin_id, tanggal' ) ->make();
Hasil data:
$row['izin_histori'] = [ ['izin_id' => 1, 'tanggal' => '2024-01-01'], ['izin_id' => 1, 'tanggal' => '2024-01-02'], ];
8.2️⃣ Lazy Load Relasi (Direkomendasikan)
Relasi hanya akan di-load jika benar-benar digunakan pada addColumn() atau editColumn().
return DataTables::from('izin') ->select('id, status') ->withRelation( 'izin_id', 'id', 'izin_histori', 'izin_id, tanggal', [ 'onlyIfUsedIn' => ['tanggal'] ] ) ->addColumn('tanggal', function ($row) { return implode( ', ', array_column($row->izin_histori, 'tanggal') ); }) ->make();
📌 Jika kolom tanggal tidak dipakai, query relasi tidak akan dijalankan.
8.3️⃣ Nested Relation (Relasi Bertingkat)
Mendukung relasi di dalam relasi.
return DataTables::from('izin') ->select('id, status') ->withRelation( 'izin_id', 'id', 'izin_histori', 'id, izin_id, tanggal', [ 'nested' => [ [ 'foreignKey' => 'izin_histori_id', 'localKey' => 'id', 'table' => 'izin_histori_detail', 'columns' => '*', ] ] ] ) ->make();
Akses data:
$row->izin_histori[0]['izin_histori_detail']
8.4️⃣ Kenapa withRelation Tidak Menggunakan JOIN?
❌ JOIN menyebabkan:
- Duplikasi row
- Pagination tidak akurat
- Count total & filtered salah
✅ withRelation:
- Query utama tetap bersih
- Relasi di-load sekali (no N+1)
- Aman untuk DataTables server-side
8.5️⃣ Rekomendasi Best Practice
- ✔ Gunakan withRelation() untuk data child (histori, detail, log)
- ✔ Aktifkan onlyIfUsedIn untuk performa optimal
- ✔ Gunakan JOIN hanya untuk data 1–1 yang memang ditampilkan langsung
- ✔ Hindari JOIN untuk data 1–N pada DataTables
统计信息
- 总下载量: 7
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2025-12-30