Tutorial Membuat Load More on Scroll atau Infinite Scroll dengan Laravel Livewire

Tutorial Membuat Load More on Scroll atau Infinite Scroll dengan Laravel Livewire

Admin
Admin・ 2 Juni 2021
17 min read ・ 6289 views
Series: Laravel Livewire

Load More on Scroll Laravel Livewire- Pernahkah kamu melihat web-web besar media sosial seperti facebook, instagram atau twitter ? pernahkah kamu coba scroll ke bawah terus ? seperti tidak ada ujungnya ya ? Iya, karena begitu kita scroll terus ke bawah, konten-konten yang lainnya terus saja bermunculan. Inilah yang dinamakan load more on scroll atau infinite scroll, cara kerjanya hampir terlihat mirip dengan pagination, hanya saja user tidak perlu klik-klik nav-link di pagination untuk berpindah halaman.

Nah, pada kesempatan kali ini saya akan membagikan artikel tentang tutorial bagaimana cara membuat load more on scroll atau infinite scroll dengan laravel livewire. Hampir sama dengan beberapa artikel yang pernah saya bagikan, pada artikel ini kita akan mulai juga dari nol yaitu dengan install projek laravel terbaru.

Pendahuluan

Sekilas tentang gambaran projek latihan yang akan kita buat nantinya, kita akan coba membuat contoh website yang memuat konten seperti blog. Kemudian nantinya kita akan membuat data dummy posts dengan laravel factory. Setelah kita mempunyai data dummy posts, baru kita akan buat fitur load more on scroll atau infite scroll (gulir tak terbatas) dengan laravel livewire. Nanti kita akan coba tambahkan juga button "load more", jadi ketika kita klik button load more maka akan muncul lagi konten yang lainnya.

Yang Perlu Dipersiapkan

  1. Text Editor (Visual Studio Code atau yang lainnya)
  2. Local Server (Xampp atau yang lainnya)
  3. Browser (Chrome atau yang lainnya)
  4. Internet (Optional)

Ada 4 poin yang saya sarankan untuk bisa kita persiapkan dalam mengikuti artikel tutorial membuat load more on scroll atau infinite scroll ini.

Mulai Koding

Oke, setelah mengetahui apa itu load more on scroll atau infinite scroll dan juga sudah mempersiapkan untuk kebutuhan latihan ini, sekarang waktunya kita ke koding. Dan sebagai catatan, mungkin artikel tutorial membuat load more on scroll atau infinite scroll ini nantinya akan terlihat panjang, itu karena kita akan memulainya dari nol. Sebenarnya untuk membuat load more on scroll atau infinite scroll dengan laravel livewire cukup mudah dan cepat.

Install Laravel

composer create-project laravel/laravel livewire

Kita awali koding dengan install laravel terbaru (saat ini versi 8.46.0) via composer. Silahkan buka terminal, lalu jalankan perintah seperti di atas. Dengan perintah seperti di atas, saya akan membuat projek laravel dengan nama livewire, karena kedepannya saya ingin membuat artikel tentang livewire menggunakan projek laravel yang akan kita gunakan saat ini.

Menyiapkan View

Setelah install laravel sudah selesai, sekarang silahkan buka projek laravel di text editor kalian masing-masing. Pada langkah ini, kita akan menyiapkan view yaitu dengan memperbarui file welcome.blade.php

<!doctype html>
<html lang="en">
    <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- Bootstrap CSS -->
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
        <title>Laravel Multi Bahasa</title>
    </head>
    <body>
        <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
            <div class="container-fluid">
                <a class="navbar-brand" href="#">Bisabos.com</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                        <li class="nav-item">
                            <a class="nav-link active" aria-current="page" href="#">Home</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
        <div class="container">
            <div class="row pt-5">
                <div class="text-center pb-3">
                    <h1>Load More on Scroll / Infinite Scroll Laravel Livewire</h1>
                </div>
                <div class="card mb-2">
                    <div class="card-body">
                        <h5 class="card-title">Special title treatment</h5>
                        <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
                    </div>
                </div>
                <div class="card mb-2">
                    <div class="card-body">
                        <h5 class="card-title">Special title treatment</h5>
                        <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
                    </div>
                </div>
                <div class="card mb-2">
                    <div class="card-body">
                        <h5 class="card-title">Special title treatment</h5>
                        <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
                    </div>
                </div>
                <div class="card mb-2">
                    <div class="card-body">
                        <h5 class="card-title">Special title treatment</h5>
                        <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
                    </div>
                </div>
                <div class="card mb-2">
                    <div class="card-body">
                        <h5 class="card-title">Special title treatment</h5>
                        <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
                    </div>
                </div>
                <div class="card mb-2">
                    <div class="card-body">
                        <h5 class="card-title">Special title treatment</h5>
                        <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
                    </div>
                </div>
                <div class="card mb-2">
                    <div class="card-body">
                        <h5 class="card-title">Special title treatment</h5>
                        <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
                    </div>
                </div>
                <div class="card mb-2">
                    <div class="card-body">
                        <h5 class="card-title">Special title treatment</h5>
                        <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
                    </div>
                </div>
                <div class="card mb-2">
                    <div class="card-body">
                        <h5 class="card-title">Special title treatment</h5>
                        <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
                    </div>
                </div>
                <div class="card mb-2">
                    <div class="card-body">
                        <h5 class="card-title">Special title treatment</h5>
                        <p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
                    </div>
                </div>
            </div>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>
    </body>
</html>

Disini saya sudah siapkan starter template (menggunakan bootstrap 5) yang akan kita gunakan dalam latihan percobaan membuat load more on scroll atau infinite scroll pada artikel kali ini. Dengan kode di atas, kita sudah mempunyai tampilan statis dengan card sebagai konten dan dengan tampilan list. Silahkan copy kode di atas, lalu buka welcome.blade.php dan paste atau replace kode.

Buat Database

Untuk menampung data-data post nantinya, kita perlu membuat database baru. Dalam hal ini, saya akan membuat database baru di phpMyAdmin dengan nama database livewire dan jangan lupa juga untuk menyesuaikan nama database di DB_DATABASE file .env.

Buat Model & Migration Post

php artisan make:model Post -m

Selanjutnya silahkan jalankan perintah seperti di atas pada terminal kalian. Dengan perintah tersebut, kita akan membuat file Model sekaligus Migration untuk tabel Posts.

<?php

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

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('slug');
            $table->longText('desc');
            $table->timestamps();
        });
    }

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

Jika model dan migration sudah berhasil dibuat, sekarang masuk ke file di databases/migrations/ [timestamp] _create_posts_table.php. Kemudian sesuaikan kode yang ada dengan kode seperti di atas. Disini kita akan membuat field-field di tabel posts antara lain title, slug dan desc.

Oke jika sudah, silahkan jalankan php artisan migrate

Membuat Data Dummy dengan Factory

php artisan make:factory PostFactory --model=Post

Sekarang kita isi tabel posts dengan data dummy atau dengan memanfaatkan fitur factory (faker) dari laravel untuk membuat data dummy tabel posts sebagai contoh konten. Silahkan jalankan perintah seperti di atas untuk membuat file PostFactory dengan target model Post.

<?php

namespace Database\Factories;

use App\Models\Post;
use Illuminate\Database\Eloquent\Factories\Factory;

class PostFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Post::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'title' => $this->faker->sentence(),
            'slug' => \Str::slug($this->faker->sentence()),
            'desc' => $this->faker->paragraph(5),
        ];
    }
}

Jika file factory sudah berhasil dibuat, sekarang silahkan buka file di database/factories/PostFactory.php. Silahkan sesuaikan kode yang ada dengan kode seperti di atas. Secara garis besarnya, kita hanya perlu menambahkan di bagian return saja.

php artisan tinker
Post::factory()->count(20)->create()

Kemudian kita generate PostFactory menggunakan tinker. Caranya silahkan jalankan perintah php artisan tinker, kemudian diikuti dengan perintah Post::factory()->count(20)->create() untuk generate data factory sebanyak 20 data.

Oke, sekarang kita sudah mempunyai data dummy untuk tabel posts. Sekarang kita akan masuk ke langkah-langkah bagaimana menggunakan laravel livewire untuk membuat fitur load more on scroll atau infinite scroll.

Install Livewire Package

composer require livewire/livewire

Jalankan perintah composer seperti di atas untuk install livewire library di projek laravel kita.

Buat Posts Component

php artisan make:livewire post-data

Setelah proses install livewire package sudah berhasil, sekarang kita akan membuat post component untuk membuat logic dan menampilkan data post. Silahkan jalankan perintah php artisan seperti di atas untuk mulai membuat livewire component. Dengan perintah di atas, kita sudah berhasil membuat file atau component livewire yang akan kita gunakan nantinya.

app/Http/Livewire/PostData.php
resources/views/livewire/post-data.blade.php

File-file atau component livewire yang sudah berhasil dibuat, berada pada path seperti di atas.

Edit Livewire/PostData.php

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\Post;

class PostData extends Component
{
    public $limitPerPage = 10;

    protected $listeners = [
        'post-data' => 'postData'
    ];
   
    public function postData()
    {
        $this->limitPerPage = $this->limitPerPage + 6;
    }

    public function render()
    {
        $posts = Post::latest()->paginate($this->limitPerPage);
        $this->emit('postStore');

        return view('livewire.post-data', ['posts' => $posts]);
    }
}

Setelah berhasil membuat component PostData.php dan post-data.blade.php, sekarang waktunya kita buka file yang ada di App/Http/Livewire/PostData.php. Copy semua kode di atas, lalu paste atau replay di file PostData.php. Sedikit penjelasan mengenai kode di atas, jadi karena kita akan memuat atau menampilkan data dari tabel posts maka kita harus import terlebih dahulu Models\Post. public $limitPerPage = 10; artinya adalah jumlah data yang dimuat diawal adalah sebanyak 10 data. Kemudian kita buat juga protected $listener. public function postData merupakan method yang akan dipanggil jika nantinya kita scroll di view dan akan menambahkan data sebanyak 6 data lagi dan seterusnya. Dan terakhir kita render dengan return view('livewire.post-data', ['posts' => $posts]); dengan urutan data post terakhir dan paginate awal 10.

Edit livewire/post-data.blade.php

<div class="row">
    @foreach ($posts as $post)
    <div class="card mb-2">
        <div class="card-body">
            <a href="">
                <h5 class="card-title">{{ $post->title }}</h5>
            </a>
            <p class="card-text">{{ Str::limit( strip_tags( $post->desc ), 100 ) }}</p>
        </div>
    </div>
    @endforeach
</div>

Silahkan copy semua kode di atas lalu buka paste atau replace di file resources/views/livewire/post-data.blade.php. Dengan kode di atas, kita akan menampilkan data-data yang diambil dari tabel post (sudah kita definisikan di PostData.php) dengan menggunakan perulangan foreach. Untuk link destination pada attribute href sementara kita kosongi karena kita akan menggunakannya nanti di artikel berikutnya. Dan untuk value desc, kita batasi maximal 100 karakter dengan menggunakan Str::limit(strip_tags()) agar tidak terlalu panjang di tampilan home.

Edit welcome.blade.php

<!doctype html>
<html lang="en">
    <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- Bootstrap CSS -->
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">
        <title>Laravel Multi Bahasa</title>
    </head>
    <body>
        <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
            <div class="container-fluid">
                <a class="navbar-brand" href="#">Bisabos.com</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
                </button>
                <div class="collapse navbar-collapse" id="navbarSupportedContent">
                    <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                        <li class="nav-item">
                            <a class="nav-link active" aria-current="page" href="#">Home</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
        <div class="container">
            <div class="row pt-5">
                <div class="text-center pb-3">
                    <h1>Load More on Scroll / Infinite Scroll Laravel Livewire</h1>
                </div>
                <livewire:post-data>
            </div>
        </div>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>
        @livewireScripts
        <script type="text/javascript">
            window.onscroll = function (ev) {
                if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
                    window.livewire.emit('post-data');
                }
            };
        </script>
    </body>
</html>

Karena kita sudah mempunyai livewire component yaitu post-data.blade.php untuk melakukan perulangan dengan foreach atau menampilkan data dari tabel posts, maka di file welcome.blade.php kita sudah tidak membutuhkan lagi component card. Silahkan hapus seluruh card yang ada di file welcome.blade.php dan sebagai gantinya kita harus melakukan rendering component dengan inline component yaitu dengan <livewire:post-data> atau bisa juga dengan @livewire('post-data'). Dan sebelum tag </body> jangan lupa untuk menyertakan @livewireScripts untuk rendering script dari livewire. Untuk membuat logic ketika kita scroll ke bawah maka akan menampilkan data lagi atau load more, maka kita bisa menggunakan script seperti di atas yaitu akan memanggil post-data yang sudah kita buat dengan protected $listener = ['post-data' => 'postData']; di file app/Http/Livewire/PostData.php. Secara keseluruhan, kode yang ada di file welcome.blade.php akan seperti kode di atas.

Bagaimana jika kita menginginkan load more setelah klik button load more ? Mudah saja, kita bisa menggunakan script seperti di bawah ini.

document.getElementById('load-more').onclick = function() {
         window.livewire.emit('post-data');
};

Dengan script di atas, akan membaca setiap ada klik pada button dengan id load-more maka akan memanggil emit post-data

<div class="text-center">
        <button id="load-more" class="btn btn-primary my-3">
        Load More
        </button>
</div>

Kemudian di file resources/views/livewire/post-data.blade.php, kita perlu menambahkan button dengan id="load-more" seperti contoh kode di atas dan diletakkan tepat di bawah @endforeach.

Pengujian

Baiklah, setelah melewati proses panjang yang diawali dengan install laravel, install livewire package sampai dengan membuat livewire component, sekarang waktunya pengujian. Silahkan jalankan php artisan serve lalu buka di browser 127.0.0.1:8000 atau livewire.test. Data yang tampil saat kita membuka projek kita ada 10 data, tapi saat kita scroll ke bawah akan bertambah lagi sebanyak 6 data.

Selamat. Kamu sudah bisa membuat fitur load more on scroll atau infinite scroll menggunakan laravel livewire.

Kesimpulan

Di artikel ini kita sudah sama-sama belajar bagaimana cara membuat fitur load more on scroll atau infinite scroll dengan laravel livewire. Dan hasilnya kita sudah berhasil membuat fitur tersebut. Dapat kita simpulkan bahwa dengan livewire kita dengan mudah sekali dapat membuat fitur load more on scroll atau infite scroll seperti web-web besar type media sosial seperti instagram, facebook atau twitter hanya dengan livewire. Di percobaan ini kita sama sekali tidak menggunakan AJAX atau jQuery untuk membuat fitur tersebut. Di artikel berikutnya akan kita sambung dengan bagaimana cara membuat fitur live search dengan livewire dan lain-lain dan menggunakan atau meneruskan projek yang sudah kita buat ini.

Sekian artikel kali ini, jika ada saran, kritik atau apapun itu yang ingin didiskusikan, silahkan tulis komentar pada form komentar yang tersedia di bawah ini. Dan jika teman-teman punya cara lain untuk membuat fitur load more on scroll atau infinite scroll, bisa juga teman-teman share di form komentar di bawah ini. See you

 

Web illustrations by Storyset

Tinggalkan Komentar
Loading Comments