- Part 1: Setup & Menampilkan Data
- Part 2: CRUD (Tambah, Edit, Hapus) (sedang dibaca)
- Part 3: Pencarian, Filter & Pagination
- Part 4: Login & Autentikasi
Pada Part 1, kita sudah membangun fondasi aplikasi To-Do List dan menampilkan daftar tugas. Sekarang di Part 2 kita lengkapi menjadi aplikasi CRUD penuh: menambah, mengedit, dan menghapus tugas, lengkap dengan validasi form dan notifikasi.

Empat Operasi CRUD
CRUD adalah Create (tambah), Read (tampil, sudah dibuat di Part 1), Update (edit), dan Delete (hapus) — empat operasi dasar yang menjadi inti hampir semua aplikasi.
Karena di Part 1 kita sudah memakai Route::resource, seluruh route CRUD (index, create, store, edit, update, destroy) sudah otomatis tersedia. Kita tinggal mengisi metode controllernya.
Menambahkan Tombol Aksi di Daftar
Perbarui resources/views/tugas/index.blade.php, tambahkan tombol Tambah dan kolom Aksi:
@extends('layouts.app')
@section('konten')
<h2>Daftar Tugas</h2>
<a href="{{ route('tugas.create') }}" class="tombol">+ Tambah Tugas</a>
@if (session('sukses'))
<div class="kotak-sukses">{{ session('sukses') }}</div>
@endif
<table border="1" cellpadding="8" cellspacing="0">
<thead>
<tr><th>Judul</th><th>Prioritas</th><th>Status</th><th>Deadline</th><th>Aksi</th></tr>
</thead>
<tbody>
@foreach ($tugas as $t)
<tr>
<td>{{ $t->judul }}</td>
<td>{{ ucfirst($t->prioritas) }}</td>
<td>{{ ucfirst($t->status) }}</td>
<td>{{ $t->deadline }}</td>
<td>
<a href="{{ route('tugas.edit', $t->id) }}">Edit</a>
<form action="{{ route('tugas.destroy', $t->id) }}" method="post" style="display:inline"
onsubmit="return confirm('Yakin hapus tugas ini?')">
@csrf
@method('DELETE')
<button type="submit">Hapus</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
@endsection
Perhatikan tombol Hapus dibungkus <form> dengan @method('DELETE') — ini cara Laravel mengirim request DELETE lewat form HTML biasa. Directive @csrf menyisipkan token keamanan wajib.
Membuat Form Tambah dan Edit
Kita rancang satu view form yang dipakai bersama. Buat resources/views/tugas/form.blade.php:
@extends('layouts.app')
@section('konten')
<h2>{{ isset($tugas) ? 'Edit Tugas' : 'Tambah Tugas' }}</h2>
@if ($errors->any())
<div class="kotak-error">
<ul>
@foreach ($errors->all() as $e)
<li>{{ $e }}</li>
@endforeach
</ul>
</div>
@endif
<form action="{{ isset($tugas) ? route('tugas.update', $tugas->id) : route('tugas.store') }}" method="post">
@csrf
@isset($tugas) @method('PUT') @endisset
<label>Judul</label>
<input type="text" name="judul" value="{{ old('judul', $tugas->judul ?? '') }}">
<label>Deskripsi</label>
<textarea name="deskripsi">{{ old('deskripsi', $tugas->deskripsi ?? '') }}</textarea>
<label>Prioritas</label>
<select name="prioritas">
@foreach (['rendah','sedang','tinggi'] as $p)
<option value="{{ $p }}" @selected(old('prioritas', $tugas->prioritas ?? '') == $p)>{{ ucfirst($p) }}</option>
@endforeach
</select>
<label>Status</label>
<select name="status">
@foreach (['belum','proses','selesai'] as $s)
<option value="{{ $s }}" @selected(old('status', $tugas->status ?? '') == $s)>{{ ucfirst($s) }}</option>
@endforeach
</select>
<label>Deadline</label>
<input type="date" name="deadline" value="{{ old('deadline', $tugas->deadline ?? '') }}">
<button type="submit" class="tombol">Simpan</button>
</form>
@endsection
Fungsi old() mengembalikan input sebelumnya bila validasi gagal, atau nilai data tugas saat mode edit. Directive @selected memudahkan menandai opsi yang aktif.

Metode create() dan store()
Lengkapi controller. Metode create() menampilkan form kosong, store() memvalidasi lalu menyimpan:
public function create()
{
return view('tugas.form');
}
public function store(Request $request)
{
$data = $request->validate([
'judul' => 'required|max:150',
'prioritas' => 'required|in:rendah,sedang,tinggi',
'status' => 'required|in:belum,proses,selesai',
'deadline' => 'nullable|date',
'deskripsi' => 'nullable',
]);
Tugas::create($data);
return redirect()->route('tugas.index')->with('sukses', 'Tugas baru berhasil ditambahkan.');
}
Metode validate() otomatis memeriksa aturan. Jika gagal, Laravel mengembalikan pengguna ke form dengan pesan error dan input lama tanpa kode tambahan. Jika lolos, data tervalidasi disimpan lewat Tugas::create().
Metode edit() dan update()
public function edit(Tugas $tugas)
{
return view('tugas.form', compact('tugas'));
}
public function update(Request $request, Tugas $tugas)
{
$data = $request->validate([
'judul' => 'required|max:150',
'prioritas' => 'required|in:rendah,sedang,tinggi',
'status' => 'required|in:belum,proses,selesai',
'deadline' => 'nullable|date',
'deskripsi' => 'nullable',
]);
$tugas->update($data);
return redirect()->route('tugas.index')->with('sukses', 'Tugas berhasil diperbarui.');
}
Perhatikan parameter Tugas $tugas — ini fitur Route Model Binding Laravel yang otomatis mencari data tugas berdasarkan ID di URL. Jika tidak ditemukan, Laravel otomatis menampilkan halaman 404.
Metode destroy()
public function destroy(Tugas $tugas)
{
$tugas->delete();
return redirect()->route('tugas.index')->with('sukses', 'Tugas berhasil dihapus.');
}

Menampilkan Notifikasi (Flash Message)
Kita sudah mengirim pesan lewat ->with('sukses', ...) dan menampilkannya di view dengan @if (session('sukses')). Tambahkan CSS agar menarik:
.kotak-sukses {
background-color: #dcfce7;
border: 1px solid #16a34a;
color: #166534;
padding: 12px 16px;
border-radius: 6px;
margin-bottom: 16px;
}
.kotak-error {
background-color: #fee2e2;
border: 1px solid #dc2626;
color: #991b1b;
padding: 12px 16px;
border-radius: 6px;
margin-bottom: 16px;
}
Penutup
Aplikasi To-Do List Anda kini sudah bisa menambah, menampilkan, mengedit, dan menghapus tugas — CRUD penuh dengan validasi otomatis dan notifikasi yang ramah. Perhatikan betapa ringkasnya kode Laravel berkat Eloquent, validasi bawaan, dan Route Model Binding.
Ketika tugas bertambah banyak, kita butuh pencarian, filter, dan pagination. Semua itu kita bangun di Part 3. Sampai jumpa!
Referensi: untuk pendalaman lebih lanjut, kunjungi dokumentasi resmi Laravel.

