Join, Search, Filter Laravel 9 – Tutorial Join, Search, Filter pada Laravel 9 dengan Bootstrap 5 dan database MySQL. Kasus kali ini menggunakan Nortwind Database.
1. Membuat Project Laravel
Pastikan Anda sudah menginstall composer, kemudian jalankan perintah berikut di command prompt.
composer create-project laravel/laravel laravel-filter
2. Mengatur Database MySQL
Langkah kedua adalah membuat database dengan nama laravel_filter
di http://localhost/phpmyadmin
jika Anda menginstall XAMPP untuk server MySQL.
Sesuaikan pengaturan koneksi mysql di project laravel pada file .env
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=laravel_filter DB_USERNAME=root DB_PASSWORD=
Sesuaikan DB_HOST
, DB_PORT
, DB_DATABASE
, DB_USERNAME
, dan DB_PASSWORD
sesuai server MySQL.
3. Import Database
Pada tutorial ini sudah menyediakan data dalam bentuk sql, silakan Anda impor ke phpmyadmin. Database terdiri dari 5 tabel yaitu categories, cutomers, order_details, orders, dan products. Anda juga bisa membuat data dummy sendiri dengan migrasi, factory, dan faker seperti pada tutorial Crud Laravel 9. Download database laravel_filter.sql.
4. Membuat Model
Buat model Category dan OrderDetail menggunakan perintah berikut.
php artisan make:model Category php artisan make:model OrderDetail
5. Membuat Controller OrderDetail
Gunakan perintah berikut untuk membuat controller.
php artisan make:controller OrderDetailController --model=OrderDetail
Sesuaikan app/controllers/OrderDetailController.php
sebagai berikut.
<?php namespace App\Http\Controllers; use App\Models\Category; use App\Models\OrderDetail; use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; class OrderDetailController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index(Request $request) { $data['q'] = $request->query('q'); $data['category_id'] = $request->query('category_id'); $data['start'] = $request->query('start'); $data['end'] = $request->query('end'); $data['categories'] = Category::all(); $data['operators'] = [ '=' => 'equal to', '<>' => 'not equal to', '>' => 'greater than', '>=' => 'greater than or equal to', '<' => 'less than', '<=' => 'less than or equal to', 'between' => 'between', ]; $data['total_operator'] = $request->get('total_operator'); $data['total_value'] = $request->get('total_value'); $data['total_value_end'] = $request->get('total_value_end'); $query = OrderDetail::select('order_details.*', 'orders.*', 'customers.*', 'categories.*', 'products.*', DB::raw('quantity * price AS total')) ->join('products', 'products.product_id', '=', 'order_details.product_id') ->join('orders', 'orders.order_id', '=', 'order_details.order_id') ->join('customers', 'customers.customer_id', '=', 'orders.customer_id') ->join('categories', 'categories.category_id', '=', 'products.category_id') ->where(function ($query) use ($data) { $query->where('product_name', 'like', '%' . $data['q'] . '%'); $query->orWhere('customer_name', 'like', '%' . $data['q'] . '%'); $query->orWhere('category_name', 'like', '%' . $data['q'] . '%'); }); if ($data['start']) $query->whereDate('order_date', '>=', $data['start']); if ($data['end']) $query->whereDate('order_date', '<=', $data['end']); if ($data['category_id']) $query->where('categories.category_id', $data['category_id']); if ($data['total_operator']) { if ($data['total_operator'] == 'between') $query->whereRaw('quantity * price between ? AND ?', [$data['total_value'], $data['total_value_end']]); else $query->whereRaw('quantity * price ' . $data['total_operator'] . ' ? ', $data['total_value']); } $data['order_details'] = $query->paginate(15)->withQueryString(); return view('order_detail.index', $data); } /** * Show the form for creating a new resource. * * @return \Illuminate\Http\Response */ public function create() { } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { } /** * Display the specified resource. * * @param \App\Models\OrderDetail $orderDetail * @return \Illuminate\Http\Response */ public function show(OrderDetail $orderDetail) { } /** * Show the form for editing the specified resource. * * @param \App\Models\OrderDetail $orderDetail * @return \Illuminate\Http\Response */ public function edit(OrderDetail $orderDetail) { } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param \App\Models\OrderDetail $orderDetail * @return \Illuminate\Http\Response */ public function update(Request $request, OrderDetail $orderDetail) { } /** * Remove the specified resource from storage. * * @param \App\Models\OrderDetail $orderDetail * @return \Illuminate\Http\Response */ public function destroy(OrderDetail $orderDetail) { } }
- Perintah
$request->query('...')
berfungsi untuk mengambil nilai filter dan pencarian yang Anda masukkan. - Perintah
->where(function ($query) use ($data)
berfungsi untuk mengelompokkan perintah pencarian dengan OR.
6. Menambahkan Route order_detail
Tambahkan route untuk crud user di routes/web.php
bertipe resource
seperti berikut.
<?php use App\Http\Controllers\OrderDetailController; use Illuminate\Support\Facades\Route; /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Route::get('/', function () { return view('welcome'); }); Route::resource('order_detail', OrderDetailController::class);
7. Membuat View
Buat view untuk menampilkan data order_detail di direktori resources/views/order_detail/index.blade.php
.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Filter and Join Laravel</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"> </head> <body> <div class="container-fluid"> <h1>Order Details</h1> <div class="card"> <div class="card-header"> <form class="row row-cols-lg-auto g-1"> <div class="col"> <select class="form-select" name="category_id"> <option value="">All Category</option> @foreach($categories as $category) @if($category->category_id==$category_id) <option value="{{ $category->category_id }}" selected>{{ $category->category_name }}</option> @else <option value="{{ $category->category_id }}">{{ $category->category_name }}</option> @endif @endforeach </select> </div> <div class=" col"> <div class="input-group"> <input class="form-control" type="date" name="start" value="{{ $start }}" /> <input class="form-control" type="date" name="end" value="{{ $end }}" /> </div> </div> <div class="col"> <div class="input-group"> <select class="form-select" name="total_operator" onchange="hide_total_value_end()"> <option value="">All Total</option> @foreach($operators as $key => $val) @if($key==$total_operator) <option value="{{ $key }}" selected>Total {{ $val }}</option> @else <option value="{{ $key }}">Total {{ $val }}</option> @endif @endforeach </select> <input class="form-control" type="text" name="total_value" value="{{ $total_value }}" size="4" /> <input class="form-control" type="text" name="total_value_end" value="{{ $total_value_end }}" size="4" /> </div> </div> <div class=" col"> <input class="form-control" type="text" name="q" value="{{ $q }}" placeholder="Search here..." /> </div> <div class="col"> <button class="btn btn-success">Search</button> </div> </form> </div> <div class="card-body p-0"> <table class="table table-bordered table-striped table-hover table-sm m-0"> <thead> <tr> <th>#</th> <th>OrderID</th> <th>OrderDate</th> <th>CustomerID</th> <th>CustomerName</th> <th>ProductID</th> <th>ProductName</th> <th>CategoryID</th> <th>CategoryName</th> <th>Quantity</th> <th>Price</th> <th>Total</th> </tr> </thead> <?php $i = $order_details->firstItem(); ?> @foreach($order_details as $order_detail) <tr> <td>{{ $i++ }}</td> <td>{{ $order_detail->order_id }}</td> <td>{{ date('M d Y', strtotime($order_detail->order_date)) }}</td> <td>{{ $order_detail->customer_id }}</td> <td>{{ $order_detail->customer_name }}</td> <td>{{ $order_detail->product_id }}</td> <td>{{ $order_detail->product_name }}</td> <td>{{ $order_detail->category_id }}</td> <td>{{ $order_detail->category_name }}</td> <td>{{ $order_detail->quantity }}</td> <td>{{ $order_detail->price }}</td> <td>{{ $order_detail->total }}</td> </tr> @endforeach </table> </div> @if($order_details->hasPages()) <div class="card-footer"> {{ $order_details->links() }} </div> @endif </div> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <script> $(function() { hide_total_value_end(); }) function hide_total_value_end() { if ($('select[name="total_operator"]').val() == 'between') $('input[name="total_value_end"]').show(); else $('input[name="total_value_end"]').hide(); } </script> </body> </html>
8. Mengatur Template Filter
Atur agar template filter sesuai dengan bootstrap 5 di app/providers/AppServiceProvider.php
sebagai berikut.
<?php namespace App\Providers; use Illuminate\Pagination\Paginator; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * Register any application services. * * @return void */ public function register() { } /** * Bootstrap any application services. * * @return void */ public function boot() { Paginator::useBootstrapFive(); } }
9. Menjalankan Project Join, Search, Filter Laravel 9
Langkah terakhir adalah menjalankan project. Silahkan gunakan perintah berikut untuk mengaktifkan server laravel.
php artisan serve
Ketikkan alamat sesuai server diikuti dengan /customer di browser (http://127.0.0.1:8000/order_detail
). Hasilnya seperti berikut.


Masukkan tanggal awal dan akhir, sehingga data yang muncul antara kedua tanggal yang Anda masukkan.

Pencarian bisa Anda lakukan berdasarkan Nama customer, nama kategori, maupun nama produk, sehingga lebih mudah menem

Filter total antara lain:
- sama dengan
- lebih besar
- lebih besar sama dengan
- lebih kecil
- lebih kecil sama dengan
- diantara x dan y

Itulah tutorial membuat Advance Filter Laravel 9. Jika ada yang ditanyakan, silahkan berkomentar.
Apayah
says:mantaps bang
admin
says:Semoga membantu 🙂
Apit
says:Hai pak,
sudah mencoba tutorial dari atas sampe bawah ada error
Error
Call to undefined method Illuminate\Pagination\Paginator::useBootstrapFive()
http://127.0.0.1:8000/order_detail
Mohon bantuannya
admin
says:Tambahkan di bagian atas “use Illuminate\Pagination\Paginator;”
Kalau menggunakan Extension di Visual Studio Code, pasti otomatis ditambahkan ketika mengetik “Paginator::useBootstrapFive();”
Roby Sukmana
says:mas ijin bertanya, setelah saya menambahkan filter. datanya sudah muncul dan sesuai ..
misalnya data hasil pencaraian lebih dari pagination yang kita tentukan dan menekan halaman maka akan hilang data yang terfilter tadi
admin
says:Pastikan sudah mengisi withQueryString kak $query->paginate(15)->withQueryString()
Dudung Ruswan
says:Terima kasih, semoga menjadi penambah amal kebaikan.
fea one
says:liatin modelnya kak
admin
says:Tidak ada yang di ubah di bagian model, masih standarnya.