Hello everyone, we will continue our car rental project, this time we will focus on car management.
There is something missing in our database, namely photos of cars, therefore we will add an image column to the cars table. Run the following command on the terminal:
php artisan make:migration add_image_to_cars_table --table=cars
then open the migration and add the following code:
Schema::table('cars', function (Blueprint $table) {
$table->string('image');
});
then run artisan migrate.
Next we create a controller first by running the command
php artisan make:controller CarController --resource
Since we will be uploading files, we have to set up filestorage in config\filestorage.php
and change the links to:
'links' => [
public_path('storage') => storage_path('app'),
],
Next run the artisan command:
php artisan storage:link
on web.php
add route
Route::middleware(['auth'])->resource('/car', CarController::class);
in sidebar.blade.php
don’t forget to add a link for route car.index
<div class="sb-sidenav-menu-heading">Data</div>
<a class="nav-link collapsed" href="#" data-bs-toggle="collapse" data-bs-target="#collapseLayouts" aria-expanded="false" aria-controls="collapseLayouts">
<div class="sb-nav-link-icon"><i class="fas fa-columns"></i></div>
Car
<div class="sb-sidenav-collapse-arrow"><i class="fas fa-angle-down"></i></div>
</a>
<div class="collapse" id="collapseLayouts" aria-labelledby="headingOne" data-bs-parent="#sidenavAccordion">
<nav class="sb-sidenav-menu-nested nav">
<a class="nav-link" href="{{ route('car.index') }}">All Car</a>
</nav>
</div>
Index
Open CarController.php
, then we will create index view first. Here we will use pagination to handle if we have a lot of data.
public function index(){
$cars = Car::latest()->paginate(10);
return view('cars.index');
}
next we will create a cars.index
view, here we will use the sb-admin template.
Since we are using bootstrap for pagination, we have to set it to App\Providers\AppServiceProvider
.
use Illuminate\Pagination\Paginator;public function boot()
{
Paginator::useBootstrapFive();
}
Create
In CarController create method add code like this
public function create()
{
return view('cars.create');
}
and in the store method add code like this:
public function store(Request $request){
$data = $request->validate([
'name' => 'required',
'plat' => 'required',
'description' => 'required',
'price' => 'required|integer',
'status' => 'required',
]);
if($request->file('image')){
$data['image'] = $request->file('image')->store('cars');
}
Car::create($data);
return redirect()->route('car.index')->with('success', 'Data mobil berhasil ditambahkan');
}
Selanjutnya kita akan membuat view cars/create.blade.php
,
In the form above, we have added an error message, an old value, and a preview image using javascript.
Delete
To use this feature, we will add 1 action column to cars\index.blade.php
.
<td>
<form class="d-inline" action="{{ route('car.destroy', $car->id) }}" method="POST">
@csrf
@method('delete')
<button class="btn btn-danger" onclick="return confirm('Hapus data mobil ini?')">Hapus</button>
</form>
<a href="{{ route('car.edit', $car->id) }}" class="btn btn-success">Edit</a>
<a href="#" class="btn btn-info">Detail</a>
</td>
Then in CarController
method destroy add code
public function destroy(Car $car){
if($car->image){
Storage::delete($car->image);
}
Car::destroy($car->id);
return redirect()->route('car.index')->with('success', 'Data mobil berhasil dihapus');
}
Show
For the detail part we will use bootstrap’s modal
<button type="button" class="btn btn-info" data-bs-toggle="modal" data-bs-target="#detail{{ $car->id }}">Detail</button>
Then under the table we add the modal code
<div class="modal fade" data-bs-backdrop="static" data-bs-keyboard="false" id="detail{{ $car->id }}" tabindex="-1" aria-labelledby="detail{{ $car->id }}Label" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>Nama : {{ $car->name }}</p>
<p>Plat : {{ $car->plat }}</p>
<p>Deskripsi : {{ $car->description }}</p>
<p>Harga : {{ number_format($car->price, 2) }}</p>
<p>Status : @if($car->status == 1)
<span class="badge bg-success">Available</span>
@else
<span class="badge bg-danger">Not Available</span>
@endif</p>
<p>
<img src="{{ asset('storage/' . $car->image) }}" width="400" alt="">
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Update
To create an update feature we will use the edit and update methods in CarController.php
,
public function edit(Car $car){
return view('cars.edit', ['car'=> $car]);
}public function update(Request $request, Car $car){
$data = $request->validate([
'name' => 'required',
'plat' => 'required',
'description' => 'required',
'price' => 'required|integer',
'status' => 'required',
]);
if($request->file('image')){
if($request->oldImage){
Storage::delete($request->oldImage);
}
$data['image'] = $request->file('image')->store('cars');
}
$car->update($data);
return redirect()->route('car.index')->with('success', 'Data mobil berhasil diedit');
}
Now we create an edit view in cars\edit.blade.php
with the following code:
the edit view is not much different from create, there is only car data to be edited.
Search
in the cars\index.blade.php
view add a search form
<div class="mt-3 justify-content-center">
<form action="{{ route('car.index') }}" method="GET">
<div class="row">
<div class="col">
<div class="input-group mb-3">
<input type="text" value="{{ Request::input('search') }}" class="form-control" placeholder="search . . ." name="search">
</div>
</div>
<div class="col-1">
<button class="btn btn-outline-primary" type="submit">Search</button>
</div>
</div>
</form>
</div>
Then in the CarController.php
method index we modify the code to
$search = $request->search;
$cars = Car::where('name', 'like', '%' . $search .'%')
->orWhere('plat', 'like', '%' . $search .'%')
->orWhere('price', 'like', '%' . $search .'%')
->latest()
->paginate(10);
return view('cars.index', compact('cars'));
Okay, that’s enough for Car management, then we will make transaction and user management, thank you.