Pernahkah kamu mengunjungi sebuah website dengan tabel data yang isinya ribuan baris, lalu coba klik tombol pencarian bawaan… dan hasilnya malah loading lama atau hasilnya nggak relevan? Itulah masalah klasik yang sering dihadapi developer pemula. Padahal, dengan menerapkan filter pencarian DataTables Laravel secara kustom di sisi server, semua itu bisa diselesaikan dengan elegan.
Di artikel ke-48 dari seri 50 Artikel Belajar Laravel ini, kamu akan belajar cara membuat pencarian dan filter kustom yang benar-benar powerful — mulai dari pencarian teks sederhana, filter berdasarkan kolom spesifik, hingga kombinasi filter dinamis yang bisa kamu sesuaikan dengan kebutuhan proyekmu. Kalau kamu sudah mengikuti artikel sebelumnya tentang kolom aksi edit & hapus, tutorial ini adalah lanjutan sempurnanya!
"DataTables Server-Side Processing = query database berjalan di server, bukan di browser."
Artinya: semua logika pencarian, filter, sorting, dan paginasi dikerjakan oleh Laravel di backend. DataTables hanya mengirimkan parameter request dan menampilkan hasilnya. Efisien, cepat, dan skalabel untuk jutaan baris data sekalipun.
🔍 Memahami Cara Kerja Filter Pencarian DataTables Laravel
Bayangkan DataTables seperti seorang kasir supermarket. Saat kamu bilang "cari produk susu", si kasir tidak menelusuri seluruh rak sendiri — dia menekan tombol di komputer, dan sistem di gudang belakang yang melakukan pencariannya. Hasilnya baru dikirim ke layar kasir. Itulah persis cara kerja DataTables server-side!
Secara teknis, ketika pengguna mengetik di kolom pencarian DataTables, library ini otomatis mengirimkan AJAX request ke Laravel dengan membawa parameter seperti search[value], start, length, dan informasi sorting. Laravel kemudian memproses query database berdasarkan parameter tersebut dan mengembalikan JSON.
Pastikan kamu sudah menginstall package yajra/laravel-datatables-oracle di proyekmu sebelum mengikuti tutorial ini. Kalau belum, jalankan: composer require yajra/laravel-datatables-oracle
📊 Client-Side vs Server-Side: Pilih yang Mana?
| Aspek | Client-Side | Server-Side |
|---|---|---|
| Jumlah Data Ideal | < 1.000 baris | Jutaan baris ✅ |
| Performa | Lambat jika data banyak ⚠️ | Sangat cepat ✅ |
| Filter Kustom | Terbatas | Sangat fleksibel ✅ |
| Kompleksitas Setup | Mudah | Perlu sedikit konfigurasi |
⚙️ Implementasi Filter Pencarian DataTables Laravel Step-by-Step
Oke, sekarang kita masuk ke bagian yang paling seru! Kita akan membuat sistem filter yang bisa mencari berdasarkan nama, status, dan rentang tanggal — semuanya real-time tanpa reload halaman. Ikuti langkah-langkah berikut dengan teliti.
Buat Route dan Controller Method
Pertama, daftarkan route untuk endpoint DataTables di routes/web.php:
use App\Http\Controllers\UserController; Route::get('/users', [UserController::class, 'index'])->name('users.index'); Route::get('/users/data', [UserController::class, 'getData'])->name('users.data');
Buat Method getData() di Controller
Inilah inti dari filter pencarian DataTables Laravel. Di sini kita tangkap parameter filter dari request dan terapkan ke query Eloquent:
use Yajra\DataTables\Facades\DataTables; use App\Models\User; public function getData(Request $request) { $query = User::query(); // Filter berdasarkan status (custom) if ($request->filled('status')) { $query->where('status', $request->status); } // Filter berdasarkan rentang tanggal if ($request->filled('tgl_dari') && $request->filled('tgl_sampai')) { $query->whereBetween('created_at', [ $request->tgl_dari, $request->tgl_sampai . ' 23:59:59' ]); } return DataTables::of($query) ->addIndexColumn() ->filterColumn('name', function($query, $keyword) { $query->where('name', 'like', "%{$keyword}%") ->orWhere('email', 'like', "%{$keyword}%"); }) ->make(true); }
Method filterColumn() adalah kunci untuk mengoverride perilaku pencarian default DataTables. Gunakan ini ketika kamu ingin mencari di lebih dari satu kolom database sekaligus!
Buat Form Filter di Blade View
Buat UI filter di atas tabel DataTables. Kita pakai input HTML biasa yang nantinya nilainya dikirim lewat AJAX:
<div class="card mb-3"> <div class="card-body"> <div class="row g-3"> <div class="col-md-3"> <label>Status</label> <select id="filterStatus" class="form-control"> <option value="">Semua Status</option> <option value="active">Aktif</option> <option value="inactive">Tidak Aktif</option> </select> </div> <div class="col-md-3"> <label>Dari Tanggal</label> <input type="date" id="filterTglDari" class="form-control"> </div> <div class="col-md-3"> <label>Sampai Tanggal</label> <input type="date" id="filterTglSampai" class="form-control"> </div> <div class="col-md-3 d-flex align-items-end gap-2"> <button id="btnFilter" class="btn btn-primary">Filter</button> <button id="btnReset" class="btn btn-secondary">Reset</button> </div> </div> </div> </div>
Hubungkan Filter ke DataTables via JavaScript
Ini bagian krusial: kirimkan nilai filter sebagai parameter tambahan ke AJAX request DataTables menggunakan data callback:
let table = $('#tabelUsers').DataTable({ processing: true, serverSide: true, ajax: { url: '{{ route("users.data") }}', data: function(d) { // Tambahkan parameter filter kustom d.status = $('#filterStatus').val(); d.tgl_dari = $('#filterTglDari').val(); d.tgl_sampai = $('#filterTglSampai').val(); } }, columns: [ { data: 'DT_RowIndex', name: 'DT_RowIndex', orderable: false }, { data: 'name', name: 'name' }, { data: 'email', name: 'email' }, { data: 'status', name: 'status' }, { data: 'action', name: 'action', orderable: false } ] }); // Tombol Filter diklik → reload tabel $('#btnFilter').on('click', function() { table.ajax.reload(); }); // Tombol Reset → kosongkan filter & reload $('#btnReset').on('click', function() { $('#filterStatus').val(''); $('#filterTglDari').val(''); $('#filterTglSampai').val(''); table.ajax.reload(); });
Jangan pernah menggunakan $request->search['value'] secara manual untuk menangkap kata kunci pencarian — biarkan Yajra DataTables yang menanganinya secara otomatis. Penanganan manual bisa menyebabkan konflik dengan fitur built-in library.
🚀 Fitur Lanjutan: Filter Pencarian DataTables dengan Pencarian Per-Kolom
Kalau kamu ingin level lebih advance, kita bisa menambahkan input pencarian di bawah setiap header kolom tabel. Fitur ini sangat populer di aplikasi admin yang membutuhkan filter data granular.
Tambahkan Input di Footer Header Tabel
// Jalankan setelah DataTable ter-inisialisasi $('#tabelUsers thead tr') .clone(true) .addClass('filter-row') .appendTo('#tabelUsers thead'); $('#tabelUsers thead tr.filter-row th').each(function() { let title = $(this).text(); $(this).html(`<input type="text" placeholder="Cari ${title}" class="form-control form-control-sm">`); }); // Trigger pencarian saat input berubah table.columns().every(function() { let that = this; $('input', this.header()).on('keyup change', function() { if (that.search() !== this.value) { that.search(this.value).draw(); } }); });
Untuk aplikasi skala besar, best practice-nya adalah memindahkan logika filter ke dalam Eloquent Local Scope. Ini membuat Controller lebih bersih dan logika filter bisa di-reuse di tempat lain.
// Di Model User.php
public function scopeFilter($query, $request) {
return $query
->when($request->status, fn($q) => $q->where('status', $request->status))
->when($request->tgl_dari, fn($q) => $q->whereDate('created_at', '>=', $request->tgl_dari));
}
// Di Controller — jauh lebih bersih!
$query = User::filter($request);
Yajra DataTables sendiri mendukung pencarian dengan regular expression! Kamu bisa mengaktifkannya dengan menambahkan regex: true pada konfigurasi kolom — cocok untuk pencarian pola seperti format nomor telepon atau kode produk.
⚡ Tips Optimasi Performa Filter Pencarian DataTables Laravel
Membangun filter yang fungsional itu bagus — tapi membangunnya dengan performa optimal itu lebih bagus lagi. Berikut beberapa tips yang wajib kamu terapkan, terutama saat data sudah mencapai puluhan ribu baris:
| Teknik | Cara Implementasi | Dampak Performa |
|---|---|---|
| Database Index | Index kolom name, status, created_at |
🚀 Sangat Besar |
| Select Kolom Spesifik | Gunakan ->select(['id','name','email','status']) |
⚡ Sedang |
| Debounce di Frontend | Delay 300ms sebelum AJAX dikirim | ⚡ Sedang |
| Query Caching | Cache hasil dengan Cache::remember() |
🚀 Besar (data statis) |
Tag Artikel
🧭 Navigasi Seri Artikel
No comments:
Post a Comment