Tutorial CRUD Lanjutan Upload Gambar dan Validasi Form pada CodeIgniter 4

Hai, Sobat Jagoan! Melanjutkan seri tutorial CRUD sebelumnya, yaitu fitur tambah, tampil, edit, dan hapus data dari database, pada artikel kali ini akan memperkaya fungsionalitas aplikasi dengan menambahkan fitur upload gambar, validasi form, dan penggunaan flash messages. Simak di bawah ini, Sob!

Fitur Validasi Form

Membuat validasi form bertujuan agar data yang dikirim pengguna sesuai dengan format dan aturan yang diiginkan, misalnya memastikan kolom nama barang tidak kosong, harga harus berupa angka, dan gambar memiliki ekstensi yang sesuai.

Fitur ini akan memeriksa input pengguna sebelum disimpan ke database apakah sudah sesuai dengan aturan validasi dan membantu agar data tetap konsisten.

Fitur Flash Message

Penggunaan flash message untuk memberikan umpan balik langsung ke pengguna, seperti pesan sukses atau peringatan, sehingga proses input lebih responsif.

Bagian 1: Menambahkan Fitur Upload Gambar

Fitur upload gambar bisa membuat data barang kamu menjadi lebih representatif, informatif, dan menarik. Kali ini akan memodifikasi halaman view dan form supaya bisa menyimpan gambar, menampilkan gambar barang, dan menyimpan nama file di database (bukan file-nya langsung).

STEP 1: Jalankan perintah di bawah ini di phpMyAdmin untuk menambahkan kolom gambar di tabel barang.

				
					USE db_toko_barang;
ALTER TABLE barang ADD gambar VARCHAR(255) DEFAULT NULL;

				
			
1-tambah-kolom-gambar

STEP 2: Setelah itu, modifikasi model BarangModel.php di app/Models/ dengan menambahkan field gambar seperti berikut.

				
					protected $allowedFields = ['nama_barang', 'harga', 'stok', 'gambar'];
				
			

STEP 3: Setelah model disesuaikan dengan database, buka file view create.php di app/Views/barang/ lalu tambahkan input file gambar.

  • Modifikasi tag form seperti berikut supaya form bisa menerima input berupa file juga.
				
					<form action="<?= base_url('/barang/store') ?>" method="post" enctype="multipart/form-data">
				
			
  • Lalu, tambahkan input gambar di bawah input stok
				
					<div class="mb-3">
    <label for="gambar" class="form-label">Upload Gambar</label>
    <input type="file" name="gambar" class="form-control">
</div>

				
			
2-edit-view-create

STEP 4: Selanjutnya, ubah method store() di controller Barang.php agar bisa untuk memproses upload gambar.

				
					public function store()
{
    $model = new BarangModel();

    // Ambil file
    $fileGambar = $this->request->getFile('gambar');
    $namaGambar = '';

    if ($fileGambar && $fileGambar->isValid() && !$fileGambar->hasMoved()) {
        $namaGambar = $fileGambar->getRandomName(); // nama acak
        $fileGambar->move('uploads/', $namaGambar); // simpan ke folder public/uploads
    }

    // Data yang disimpan
    $data = [
        'nama_barang' => $this->request->getPost('nama_barang'),
        'harga'       => $this->request->getPost('harga'),
        'stok'        => $this->request->getPost('stok'),
        'gambar'      => $namaGambar
    ];

    $model->insert($data);
    return redirect()->to('/barang');
}

				
			

STEP 5: Kemudian, di app/Views/barang/index.php tambahkan kolom “Gambar” di <thead> untuk menampilkan gambar di halaman index.

  • Tambahkan header tabel:

<th>Gambar</th>

  • Dan tambahkan di baris data untuk menampilkan gambar:

<td>
<?php if ($item[‘gambar’]) : ?>
<img src=”<?= base_url(‘uploads/’ . $item[‘gambar’]) ?>” alt=”Gambar Barang” width=”60″>
<?php else : ?>
<span class=”text-muted”>-</span>
<?php endif; ?>
</td>

3-edit-view-index

STEP 6: Kalau kamu akses http://localhost:8080/barang sekarang tampilannya seperti gambar di bawah ini.

4-buat-form-gambar-di-code-igniter-4

Cobalah menambahkan data baru dan menginnputkan gambar berformat .jpg atau .png lalu klik Simpan maka hasilnya seperti berikut.

5-buat-form-upload-gambar-code-igniter-4

Bagain 2: Menambahkan Validasi dan Flash Message (Berhasil atau Gagal)

Ketika kamu menambahkan data baru lalu setelah mengkilk tombol Simpan, kamu akan langsung diarahkan ke halaman index.php. Nah, transisi ini bisa kamu poles supaya jadi lebih menarik dengan menambahkan validasi yang akan menampilkan error kalau input pengguna tidak sesuai dan menambahkan flash message sukses bila pengguna berhasil menambahkan data.

STEP 1: Pertama, update controller Barang.php bagian store() method dengan menambahkan logika validasi dan flash data seperti berikut.

				
					public function store()
{
    $validation = \Config\Services::validation();

    $rules = [
        'nama_barang' => 'required',
        'harga'       => 'required|numeric',
        'stok'        => 'required|integer',
        'gambar'      => 'permit_empty|is_image[gambar]|mime_in[gambar,image/jpg,image/jpeg,image/png]'
    ];

    if (!$this->validate($rules)) {
        return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
    }

    $fileGambar = $this->request->getFile('gambar');
    $namaGambar = '';

    if ($fileGambar && $fileGambar->isValid() && !$fileGambar->hasMoved()) {
        $namaGambar = $fileGambar->getRandomName();
        $fileGambar->move('uploads/', $namaGambar);
    }

    $model = new BarangModel();
    $model->insert([
        'nama_barang' => $this->request->getPost('nama_barang'),
        'harga' => $this->request->getPost('harga'),
        'stok' => $this->request->getPost('stok'),
        'gambar' => $namaGambar
    ]);

    session()->setFlashdata('success', 'Data barang berhasil ditambahkan.');
    return redirect()->to('/barang');
}

				
			

STEP 2: Kemudian, buka fiile view create.php dan edit isinya dengan menambahkan kode di bawah ini untuk menampilkan error validasi apabila data yang dimasukkan tidak sesuai.

				
					<?php if (session()->getFlashdata('errors')): ?>
<div class="alert alert-danger">
    <ul>
        <?php foreach (session()->getFlashdata('errors') as $error): ?>
            <li><?= esc($error) ?></li>
        <?php endforeach; ?>
    </ul>
</div>
<?php endif; ?>

				
			
6-tambah-flash-data-di-view-create

STEP 3: Tambahkan juga kode di bawah ini, di dalam view index.php untuk menampilkan flash message apabila data berhasil ditambahkan.

				
					<?php if (session()->getFlashdata('success')): ?>
<div class="alert alert-success">
    <?= session()->getFlashdata('success') ?>
</div>
<?php endif; ?>

				
			
7-tambah-flash-data-di-view-index

STEP 4: Setelah memodifikasi view index.php dan create.php, berikutnya modifikasi bagian yang memproses edit data. Pada file view edit.php, tambahkan input file gambar baru dan tampilkan gambar lama supaya memudahkan pengguna ketika akan mengedit data.

<img src=”<?= base_url(‘uploads/’ . $barang[‘gambar’]) ?>” alt=”” width=”100″ class=”mb-2″>

 

<div class=”mb-3″>

    <label for=”gambar” class=”form-label”>Upload Gambar Baru (Opsional)</label>

    <input type=”file” name=”gambar” class=”form-control”>

</div>

Ubah form edit dengan menambahkan atribut untuk menangani upload file.

<form action=”<?= base_url(‘/barang/update/’ . $barang[‘id’]) ?>” method=”post” enctype=”multipart/form-data”>

8-tambah-input-gambar-di-view-edit

STEP 5: Berikutnya, update controller update() di Barang.php untuk menambahkan logika proses update data (termasuk data gambar), validasi dan flash message.

				
					public function update($id)
{
    $model = new BarangModel();
    $barangLama = $model->find($id);

    $validation = \Config\Services::validation();
    $rules = [
        'nama_barang' => 'required',
        'harga' => 'required|numeric',
        'stok' => 'required|integer',
        'gambar' => 'permit_empty|is_image[gambar]|mime_in[gambar,image/jpg,image/jpeg,image/png]'
    ];

    if (!$this->validate($rules)) {
        return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
    }

    $fileGambar = $this->request->getFile('gambar');
    $namaGambar = $barangLama['gambar']; // pakai lama dulu

    if ($fileGambar && $fileGambar->isValid() && !$fileGambar->hasMoved()) {
        // Hapus gambar lama jika ada
        if ($namaGambar && file_exists('uploads/' . $namaGambar)) {
            unlink('uploads/' . $namaGambar);
        }

        $namaGambar = $fileGambar->getRandomName();
        $fileGambar->move('uploads/', $namaGambar);
    }

    $model->update($id, [
        'nama_barang' => $this->request->getPost('nama_barang'),
        'harga' => $this->request->getPost('harga'),
        'stok' => $this->request->getPost('stok'),
        'gambar' => $namaGambar
    ]);

    session()->setFlashdata('success', 'Data barang berhasil diperbarui.');
    return redirect()->to('/barang');
}

				
			

STEP 6: Terakhir, modifikasi method delete() di dalam controller menjadi seperti kode di bawah ini agar ketika data dihapus gambar juga ikut dihapus.

				
					public function delete($id)
{
    $model = new BarangModel();
    $barang = $model->find($id);

    if (!$barang) {
        return redirect()->to('/barang');
    }

    // Hapus gambar dari folder
    if ($barang['gambar'] && file_exists('uploads/' . $barang['gambar'])) {
        unlink('uploads/' . $barang['gambar']);
    }

    $model->delete($id);

    session()->setFlashdata('success', 'Data barang berhasil dihapus.');
    return redirect()->to('/barang');
}

				
			

Sehingga controller Barang.php keseluruhan menjadi seperti berikut.

				
					<?php

namespace App\Controllers;

use App\Models\BarangModel;

class Barang extends BaseController
{
    public function index()
    {
        $model = new BarangModel();

        // Ambil semua data dari tabel barang
        $data['barang'] = $model->findAll();

        // Kirim data ke view barang/index
        return view('barang/index', $data);
    }

    // Tampilkan form input
    public function create()
    {
        return view('barang/create');
    }

    // Simpan data baru
    public function store()
    {
        $validation = \Config\Services::validation();

        $rules = [
            'nama_barang' => 'required',
            'harga'       => 'required|numeric',
            'stok'        => 'required|integer',
            'gambar'      => 'permit_empty|is_image[gambar]|mime_in[gambar,image/jpg,image/jpeg,image/png]'
        ];

        if (!$this->validate($rules)) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $fileGambar = $this->request->getFile('gambar');
        $namaGambar = '';

        if ($fileGambar && $fileGambar->isValid() && !$fileGambar->hasMoved()) {
            $namaGambar = $fileGambar->getRandomName();
            $fileGambar->move('uploads/', $namaGambar);
        }

        $model = new BarangModel();
        $model->insert([
            'nama_barang' => $this->request->getPost('nama_barang'),
            'harga'       => $this->request->getPost('harga'),
            'stok'        => $this->request->getPost('stok'),
            'gambar'      => $namaGambar
        ]);

        session()->setFlashdata('success', 'Data barang berhasil ditambahkan.');
        return redirect()->to('/barang');
    }

    // Tampilkan form edit
    public function edit($id)
    {
        $model = new BarangModel();
        $data['barang'] = $model->find($id);

        // Jika data tidak ditemukan, redirect kembali
        if (!$data['barang']) {
            return redirect()->to('/barang');
        }

        return view('barang/edit', $data);
    }

    public function update($id)
    {
        $model = new BarangModel();
        $barangLama = $model->find($id);

        $validation = \Config\Services::validation();
        $rules = [
            'nama_barang' => 'required',
            'harga'       => 'required|numeric',
            'stok'        => 'required|integer',
            'gambar'      => 'permit_empty|is_image[gambar]|mime_in[gambar,image/jpg,image/jpeg,image/png]'
        ];

        if (!$this->validate($rules)) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }

        $fileGambar = $this->request->getFile('gambar');
        $namaGambar = $barangLama['gambar']; // pakai gambar lama dulu

        if ($fileGambar && $fileGambar->isValid() && !$fileGambar->hasMoved()) {
            // Hapus gambar lama jika ada
            if ($namaGambar && file_exists('uploads/' . $namaGambar)) {
                unlink('uploads/' . $namaGambar);
            }

            $namaGambar = $fileGambar->getRandomName();
            $fileGambar->move('uploads/', $namaGambar);
        }

        $model->update($id, [
            'nama_barang' => $this->request->getPost('nama_barang'),
            'harga'       => $this->request->getPost('harga'),
            'stok'        => $this->request->getPost('stok'),
            'gambar'      => $namaGambar
        ]);

        session()->setFlashdata('success', 'Data barang berhasil diperbarui.');
        return redirect()->to('/barang');
    }

    // Hapus data
    public function delete($id)
    {
        $model = new BarangModel();
        $barang = $model->find($id);

        if (!$barang) {
            return redirect()->to('/barang');
        }

        // Hapus gambar dari folder
        if ($barang['gambar'] && file_exists('uploads/' . $barang['gambar'])) {
            unlink('uploads/' . $barang['gambar']);
        }

        $model->delete($id);

        session()->setFlashdata('success', 'Data barang berhasil dihapus.');
        return redirect()->to('/barang');
    }
}

				
			

STEP 6: Silahkan, coba akses http://localhost:8080/barang lalu demo dengan mencoba menambahkan data baru dengan gambar, edit data, lalu hapus data untuk memastikan fitur-fiturnya berjalan lancar. Cobalah juga untuk menginputkan data yang tidak valid pada form.

Simak terus tips-tips dari Jagoan Hosting melalui laman Pusat Tutorial Hostin dan Domain Jagoan Hosting. Kalau ada yang masih bikin bingung atau ada artikel yang belum tersedia, jangan ragu hubungi Tim Support Jagoan Hosting ya, Sob!

Related Posts
Cara Install CodeIgniter di Softaculous cPanel

Hai, Sobat Jagoan! Softaculous adalah fitur auto-installer yang biasanya tersedia di cPanel dan digunakan untuk memasang berbagai aplikasi web secara Read more

Cara Install CodeIgniter dengan Composer di cPanel Hosting

Hai, Sobat Jagoan! Saat kamu mengembangkan proyek CodeIgniter, menggunakan Composer adalah langkah terbaik. Selain mendapatkan versi resmi terbaru, kamu juga Read more

Clone Proyek CodeIgniter dari Remote Repository ke Hosting

Halo, Sobat! Remote repository adalah tempat penyimpanan proyek kamu di server Git yang bisa diakses dari mana saja melalui internet. Read more

Memahami Konsep Dasar CodeIgniter 4

Hai, Sobat Jagoan! Sebelum nyemplung lebih jauh dengan CodeIgniter versi 4, kamu perlu mengenal dan memahami konsep dasar CodeIgniter 4 Read more