Cara membuat kolom upload image laravel #5

Cara membuat kolom upload image laravel 11


Pada Artikel kali ini, saya akan memberikan tutorial cara membuat kolom upload image laravel. Tanpa basa basi, langsung saja ke tutorialnya.

Buka file migration kalian yang bernama create_projek_table (file migration di artikel sebelumnya) dan ketikkan skrip berikut:


<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('projek', function (Blueprint $table) {
            $table->id();
            $table->string('foto')->nullable();
            $table->string('nama');
            $table->integer('kelas');
            $table->string('jurusan');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('projek');
    }
};

Bisa dilihat bahwa saya menambahkan tabel baru untuk foto. Setelah itu jangan lupa save. Kemudian buka file model kalian yang bernama projek.php dan tambahkan baris skrip baru seperti berikut:


<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Projek extends Model
{
    use HasFactory;

    protected $table = 'projek';
    protected $fillable = [
        'foto',
        'nama',
        'kelas',
        'jurusan',
    ];
}

Setelah itu jangan lupa di save. Kemudian buka terminal visual code studio atau cmd kalian. Masuk ke direktori projek-laravel dan ketikkan "php artisan migrate:refresh" maka laravel akan menambahkan kolom baru untuk foto di databasenya.

Harap diperhatikan bahwa menggunakan "php artisan migrate:refresh" akan menghapus seluruh data yang ada di dalam database kalian.

Jika sudah, buka file ProjekController.php kalian dan tambahkan skrip baru seperti berikut:


<?php

namespace App\Http\Controllers;

use App\Models\Projek;
use Illuminate\View\View;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Storage;

class ProjekController extends Controller
{
    public function index(Request $request): View
    {
        $search = $request->input('search');
        $query = Projek::query();

        if ($search) {
            $query->where('nama', 'LIKE', "%{$search}%")
                ->orWhere('kelas', 'LIKE', "%{$search}%")
                ->orWhere('jurusan', 'LIKE', "%{$search}%");
        }

        $projek = $query->orderBy('nama', 'asc')->paginate(10);
        if ($projek->isEmpty() && $search) {
            session()->flash('error', 'Data tidak ditemukan.');
        }

        if ($request->fullUrl() != session('previous_url')) {
            session(['previous_url' => url()->previous()]);
        }

        return view('projek.index', compact('projek'));
    }

    public function create(): View
    {
        return view('projek.create');
    }

    public function store(Request $request): RedirectResponse
    {
        $request->validate([
            'foto'         => 'required|image|mimes:jpeg,jpg,png|max:2048',
            'nama'         => 'required|string|max:255',
            'kelas'        => 'required|numeric',
            'jurusan'      => 'required|string|max:255'
        ]);

        $image = $request->file('foto');
        $image->storeAs('public/images/projek', $image->hashName());

        Projek::create([
            'foto'          => $image->hashName(),
            'nama'          => $request->nama,
            'kelas'         => $request->kelas,
            'jurusan'       => $request->jurusan,
        ]);

        return redirect()->route('projek.index')->with(['success' => 'Data Berhasil Disimpan!']);
    }

    public function edit(string $id): View
    {
        $projek = Projek::findOrFail($id);

        return view('projek.edit', compact('projek'));
    }

    public function update(Request $request, $id): RedirectResponse
    {
        $request->validate([
            'foto'         => 'image|mimes:jpeg,jpg,png|max:2048',
            'nama'         => 'required|string|max:255',
            'kelas'        => 'required|numeric',
            'jurusan'      => 'required|string|max:255'
        ]);

        $projek = Projek::findOrFail($id);

        if ($request->hasFile('foto')) {
            $image = $request->file('foto');
            $image->storeAs('public/images/projek', $image->hashName());

            Storage::delete('public/images/projek/' . $projek->foto);

            $projek->update([
                'foto'          => $image->hashName(),
                'nama'          => $request->nama,
                'kelas'         => $request->kelas,
                'jurusan'       => $request->jurusan,
            ]);
        } else {
            $projek->update([
                'nama'          => $request->nama,
                'kelas'         => $request->kelas,
                'jurusan'       => $request->jurusan,
            ]);
        }

        return redirect()->route('projek.index')->with(['success' => 'Data Berhasil Diubah!']);
    }

    public function destroy(string $id): RedirectResponse
    {
        $projek = Projek::findOrFail($id);

        Storage::delete('public/images/projek/' . $projek->foto);

        $projek->delete();

        return redirect()->route('projek.index')->with(['success' => 'Data Berhasil Dihapus!']);
    }
}

Pada bagian upload dan penyimpanan foto dalam skrip ini, file foto divalidasi agar hanya menerima gambar bertipe jpeg, jpg, dan png dengan ukuran maksimal 2 MB. Kalian juga bisa menambahkan ekstensi gambar lainnya seperti webp, svg, dll.

Foto kemudian diambil dari request menggunakan $request->file('foto') dan disimpan di folder public/images/projek dengan nama yang di-hash untuk menghindari duplikasi nama file. Saat data diperbarui, jika ada foto baru yang diunggah, foto lama akan dihapus menggunakan Storage::delete() untuk mencegah penumpukan file yang tidak terpakai. Saat data dihapus, foto terkait juga akan dihapus dari penyimpanan, menjaga agar tidak ada file sisa yang tertinggal.

Jika sudah jangan lupa disave. Setelah itu buka file index.blade.php kalian dan ketikkan skrip baru seperti berikut.


<!DOCTYPE html>
<html>
<head>
    <title>Daftar Data Siswa</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body class="bg-light">
    <div class="container mt-5">
        <h1 class="mb-4">Daftar Data Siswa</h1>
        <form action="{{ route('projek.index') }}" method="GET" class="d-flex mb-3">
            <input class="form-control me-2" type="search" name="search" placeholder="Cari Berdasarkan Nama..." aria-label="Search">
            <button class="btn btn-outline-success" type="submit">Search</button>
        </form>
        <a href="{{ route('projek.create') }}" class="btn btn-primary mb-3">Tambah Data Siswa</a>
        <table class="table table-striped table-bordered">
            <thead class="table-dark">
                <tr>
                    <th>No</th>
                    <th>Foto</th>
                    <th>Nama</th>
                    <th>Kelas</th>
                    <th>Jurusan</th>
                    <th>Action</th>
                </tr>
            </thead>
            <tbody>
                @foreach ($projek as $index => $p)
                <tr>
                    <td>{{ $index + 1 + ($projek->currentPage() - 1) * $projek->perPage() }}</td>
                    <td class="text-center">
                        <img src="{{ asset('storage/images/projek/' . $p->foto) }}" class="rounded" style="width: 150px">
                    </td>
                    <td>{{ $p->nama }}</td>
                    <td>{{ $p->kelas }}</td>
                    <td>{{ $p->jurusan }}</td>
                    <td>
                        <form onsubmit="return confirm('Apakah Anda yakin ingin menghapus data ini?');" 
                              action="{{ route('projek.destroy', $p->id) }}" method="POST">
                            <a href="{{ route('projek.edit', $p->id) }}" class="btn btn-warning btn-sm">Edit</a>
                            @csrf
                            @method('DELETE')
                            <button type="submit" class="btn btn-danger btn-sm">Delete</button>
                        </form>
                    </td>
                </tr>
                @endforeach
            </tbody>
        </table>
        <nav aria-label="Page navigation example">
            <ul class="pagination justify-content-center">
                <li class="page-item {{ $projek->onFirstPage() ? 'disabled' : '' }}">
                    <a class="page-link" href="{{ $projek->previousPageUrl() }}">Sebelumnya</a>
                </li>

                <li class="page-item {{ $projek->hasMorePages() ? '' : 'disabled' }}">
                    <a class="page-link" href="{{ $projek->nextPageUrl() }}">Berikutnya</a>
                </li>
            </ul>
        </nav>
        <div class="text-center">
            <span>Halaman {{ $projek->currentPage() }} dari {{ $projek->lastPage() }}</span>
        </div>
    </div>
</body>
</html>

Bisa kalian lihat bahwa terdapat elemen bootstrap di skrip tersebut. Jika kalian penasaran, kalian bisa cek di salah satu artikel saya mengenai bootstrap. Setelah di save, buka file create.blade.php dan ketikkan skrip baru seperti berikut:


<!DOCTYPE html>
<html>
<head>
    <title>Tambah Data Siswa</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body class="bg-light">
    <div class="container mt-5">
        <h1 class="mb-4">Tambah Data Siswa</h1>
        <form action="{{ route('projek.store') }}" method="POST" class="bg-white p-4 shadow-sm rounded" enctype="multipart/form-data"> <!-- Enctype ditambahkan -->
            @csrf

            <div class="mb-3">
                <label for="foto" class="font-weight-bold">Foto</label>
                <input type="file" class="form-control @error('foto') is-invalid @enderror" name="foto" required>
                @error('foto')
                    <div class="alert alert-danger mt-2">
                        {{ $message }}
                    </div>
                @enderror
            </div>

            <div class="mb-3">
                <label for="nama" class="form-label">Nama:</label>
                <input type="text" class="form-control" id="nama" name="nama" required>
            </div>

            <div class="mb-3">
                <label for="kelas" class="form-label">Kelas:</label>
                <input type="text" class="form-control" id="kelas" name="kelas" required>
            </div>

            <div class="mb-3">
                <label for="jurusan" class="form-label">Jurusan:</label>
                <input type="text" class="form-control" id="jurusan" name="jurusan" required>
            </div>

            <div class="d-flex justify-content-between">
                <button type="submit" class="btn btn-success">Simpan</button>
                <a href="{{ route('projek.index') }}" class="btn btn-secondary">Kembali</a>
            </div>
        </form>
    </div>
</body>
</html>

Jika sudah jangan lupa di save. Setelah itu buka file edit.blade.php dan ketikkan skrip seperti berikut:


<!DOCTYPE html>
<html>
<head>
    <title>Edit Data Siswa</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body class="bg-light">
    <div class="container mt-5">
        <h1 class="mb-4">Edit Data Siswa</h1>
        
        <form action="{{ route('projek.update', $projek->id) }}" method="POST" class="bg-white p-4 shadow-sm rounded" enctype="multipart/form-data">
            @csrf
            @method('PUT')

            @if($projek->foto)
            <div class="mb-3">
                <label for="foto" class="form-label">Gambar Saat Ini:</label>
                <div>
                    <img src="{{ asset('storage/images/projek/' . $projek->foto) }}" alt="Foto Siswa" class="img-thumbnail" style="max-width: 150px;">
                </div>
            </div>
            @endif

            <div class="mb-3">
                <label for="foto" class="font-weight-bold">Foto</label>
                <input type="file" class="form-control @error('foto') is-invalid @enderror" name="foto">
                @error('foto')
                    <div class="alert alert-danger mt-2">
                        {{ $message }}
                    </div>
                @enderror
            </div>

            <div class="mb-3">
                <label for="nama" class="form-label">Nama:</label>
                <input type="text" class="form-control" id="nama" name="nama" value="{{ $projek->nama }}" required>
            </div>

            <div class="mb-3">
                <label for="kelas" class="form-label">Kelas:</label>
                <input type="text" class="form-control" id="kelas" name="kelas" value="{{ $projek->kelas }}" required>
            </div>

            <div class="mb-3">
                <label for="jurusan" class="form-label">Jurusan:</label>
                <input type="text" class="form-control" id="jurusan" name="jurusan" value="{{ $projek->jurusan }}" required>
            </div>

            <div class="d-flex justify-content-between">
                <button type="submit" class="btn btn-primary">Update</button>
                <a href="{{ route('projek.index') }}" class="btn btn-secondary">Kembali</a>
            </div>
        </form>
    </div>
</body>
</html>

Setelah itu jangan lupa di save. Setelah mengubah ketiga skrip blade tersebut, maka kalian bisa menambahkan foto pada database kalian. Untuk mengeceknya, buka localhost:8000/projek kalian (seperti biasa, jangan lupa menyalakan server laravel dan xampp kalian). Bisa dilihat pada gambar di bawah sudah ada kolom foto serta upload foto.

Bisa dilihat gambar di bawah, terdapat tampilan kolom foto.

Bisa dilihat gambar dibawa juga terdapat kolom untuk upload image.

Sedangkan untuk gambar dibawah, terdapat kolom untuk edit foto serta di tampilkan nya foto yang hendak ingin diedit.

Seperti biasa saya akan menaruh semua skrip saya di github sebagai bahan pembelajaran lebih lanjut.

Terima kasih...

Posting Komentar