Tutorial Laravel 11 untuk Pemula: Langsung Bisa bikin CRUD!
Pengenalan Laravel
Laravel adalah sebuah framework PHP yang open source dan dirancang untuk memudahkan pengembangan aplikasi web. Framework ini mengikuti pola arsitektur Model-View-Controller (MVC) dan menyediakan berbagai fitur serta alat yang berguna untuk mempercepat proses pengembangan web.
Laravel sangat populer di kalangan pengembang web karena dokumentasinya yang lengkap, komunitas yang aktif, dan ekosistem paket yang kaya yang memungkinkan pengembang untuk memperluas fungsi dasar framework sesuai kebutuhan.
Framework: adalah kumpulan program berupa file pustaka (libraries) atau class-class yang mendukung dalam pengembangan aplikasi secara terstruktur dan independen terhadap aplikasi. Software Framework adalah sebuah desain yang bisa digunakan berulang-ulang (re-usable design) untuk sebuah sistem atau sub sistem piranti lunak.
Manfaat framework:
- Mempercepat proses pembuatan aplikasi baik itu aplikasi berbasis desktop, mobile ataupun web.
- Membantu para developer dalam perencanaan, pembuatan dan pemeliharaan sebuah aplikasi.
- Aplikasi yang dihasilkan menjadi lebih stabil dan handal, hal ini dikarenakan Framework sudah melalui proses uji baik itu stabilitas dan juga keandalannya.
- Memudahkan para developer dalam membaca code program dan lebih mudah dalam mencari bugs.
- Memiliki tingkat keamanan yang lebih, hal ini dikarenakan Framework telah mengantisipasi cela – cela keamanan yang mungkin timbul.
- Mempermudah developer dalam mendokumentasikan aplikasi-aplikasi yang sedang dibangun.
Arsitektur Laravel didasarkan pada pola arsitektur Model-View-Controller (MVC) yang memisahkan logika aplikasi menjadi tiga komponen utama: Model, View, dan Controller.
- Model bertanggung jawab untuk menangani data dan logika bisnis aplikasi. Dalam Laravel, model biasanya berinteraksi dengan database menggunakan Eloquent ORM. Model mewakili tabel dalam database dan menyediakan cara yang elegan untuk berinteraksi dengan data
- View View adalah komponen yang bertanggung jawab untuk menyajikan data kepada pengguna. Dalam Laravel, tampilan dibuat menggunakan Blade template engine. Blade memungkinkan penggunaan logika dalam template dengan sintak yang bersih dan mudah dipahami.
- Controller bertindak sebagai perantara antara Model dan View. Controller menerima input dari pengguna melalui HTTP request, memprosesnya (misalnya, mengambil data dari model), dan kemudian mengembalikan respon yang sesuai, biasanya berupa tampilan.
Arsitektur Laravel yang berbasis MVC memisahkan tanggung jawab di antara berbagai komponen, membuat aplikasi lebih terstruktur, mudah dipahami, dan mudah dikembangkan.
Note: kesimpulan nya data dari model(database) hanya bisa berinteraksi dengan controller. Controller akan berinteraksi dengan view (membawa data dari model/database), dan view akan menampilkannya ke web begitupun seterusnya sampe capek dan akan muter muter aja heheh.
instalasai laravel
Yang perlu di persiapkan:
- Composer
- Xampp
- Visual studio code
- Niat (hal utama)
Tahap instalasi:
Composer
Composer dibutuhkan untuk manajemen paket di PHP dan ini akan kita pakai untuk instal Laravel:
- Silakan baca: Cara Install Composer di Windows maupun Linux di sini
XAMPP
XAMPP dibutuhkan untuk menjalankan server seperti MySQL dan PHPMyAdmin untuk manajemen database.
Silakan baca:
Visual Studio Code
Visual Studio Code adalah teks editor yang akan kita pakai untuk menulis kode.
Silahkan baca:
Tahap instalasi laravel
Perintah untuk install laravel dokumentasi nya Bisa kunjungi halaman resmi laravel https://laravel.com/docs/11.x/installation
Selanjutnya buat dulu folder khusus di mana ingin menginstall laravel ini agar tidak salah nanti nya.
1. Instalasi laravel
Buka Terminal lalu ketik perintah beriku:
composer create-project laravel/laravel produk
Kemudian di enter (jangan nunggu entar)
Di sini saya membuat projek nya dengan nama produk
dan untuk versi yang lain langsung kunjungi dokumentasi ya.
Nanti nya akan langsung melakukan penginsatalan dan jika pertama kali akan sedikit lama (belom nemu alasan nya kenapa).
2. Test instalasi laravel nya
Kalian harus masuk dulu ke folder laravel yang di buat tadi. Jika di windows buka folder yang kalian buat nantinya akan ada folder produk (jika nama folder nya sama dengan ini).
Kemudian di atas nya itu ketikan cmd Kemudian ketikan perintah :
php artisan serve.
Selanjutnya klik masuk ke web browser kalian atau klik link ini http://127.0.0.1:8000/ maka akan tampil:
Mantap, Kita berhasil membuat projek laravel nya.
Memahami Struktur Folder Laravel
Folder Controller dan model
Controller berada di folder App/Http/Controller
. Nanti kode logikanya mau ke mana akan ada di sini
Model berada di App/model
Nanti database nya berada di sini.
View
View berada di folder resources/views
. Nanti nya di sini kita akan koding mengkoding untuk tampilan nya.
Nah ada yang belom kita bahas di awal yaitu routes dan migration
Apa sih itu routes dan migration?
Routes adalah penjembatani antara controller dan view
Dan migration adalah kode yang akan kita gunakan untuk membuat tabel di database.
Di dalam di folder routes/
, terdapat dua file:
console.php
adalah route untuk menjalankan controller dari CMD danweb.php
adalah route untuk menjalankan controller yang diakses dari web atau HTTP.
Folder migration berada di folder database/migration
.
![Folder migration]
Nah di sini sudah ada migration yang di buatkan oleh laravel nya langsung.
Nah seperti sebelum nya kita belom membahas routes yaitu fungsi nya untuk menjembatani antara controller dan view atau program nya akan ke arah mana apakah ke view dulu atau ke controller.
Latihan: Menampilkan kode routes
Coba buka file routes/web.php
, di sini akan terdapat definisi routes dari aplikasi kita. Semua routes dari aplikasi wajib ditulis di ini.
Di setiap route terdapat parameter URI
yang menyatakan alamat URL dan action
adalah fungsi/controller untuk di jalankan saat alamat tersebut dibuka.
Sebagai contoh:
Di sini terdapat route menuju URL /
(root) atau home page. Lalu di sana terdapat fungsi yang akan dijalankan saat route /
dibuka. Fungsi tersebut akan membuka file view dari resource/view/welcome.blade.php
.
Oke, sekarang mari kita latihan!
Buatlah folder dengan nama produk
dan buat file hello.blade.php
di dalamnya.
Setiap membuat file di view harus menggunakan blade.php
agar bisa terbaca oleh laravel nya dikarenakan laravel menggunakan bahasa blade untuk template engine.
Dan masukan kode ini ke dalam hello.blade.php
. Disini saya membuat kan hello untuk test saja apakah nampil apa belom.
Kemudian di routes nya Saya membuat routes/web.php
nya dengan memberikan url nya produk.
Route::get('/produk', function () {
return view('produk.hello');
});
Oke kembali lagi ke web nya tetapi di url-nya di tambahkan /produk
.
Di sini kita sudah bisa menampilkannya dan view ini kita sudah bisa membuat web statis lo tampa menggunakan controller dan model(database).
Oke agar lebih bagus kita menggunakan template yang sudah ada.
Menggunakan Template Bootstrap di Laravel
Template nya bisa di download di sini jika mau dan kemudian ekstrak file nya.
Oke agar tampilan nya berhasil ada beberapa yang perlu dipersiapkan ya.
Pindahkan folder assets
, css
, dan js
dari hasil ekstrak tadi ke folder public
yang ada di projek laravel nya.
Sehingga folder public
berisi seperti ini:
Buat view baru di dalam folder views/product
dengan nama index.blade.php
.
Kemudian copy kode template dari file index.html
dari template yang kita download tai ke dalam index.blade.php
.
Kode nya jadi banyak ya.
Oke selanjutnya ubah kode di routes/web.php
menjadi seperti ini:
Route::get('/produk', function () {
return view('produk.index');
});
Untuk view hello.blade.php
yang dibuat tadi, kita bisa hapus.. karena cuma dipakai buat testing aja.
Selanjutnya coba periksa di browser, maka tampilan nya akan seperti ini:
Oke kita sudah berhasil menampilkan nya.
Di sini saya akan menghapus kode dari bari 118
sampai 175
untuk menghilangkan grafik chart-nya.
Maka hasilnya:
Selanjutnya kita akan membuat layout supaya memudahkan dan tidak menulis template view berulang.
Buat folder baru di dalam views
dengan nama layouts
, kemudian di dalamnya buat view baru dengan nama main.blade.php
.
Selanjutnya, buka kembali file product/index.blade.php
. Kemudian dari <main>
nya ke atas sampai baris 1 di-cut dan paste ke dalam main.blade.php
.
Atau biar gampang langsung di copy saja kode ini ke dalam main.blade.php
:
<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, shrink-to-fit=no" />
<meta name="description" content="" />
<meta name="author" content="" />
<title>Dashboard - SB Admin</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/style.min.css" rel="stylesheet" />
<link href="/css/styles.css" rel="stylesheet" />
<script src="https://use.fontawesome.com/releases/v6.3.0/js/all.js" crossorigin="anonymous"></script>
</head>
<body class="sb-nav-fixed">
<nav class="sb-topnav navbar navbar-expand navbar-dark bg-dark">
<!-- Navbar Brand-->
<a class="navbar-brand ps-3" href="index.html">Start Bootstrap</a>
<!-- Sidebar Toggle-->
<button class="btn btn-link btn-sm order-1 order-lg-0 me-4 me-lg-0" id="sidebarToggle" href="#!"><i class="fas fa-bars"></i></button>
<!-- Navbar Search-->
<form class="d-none d-md-inline-block form-inline ms-auto me-0 me-md-3 my-2 my-md-0">
<div class="input-group">
<input class="form-control" type="text" placeholder="Search for..." aria-label="Search for..." aria-describedby="btnNavbarSearch" />
<button class="btn btn-primary" id="btnNavbarSearch" type="button"><i class="fas fa-search"></i></button>
</div>
</form>
<!-- Navbar-->
<ul class="navbar-nav ms-auto ms-md-0 me-3 me-lg-4">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" id="navbarDropdown" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false"><i class="fas fa-user fa-fw"></i></a>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown">
<li><a class="dropdown-item" href="#!">Settings</a></li>
<li><a class="dropdown-item" href="#!">Activity Log</a></li>
<li><hr class="dropdown-divider" /></li>
<li><a class="dropdown-item" href="#!">Logout</a></li>
</ul>
</li>
</ul>
</nav>
<div id="layoutSidenav">
<div id="layoutSidenav_nav">
<nav class="sb-sidenav accordion sb-sidenav-dark" id="sidenavAccordion">
<div class="sb-sidenav-menu">
<div class="nav">
<div class="sb-sidenav-menu-heading">Core</div>
<a class="nav-link" href="index.html">
<div class="sb-nav-link-icon"><i class="fas fa-tachometer-alt"></i></div>
Dashboard
</a>
<div class="sb-sidenav-menu-heading">Interface</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>
Layouts
<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="layout-static.html">Static Navigation</a>
<a class="nav-link" href="layout-sidenav-light.html">Light Sidenav</a>
</nav>
</div>
<a class="nav-link collapsed" href="#" data-bs-toggle="collapse" data-bs-target="#collapsePages" aria-expanded="false" aria-controls="collapsePages">
<div class="sb-nav-link-icon"><i class="fas fa-book-open"></i></div>
Pages
<div class="sb-sidenav-collapse-arrow"><i class="fas fa-angle-down"></i></div>
</a>
<div class="collapse" id="collapsePages" aria-labelledby="headingTwo" data-bs-parent="#sidenavAccordion">
<nav class="sb-sidenav-menu-nested nav accordion" id="sidenavAccordionPages">
<a class="nav-link collapsed" href="#" data-bs-toggle="collapse" data-bs-target="#pagesCollapseAuth" aria-expanded="false" aria-controls="pagesCollapseAuth">
Authentication
<div class="sb-sidenav-collapse-arrow"><i class="fas fa-angle-down"></i></div>
</a>
<div class="collapse" id="pagesCollapseAuth" aria-labelledby="headingOne" data-bs-parent="#sidenavAccordionPages">
<nav class="sb-sidenav-menu-nested nav">
<a class="nav-link" href="login.html">Login</a>
<a class="nav-link" href="register.html">Register</a>
<a class="nav-link" href="password.html">Forgot Password</a>
</nav>
</div>
<a class="nav-link collapsed" href="#" data-bs-toggle="collapse" data-bs-target="#pagesCollapseError" aria-expanded="false" aria-controls="pagesCollapseError">
Error
<div class="sb-sidenav-collapse-arrow"><i class="fas fa-angle-down"></i></div>
</a>
<div class="collapse" id="pagesCollapseError" aria-labelledby="headingOne" data-bs-parent="#sidenavAccordionPages">
<nav class="sb-sidenav-menu-nested nav">
<a class="nav-link" href="401.html">401 Page</a>
<a class="nav-link" href="404.html">404 Page</a>
<a class="nav-link" href="500.html">500 Page</a>
</nav>
</div>
</nav>
</div>
<div class="sb-sidenav-menu-heading">Addons</div>
<a class="nav-link" href="charts.html">
<div class="sb-nav-link-icon"><i class="fas fa-chart-area"></i></div>
Charts
</a>
<a class="nav-link" href="tables.html">
<div class="sb-nav-link-icon"><i class="fas fa-table"></i></div>
Tables
</a>
</div>
</div>
<div class="sb-sidenav-footer">
<div class="small">Logged in as:</div>
Start Bootstrap
</div>
</nav>
</div>
<div id="layoutSidenav_content">
<main>
@yield('content')
</main>
<footer class="py-4 bg-light mt-auto">
<div class="container-fluid px-4">
<div class="d-flex align-items-center justify-content-between small">
<div class="text-muted">Copyright © Your Website 2023</div>
<div>
<a href="#">Privacy Policy</a>
·
<a href="#">Terms & Conditions</a>
</div>
</div>
</div>
</footer>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<script src="/js/scripts.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js" crossorigin="anonymous"></script>
<script src="/assets/demo/chart-area-demo.js"></script>
<script src="/assets/demo/chart-bar-demo.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/simple-datatables.min.js" crossorigin="anonymous"></script>
<script src="/js/datatables-simple-demo.js"></script>
</body>
</html>
Perhatikan pada bagian kode ini:
@yield('content')
Ini adalah placeholder, yang nantinya akan diisi dengan view lain.
Kemudian di index.blade.php
nya kita menambahkan extend dan section yang menandakan kita akan menggunakan layout main.blade.php
.
Silakan ubah kode view index.blade.php
menjadi seperti ini:
Maka hasil nya:
Tidak ada perubahan sih tapi nanti nya memudahkan kita untuk menampilkan atau mengubah data yang ada di konten nya atau di tabelnya.
Di sini teman-teman sudah bisa membuat web tanpa database ya.
Membuat Controller
Untuk membuat controller nya kita bisa menggunakan perintah
php artisan make:controller NamaController --r
Nanti nya dari index, create, show, edit, update delete-nya akan di buatkan. Jika tidak memasukkan --r
tidak masalah juga sebenarnya nanti nya kita buat sendiri. Dan perlu di ingat untuk nama controller-nya harus diawali dengan huruf kapital.
Contoh nya saya akan membuat produk controller:
php artisan make:controller ProdukController --r
Kalau berhasil, maka akan tampil created successfully seperti ini:
Perintah ini akan membuat file baru di App/Http/Controllers
.
Nah sekarang kita akan menggunakan controller nya untuk mengakses view nya nih.
Silakan buka file routes/web.php
dan kode routes yang 2 tadi di hapus aja.
Ubah menjadi seperti ini:
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProdukController\;
route::get("/", [ProdukController::class, 'index'])->name('index.index');
Artinya, pada route /
ini, kita akan menggunakan controller ProdukController::class
dan akan memanggil fungsi index()
untuk aksi yang akan dilakukan saat route /
dibuka.
Lalu di bagian akhir, saya menambahkan ->name('index.index')
ini berfungsi untuk memberikan nama route ini dan nanti bisa kita akses dengan mudah untuk melakukan redirect dari controller maupun view.
Kemudian, kita perlu modifikasi isi fungsi index()
yang ada di dalam ProdukController
menjadi seperti ini:
Artinya fungsi index()
akan menampikan sebuah view dari file views/produk/index.blade.php
.
Silakan buka browser dan akses url http://127.0.0.1:8000 untuk melihat hasilnya.
Hasil nya akan seperti ini.
Membuat Migration dan Model
Untuk membuat migration dan model kita bisa menggunakan perintah:
php artisan make:model Produk --m
Opsi -m
artinya kita akan membuat kode migration-nya. Jadi perintah ini akan membuat dua file yakni:
Produk.php
adalah kode dari model dan2024_05_22_170812_create_produks_table.php
adalah kode migrasi untuk membuat tabelproduks
.
Sebenarnya bisa saja kita langsung meminta dibuatkan 3 file sekaligus beserta ProdukController
dengan opsi -cmr
.
Jika pembuatan model dan migration berhasil, maka akan tampil seperti ini:
Kode Model-nya akan berada di folder app/models/
.
Kode Migration akan berada di folder database/migration/
Note: nama file kode migration bersifat unik, karena itu di depannya terdapat tanggal timestamp yang menyatakan tanggal dan waktu pembuatan dari file ini.
Di dalam migration kita akan membuat tabel produk dengan isi field nya:
- Nama,
- jenis,
- deskripsi,
- harga_jual,
- harga_beli,
- foto
Silakan tambah kode ini di migration _create_produks_table.php
.
public function up(): void
{
Schema::create('produks', function (Blueprint $table) {
$table->id();
$table->string('nama');
$table->string('jenis');
$table->text('deskripsi')->nullable();
$table->decimal('harga_jual', 10, 2);
$table->decimal('harga_beli', 10, 2);
$table->string('foto')->nullable();
$table->timestamps();
});
}
Penjelasan:
- Kolom
nama
danjenis
akan bertipe datastring
- Kolom
deskripsi
bertipetext
dan ada nullable yang artinya boleh tidak di isi - Kolom
harga
jual akan bertipe datadecimal
, dan maksud dari10, 2
ini adalah total jumlah digit yang diperbolehkan dalam angka tersebut, termasuk digit sebelum dan setelah titik desimal adalah 10 digit dan di belakang nya harus 2 digit. Contohnya:12345678.90
- Dan kolom
foto
bertipe data string karena data yang akan disimpan berupa URL atau bisa juga Base64 yang merupakan hasil encoding dari file gambar.
Selanjutnya kita melakukan migration ke database dengan tujuan untuk membuat data tabel yang ada di database. O iya sebelumnya kita harus setup credential database di file .env
terlebih dahulu agar bisa terhubung dengan database server-nya.
Silakan buat variabel seperti ini di dalam .env
.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=produk
DB_USERNAME=root
DB_PASSWORD=
Ini adalah credential untuk database yang menggunakan XAMPP. Password dikosongkan saja, karena user root
default di XAMPP tidak menggunakan password.
Selanjutnya kita perlu membuat database-nya di phpmyadmin. Caranya jalankan XAMPP terlebih dahulu. Aktifkan service Apache, PHP, dan MYSQL.
Setelah itu, buka http://localhost/phpmyadmin
Jangan hiraukan database yang banyak ini ya wkwk. 😅
Oke silakan klik new kemudian masukan nama database sesuai dengan nama yang kita buat di .env
.
Maka akan tampil seperti ini.
Sekarang kita kembali ke kodingan laravel-nya.
Buka Teriminal, lalu ketikan perintah:
php artisan migrate
Perintah ini akan menjalankan migrasi database sesuai dengan kode pada database/migrations/
. Jika ada error di kode tersebut, maka migrasi akan gagal.
Jika berhasil, maka tabel baru akan dibuat dengan kolom seperti yang kita deskripsikan di kode migration.
Untuk memastikan, silakan refresh Phpmyadmin maka akan terbuat seperti ini.
Oke selanjutnya kita akan membuatkan model.
Silakan buka file app/models/produk.php
, lalu ubah kodenya menjadi seperti ini:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Produk extends Model
{
use HasFactory;
protected $fillable = [
'nama',
'jenis',
'deskripsi',
'harga_jual',
'harga_beli',
'foto'
];
}
Pada kode ini kita mengisi variabel $fillable
dengan nama-nama kolom yang boleh diisi. Nantinya saat kita melakukan insert data dari model ini, maka kita hanya akan diizinkan mengisi data ke nama-nama kolom yang ada di $fillable
.
Selanjutnya kita coba menginputkan data terlebih dahulu untuk memastikan kolom-kolom tersebut dapat kita isi. Kita akan menggunakan seeder yang ada di Laravel.
Silakan buat seeder baru dengan perintah ini:
php artisan make:seeder ProdukSeeder
Lalu buka folder database/seeder
dan lihatlah kita sudah di buatkan file dengan nama Produkseeder.php
.
Silakan ubah kode ProdukSeeder.php
menjadi seperti ini:
<?php
namespace Database\Seeders;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class ProdukSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
//
DB::table('produks')->insert([
[
'nama' => 'Produk 1',
'jenis' => 'Elektronik',
'deskripsi' => 'Deskripsi untuk Produk 1',
'harga_jual' => 1000000.00,
'harga_beli' => 800000.00,
'foto' => null,
'created_at' => now(),
'updated_at' => now(),
],
[
'nama' => 'Produk 2',
'jenis' => 'Pakaian',
'deskripsi' => 'Deskripsi untuk Produk 2',
'harga_jual' => 200000.00,
'harga_beli' => 150000.00,
'foto' => null,
'created_at' => now(),
'updated_at' => now(),
],
[
'nama' => 'Produk 3',
'jenis' => 'Peralatan Rumah Tangga',
'deskripsi' => 'Deskripsi untuk Produk 3',
'harga_jual' => 300000.00,
'harga_beli' => 250000.00,
'foto' => null,
'created_at' => now(),
'updated_at' => now(),
],
]);
}
}
Dan jangan lupa ubah kode DatabaseSeeder,php
menjadi seperti di bawah ini agar kita tidak perlu memanggil satu satu seeder nya untuk di kirim ke database.
<?php
namespace Database\Seeders;
use App\Models\User;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Database\Seeders\ProdukSeeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*/
public function run(): void
{
// User::factory(10)->create();
$this->call(ProdukSeeder::class);
User::factory()->create([
'name' => 'Test User',
'email' => '[email protected]',
]);
}
}
Sekarang jalankan seeder dengan perintah
php artisan db:seed
Dan di table produks
kita sudah ada data nya yang di kirim dari seeder tadi.
Menampilkan data ke view
Oke kita akan menampilkan data yang sudah kita inputkan tadi ke dalam view.
Silakan buka file app/http/controller/ProdukController.php
dan tambahkan kode ini ke dalam fungsi index
.
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Produk;
class ProdukController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
//
$produk = Produk::all();
return view('produk.index', compact('produk'));
}
//...
}
Pada fungsi index()
saya membuat variable dengan nama $produk = Produk::all()
dengan tujuan saya ingin menampilkan semua data yang ada di tabel produk.
Kemudian mengembalikan view produk.index
dan memberikan parameter compact('produk')
. Fungsi compact()
adalah fungsi untuk membuat array dari nama variabel. Pada kasus ini kita akan membuat array dengan nama produk
dan isinya disesuaikan dengan isi yang ada di dalam variabel $produk
. Sehingga nanti kita bisa akses data di dalam view dalam bentuk array.
Sekarang buka file resources/views/produk/produk.blade.php
.
Silakan hapus semua yang ada di dalam <table>
bagian pada <tbody>
dikarenakan sudah tidak kita pakai lagi dan akan digantikan dengan data produk yang kita kirim dari controller.
Silakan kita ubah kodenya menjadi seperti ini.
@extends('layoutes.main')
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
@section('content')
<div class="container-fluid px-4">
<h1 class="mt-4">Dashboard</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item active">Dashboard</li>
</ol>
<div class="card mb-4">
<div class="card-header">
{{-- <i class=""></i> --}}
<a href="{{ route('index.create') }}" class="btn btn-sm btn-primary">Tambah data</a>
</div>
<div class="card-body">
<table id="datatablesSimple">
<thead>
<tr>
<th>No</th>
<th>Nama</th>
<th>Jenis</th>
<th>Harga Jual</th>
<th>Harga Beli</th>
<th>Foto</th>
<th width="280px">Action</th>
</tr>
</thead>
<tfoot>
<tr>
<th>No</th>
<th>Nama</th>
<th>Jenis</th>
<th>Harga Jual</th>
<th>Harga Beli</th>
<th>Foto</th>
<th>Action</th>
</tr>
</tfoot>
<tbody>
@foreach ( $produk as $k )
<tr>
<td>{{ $loop->iteration }}</td>
<td>{{ $k->nama }}</td>
<td>{{ $k->jenis }}</td>
<td>{{ $k->harga_jual }}</td>
<td>{{ $k->harga_beli }}</td>
<td>
@empty($k->foto)
<img src="{{url('image/nophoto.jpg')}}"
alt="project-image" class="rounded" style="width: 100%; max-width: 100px; height: auto;">
@else
<img src="{{url('image')}}/{{$k->foto}}"
alt="project-image" class="rounded" style="width: 100%; max-width: 100px; height: auto;">
@endempty
</td>
<td>
<a href="" class="btn btn-sm btn-secondary">show</a>
<a href="{{ route('index.edit', $k->id) }}" class="btn btn-sm btn-warning">edit</a>
<button type="button" class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#exampleModal{{$k->id}}">
hapus
</button>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
@endsection
Maka hasilnya:
Di sini saya menggunakan foreach untuk perulangan yang menampilkan banyak data dalam bentuk array dan di bagian foto saya menambahkan logika jika gambarnya tidak ada maka nofoto akan ditampilkan, tapi jika ada foto makan gambar itu yang akan ditampilkan.
Oke ada tambahan sedikit saya lupa untuk membuat folder image/
di folder public/
, silakan buat terlebih dulu.
Untuk gambar nophoto.jpg
silakan gunakan gambar ini:
Berikutnya kita akan membuat fitur untuk menambahkan, mengedit, dan menghapus data.
Menambahkan Data
Mari kita buat view-nya terlebih dahulu. Silakan buat file baru di dalam folder resources/views/produk/
dengan nama create.blade.php
kemudian isi dengan kode berikut:
@extends('layoutes.main')
@section('content')
<div class="container-fluid px-4">
<h1 class="mt-4">Dashboard</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item active">Dashboard</li>
</ol>
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-table me-1"></i>
Tambah data
</div>
<div class="card-body">
<form action="{{ route('index.store') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="form-group">
<label for="nama">Nama:</label>
<input type="text" class="form-control @error('nama') is-invalid @enderror" id="nama" name="nama" value="{{ old('nama') }}">
@error('nama')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="form-group">
<label for="jenis">Jenis:</label>
<input type="text" class="form-control @error('jenis') is-invalid @enderror" id="jenis" name="jenis" value="{{ old('jenis') }}">
@error('jenis')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="form-group">
<label for="harga_jual">Harga Jual:</label>
<input type="text" class="form-control @error('harga_jual') is-invalid @enderror" id="harga_jual" name="harga_jual" value="{{ old('harga_jual') }}">
@error('harga_jual')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="form-group">
<label for="harga_beli">Harga Beli:</label>
<input type="text" class="form-control @error('harga_beli') is-invalid @enderror" id="harga_beli" name="harga_beli" value="{{ old('harga_beli') }}">
@error('harga_beli')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="form-group">
<label for="deskripsi">Deskripsi:</label>
<textarea class="form-control" id="deskripsi" name="deskripsi">{{ old('deskripsi') }}</textarea>
</div>
<div class="form-group">
<label for="foto">Foto Produk:</label>
<input type="file" class="form-control" id="foto" name="foto">
</div>
<button type="submit" class="btn btn-primary mt-4">Submit</button>
</form>
</div>
</div>
</div>
@endsection
Kemudian kita akan membuat routes yang akan mengarah ke ProdukController::create()
.
Silakan buka file routes/web.php
dan tambahkan kode berikut:
route::get('/produk/create', [ProdukController::class, 'create'])->name('index.create');
Sekarang kita ke controller nya.
Tambahkan kode ini, di dalam fungsi create()
pada controller ProdukController
.
public function create()
{
//
return view('produk.create');
}
Untuk saat ini kita hanya menampilkan view saja di dalam fungsi ini. Untuk melihat hasilnya, bisa dibuka melalui http://127.0.0.1:8001/produk/create.
Nah agar kita tidak perlu memasukkan link lagi saat ingin membuka form ini kita bisa tambahkan link di dalam view produk/index.blade.php
.
<a href="{{ route('index.create') }}" class="btn btn-sm btn-primary">Tambah Data</a>
Sehingga menjadi seperti ini:
Perhatikan, di sini kita menggunakan route('index.create')
untuk membuat URL pada tag <a>
. index.create
adalah nama dari routes yang sudah kita buat, dalam hal ini akan menuju ke URL /produk/create
.
Nah kita sudah membuat view form create, selanjutnya kita perlu membuat fungsi dan route untuk menyimpan data nya.
Silakan tambahkan routes lagi di bawah routes create
yang kita buat sebelum nya.
route::post('/produk/store', [ProdukController::class, 'store'])->name('index.store');
Nah di sini ada sedikit perbedaan yaitu dia menggunakan method post dan sebelum nya menggunakan method get. Dikarenakan kita ingin mengirim data dan bukan mengambil data.
Dan di create.blade.php
nya silakan tambah kan kode ini.
@extends('layoutes.main')
@section('content')
<div class="container-fluid px-4">
<h1 class="mt-4">Dashboard</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item active">Dashboard</li>
</ol>
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-table me-1"></i>
Tambah data
</div>
<div class="card-body">
<form action="{{ route('index.store') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="form-group">
<label for="nama">Nama:</label>
<input type="text" class="form-control @error('nama') is-invalid @enderror" id="nama" name="nama" value="{{ old('nama') }}">
@error('nama')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="form-group">
<label for="jenis">Jenis:</label>
<input type="text" class="form-control @error('jenis') is-invalid @enderror" id="jenis" name="jenis" value="{{ old('jenis') }}">
@error('jenis')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="form-group">
<label for="harga_jual">Harga Jual:</label>
<input type="text" class="form-control @error('harga_jual') is-invalid @enderror" id="harga_jual" name="harga_jual" value="{{ old('harga_jual') }}">
@error('harga_jual')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="form-group">
<label for="harga_beli">Harga Beli:</label>
<input type="text" class="form-control @error('harga_beli') is-invalid @enderror" id="harga_beli" name="harga_beli" value="{{ old('harga_beli') }}">
@error('harga_beli')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="form-group">
<label for="deskripsi">Deskripsi:</label>
<textarea class="form-control" id="deskripsi" name="deskripsi">{{ old('deskripsi') }}</textarea>
</div>
<div class="form-group">
<label for="foto">Foto Produk:</label>
<input type="file" class="form-control" id="foto" name="foto">
</div>
<button type="submit" class="btn btn-primary mt-4">Submit</button>
</form>
</div>
</div>
</div>
@endsection
Kita perlu menambahkan method @csrf
di dalam form agar bisa melakukan pengiriman data karena csrf ini nanti nya yg menjadi token atau keamanan data yg kita kirim.
Oke selanjutnya silakan buka ProdukController
nya di bagian fungsi store()
silakan tambah kode ini.
Dan tambah kan kode ini.
public function store(Request $request)
{
// melakukan validasi data
$request->validate([
'nama' => 'required|max:45',
'jenis' => 'required|max:45',
'harga_jual' => 'required|numeric',
'harga_beli' => 'required|numeric',
'foto' => 'nullable|image|mimes:jpg,png,jpeg,gif,svg|max:2048',
],
[
'nama.required' => 'Nama wajib diisi',
'nama.max' => 'Nama maksimal 45 karakter',
'jenis.required' => 'jenis wajib diisi',
'jenis.max' => 'jenis maksimal 45 karakter',
'foto.max' => 'Foto maksimal 2 MB',
'foto.mimes' => 'File ekstensi hanya bisa jpg,png,jpeg,gif, svg',
'foto.image' => 'File harus berbentuk image'
]);
//jika file foto ada yang terupload
if(!empty($request->foto)){
//maka proses berikut yang dijalankan
$fileName = 'foto-'.uniqid().'.'.$request->foto->extension();
//setelah tau fotonya sudah masuk maka tempatkan ke public
$request->foto->move(public_path('image'), $fileName);
} else {
$fileName = 'nophoto.jpg';
}
//tambah data produk
DB::table('produks')->insert([
'nama'=>$request->nama,
'jenis'=>$request->jenis,
'harga_jual'=>$request->harga_jual,
'harga_beli'=>$request->harga_beli,
'deskripsi' => $request->deskripsi,
'foto'=>$fileName,
]);
return redirect()->route('index.index');
}
Dan jangan lupa tambahkan kode ini di atasnya:
use Illuminate\Support\Facades\DB;
Sebelum data itu dikirim kita harus melakukan validasi terlebih dahulu apakah data yang kita minta sudah sesuai atau belom. Mulai dari nama nya jenis. Hargajual, harga beli, dan foto nya. Di form nya bisa kita bisa tidak mengisi deskripsi dan foto nya karna di awal kita sudah tentukan di migrationn ya itu bahwa tabel nya itu nulable atau boleh kosong.
Dan hasil nya silahkan kalian tambahkan sendiri.
Membaut Fitur Edit Data
Mari kita mulai dengan membuat view terlebih dahulu, silakan buat file baru di dalam folder views/produk
dengan nama edit.blade.php
.
Kemudian di routes/web.php
silakan tambahkan 2 routes, yaitu untuk edit dan update.
route::get('/produk/edit{id}', [ProdukController::class, 'edit'])->name('index.edit');
route::put('/produk/update{id}', [ProdukController::class, 'update'])->name('index.update');
Maksud dari routes ini adalah nanti nya akan membawa sebuah id di dalam kurung kurawal itu adalah id yang di bawa oleh routes ini ke controller nya.
Oke silakan buka file controller nya kembali dan silakan tambahkan kode ini di dalam fungsi edit()
.
public function edit(Produk $id)
{
//
return view('produk.edit', compact('id'));
}
Sekarang kita buka file produk/index.blade.php
lalu tambahkan kode ini:
<a href="{{ route('index.edit', $k->id) }}" class="btn btn-sm btn-warning">edit</a>
Dan show data mungkin nanti kita lakukan atau bisa di lakukan sendiri logikanya sama dengan edit.
Oke agar tidak bolak-balik silakan buka main.blade.php
yang ada di folder views/layouts/
.
Silakan tambahkan routes index.index
nya agar jika kita klik dashboard akan langsung di arahkan ke halaman dashboard-nya. Ubah nya di tag <a>
ya.
Oke sekarang silakan tambah kode ini.
@extends('layoutes.main')
@section('content')
<div class="container-fluid px-4">
<h1 class="mt-4">Dashboard</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item active">Dashboard</li>
</ol>
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-table me-1"></i>
Edit data
</div>
<div class="card-body">
<form action="{{ route('index.update', $id->id) }}" method="POST" enctype="multipart/form-data">
@csrf
@method('put')
<div class="form-group">
<label for="nama">Nama:</label>
<input type="text" class="form-control @error('nama') is-invalid @enderror" id="nama" name="nama" value="{{ $id->nama }}">
@error('nama')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="form-group">
<label for="jenis">Jenis:</label>
<input type="text" class="form-control @error('jenis') is-invalid @enderror" id="jenis" name="jenis" value="{{ $id->jenis }}">
@error('jenis')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="form-group">
<label for="harga_jual">Harga Jual:</label>
<input type="text" class="form-control @error('harga_jual') is-invalid @enderror" id="harga_jual" name="harga_jual" value="{{ $id->harga_jual }}">
@error('harga_jual')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="form-group">
<label for="harga_beli">Harga Beli:</label>
<input type="text" class="form-control @error('harga_beli') is-invalid @enderror" id="harga_beli" name="harga_beli" value="{{ $id->harga_beli }}">
@error('harga_beli')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="form-group">
<label for="deskripsi">Deskripsi:</label>
<textarea class="form-control" id="deskripsi" name="deskripsi">{{ $id->id }}</textarea>
</div>
<div class="form-group">
<label for="foto">Foto Produk:</label>
<input type="file" class="form-control" id="foto" name="foto">
{{-- @if(!empty($id->foto))
<img src="{{url('image')}}/{{$id->foto}}" alt=""class="rounded" style="width: 100%; max-width: 100px; height: auto;">
@endif --}}
@if(isset($id->foto) && !empty($id->foto))
<img src="{{ url('image/' . $id->foto) }}" alt="Foto Produk" class="rounded" style="width: 100%; max-width: 100px; height: auto;">
@else
<img src="{{ url('image/nophoto.jpg') }}" alt="No Foto" class="rounded" style="width: 100%; max-width: 100px; height: auto;">
@endif
</div>
<button type="submit" class="btn btn-primary mt-4">Submit</button>
</form>
</div>
</div>
</div>
@endsection
Di sini kita mengambil id dari id yang di bawa oleh routes ke controller dan kemudian di controller nya kita compact id nya dan kemudian di teruskan ke view dan kemudian di tampilkan.
Oke kembali ke browser nya silakan pilih data mana yang ingin di edit.
Maka hasil nya:
Ini baru view form edit saja ya, kita belum membuat aksi atau fungsi untuk update data.
Mari kita buat!
Silakan buka ProdukController
lalu ubah kode di bagian fungsi update()
menjadi seperti ini:
public function update(Request $request, string $id)
{
// validasi data
$request->validate([
'nama' => 'required|max:45',
'jenis' => 'required|max:45',
'harga_jual' => 'required|numeric',
'harga_beli' => 'required|numeric',
'foto' => 'nullable|image|mimes:jpg,png,jpeg,gif,svg|max:2048',
],
[
'nama.required' => 'Nama wajib diisi',
'nama.max' => 'Nama maksimal 45 karakter',
'jenis.required' => 'jenis wajib diisi',
'jenis.max' => 'jenis maksimal 45 karakter',
'foto.max' => 'Foto maksimal 2 MB',
'foto.mimes' => 'File ekstensi hanya bisa jpg,png,jpeg,gif, svg',
'foto.image' => 'File harus berbentuk image'
]);
//foto lama
$fotoLama = DB::table('produks')->select('foto')->where('id',$id)->get();
foreach($fotoLama as $f1){
$fotoLama = $f1->foto;
}
//jika foto sudah ada yang terupload
if(!empty($request->foto)){
//maka proses selanjutnya
if(!empty($fotoLama->foto)) unlink(public_path('image'.$fotoLama->foto));
//proses ganti foto
$fileName = 'foto-'.$request->id.'.'.$request->foto->extension();
//setelah tau fotonya sudah masuk maka tempatkan ke public
$request->foto->move(public_path('image'), $fileName);
} else{
$fileName = $fotoLama;
}
//update data produk
DB::table('produks')->where('id',$id)->update([
'nama'=>$request->nama,
'jenis'=>$request->jenis,
'harga_jual'=>$request->harga_jual,
'harga_beli'=>$request->harga_beli,
'deskripsi' => $request->deskripsi,
'foto'=>$fileName,
]);
return redirect()->route('index.index');
}
Menghapus Data
Untuk menghapus data silahkan buka view index.blade.php
, kemudian tambahkan link untuk hapus data pada tiap item produk.
<button type="button" class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#exampleModal{{$k->id}}">
Hapus
</button>
<!-- Modal -->
<div class="modal fade" id="exampleModal{{$k->id}}" tabindex="-1" aria-labelledby="exampleModalLabel"
aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="exampleModalLabel">Hapus Produk</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Apakah anda yakin akan menghapus data {{$k->nama}}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<form action="{{ route('index.destroy', $k->id) }}" method="POST" style="display:inline;">
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger">Delete</button>
</form>
</div>
</div>
</div>
</div>
Di dalam form-nya kita perlu memberikan methode dan @csrf
dikarenakan
agar datanya bisa dihapus.
Kemudian di routes-nya kita bikin juga untuk routes hapus data nya. Disini menggunakan method delete dan membawa id dari view nya dan kemudian dibawa ke controller nya.
route::delete('/produk/delete{id}', [ProdukController::class, 'destroy'])->name('index.destroy');
Di controller ProdukController
pada fungsi destroy()
isi dengan kode ini.
public function destroy(Produk $id)
{
$id->delete();
return redirect()->route('index.index')
->with('success','Data berhasil di hapus' );
}
Finish selamat mencoba.
Apa Selanjutnya?
Terimakasih sudah mengikuti tutorial ini sampai akhir. Selanjutnya, kamu bisa menambahkan beberapa fitur seperti pencarian, sorting, dan lain sebagainya.
Jika ada pertanyaan, silahkan sampaikan di komentar.