Membuat Dynamic Form dengan Laravel 8 dan Livewire

Membuat Dynamic Form dengan Laravel 8 dan Livewire

Admin
Admin・ 13 Agustus 2021
11 min read ・ 415 views
Series: Laravel Livewire

Dynamic Form Laravel Livewire - Di artikel ini saya akan membagikan tutorial bagaimana cara membuat dynamic form atau input fields dengan menggunakan laravel versi 8 dan livewire. Fitur dynamic form atau input fields biasanya digunakan untuk input data yang tak terbatas jumlahnya seperti user contacts, social account links dan lain-lain.

dynamic input fields laravel livewire

Jika kamu mempunyai facebook page atau halaman facebook, mungkin kamu pernah melihat fitur tambah akun lainnya seperti contoh gambar di atas. Di fitur facebook page tersebut, kita bisa bebas menambahkan akun resmi kita selain facebook page seperti instagram, twitter, github dan lain-lain. 

Nah, di tutorial kali ini, saya akan coba menjalaskan bagaimana cara membuat fitur seperti di facebook page yaitu menambahkan akun lainnya dengan dynamic form atau input fields menggunakan laravel versi 8 dan livewire.

Ok, langsung saja kita ke kode.

Step 1: Install Laravel Latest Version

laravel new dynamic-form-laravel-livewire

Langkah pertama di tutorial ini yaitu kita awali dengan install laravel terbaru (saat ini versi 8). Untuk menginstall laravel, kita bisa menggunakan perintah laravel installer seperti di atas atau bisa juga menginstall laravel dengan composer seperti perintah di bawah ini.

composer create-project laravel/laravel dynamic-form-laravel-livewire

Dengan perintah tersebut, kita akan menginstall laravel dengan nama folder atau project yaitu dynamic-form-laravel-livewire. Jika proses installasi sudah selesai, jangan lupa untuk masuk ke project dengan cd dynamic-form-laravel-livewire.

Step 2: Create Database & Setup .ENV

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=dynamic-form-laravel-livewire
DB_USERNAME=root
DB_PASSWORD=

Setelah menyelesaikan installasi laravel, selanjutnya yaitu membuat database baru yang akan digunakan untuk menyimpan data account yang akan kita buat pada tutorial kali ini. Silahkan buat database baru dan jangan lupa menyesuaikan DB_DATABASE di file .env.

Step 3: Create Model & Migration File

 php artisan make:model Account -m

Buat file account model dan migration dengan menjalankan perintah seperti di atas. Dengan perintah tersebut, otomatis akan me-generate dua file yang terdapat di app/Models/Account dan database/migrations/[timestamp]_create_accounts_table.php

<?php

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

class CreateAccountsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('accounts', function (Blueprint $table) {
            $table->id();
            $table->string('account');
            $table->string('username');
            $table->timestamps();
        });
    }

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

Buka, file accounts migration yang baru saja digenerate. Kemudian tambahkan field account dan username pada method up, sehingga secara keseluruhan file migration tersebut akan menjadi seperti kode di atas.

php artisan migrate

Jalankan perintah php artisan migrate untuk memigrasi semua file yang ada di dalam folder migrations ke database yang baru kita buat pada step 2.

Jangan lupa menambahkan protected $guarded = []; di file /app/Models/Account.php.

Step 4: Install Livewire

composer require livewire/livewire

Selesai menginstall laravel dan membuat database, kita lanjutkan dengan menginstall livewire di project laravel kita. Jalankan perintah seperti di atas untuk menginstall livewire.

Step 5: Generate Livewire Components

php artisan make:livewire UserAccount

Kemudian kita perlu membuat atau generate livewire components yang akan kita gunakan untuk menampilkan data accounts dan membuat dynamic form atau input fields beserta action post (store). Jalankan perintah seperti di atas untuk generate livewire components. Perintah tersebut akan me-generate livewire components yang terletak di direktori;

app/Http/Livewire/UserAccount.php
resources/views/livewire/user-account.blade.php

Step 6: Setup UserAccount.php

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use Illuminate\Http\Request;
use App\Models\Account;

class UserAccount extends Component
{
    public $accounts, $account, $username, $account_id;
    public $updateMode = false;
    public $inputs = [];
    public $i = 1;

    public function add($i)
    {
        $i = $i + 1;
        $this->i = $i;
        array_push($this->inputs ,$i);
    }

    public function remove($i)
    {
        unset($this->inputs[$i]);
    }

    private function resetInputFields(){
        $this->account = '';
        $this->username = '';
    }

    public function store()
    {
        $validatedDate = $this->validate([
                'account.0' => 'required',
                'username.0' => 'required',
                'account.*' => 'required',
                'username.*' => 'required',
            ],
            [
                'account.0.required' => 'Account field is required',
                'username.0.required' => 'Username field is required',
                'account.*.required' => 'Account field is required',
                'username.*.required' => 'Username field is required',
            ]
        );
   
        foreach ($this->account as $key => $value) {
            Account::create(['account' => $this->account[$key], 'username' => $this->username[$key]]);
        }
  
        $this->inputs = [];
   
        $this->resetInputFields();
   
        session()->flash('message', 'Account Added Successfully.');
    }

    public function render()
    {
        $data = Account::all();
        return view('livewire.user-account',['data' => $data]);
    }
} 

Buka file UserAction.php yang telah kita generate di step sebelumnya, kemudian sesuaikan kode yang ada dengan kode seperti di atas. Di kode tersebut, kita membuat beberapa method seperti add (untuk tambah form input atau input field), remove (untuk menghapus form input atau input field), resetInputFields (bertugas untuk mengosongkan form input atau input field setelah proses save atau store), store (untuk menambahkan data ke database atau table accounts) dan render (untuk menampilkan data account di file view user-account.blade.php).

Step 7: Setup Blade View

Hampir selesai. Di step 7 ini kita perlu untuk setup dua blade view yaitu welcome.blade.php dan livewire/user-account.blade.php.

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/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.css">
        <title>How to Create Dynamic Forms with Laravel 8 and Livewire</title>
        @livewireStyles
    </head>
    <body>
        @livewire('user-account')
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
        @livewireScripts
    </body>
</html>

Buka file welcome.blade.php, kemudian update seperti kode di atas. Di file welcome.blade.php ini, kita menambahkan @livewireStyles, @livewire('user-account') dan @livewireScripts

Edit livewire/user-account.blade.php

<div class="container">
    <div class="row mt-5">
         <h1 class="fs-5 text-center">Dynamic Form with Laravel 8 & Livewire</h1>
    </div>
    <div class="row justify-content-center">
        <div class="w-50">
            <div class="card my-3">
                <div class="card-body">
                    <form class="row g-3 justify-content-center">
                        <div class="col-4">
                            <label class="visually-hidden">Account</label>
                            <select class="form-select" aria-label="Default select example" wire:model="account.0">
                                <option selected>Account</option>
                                <option value="facebook">Facebook</option>
                                <option value="instagram">Instagram</option>
                                <option value="twitter">Twitter</option>
                                <option value="github">Github</option>
                            </select>
                            @error('account.0') <span class="text-danger error">{{ $message }}</span>@enderror
                        </div>
                        <div class="col-6">
                            <label class="visually-hidden">Username</label>
                            <input type="text" class="form-control" wire:model="username.0" placeholder="Your Username">
                            @error('username.0') <span class="text-danger error">{{ $message }}</span>@enderror
                        </div>
                        <div class="col-2">
                            <button class="btn btn-primary mb-3" wire:click.prevent="add({{$i}})"><i class="bi bi-plus"></i></button>
                        </div>
                        {{-- Add Form --}}
                        @foreach ($inputs as $key => $value)
                        <div class="col-4">
                            <label class="visually-hidden">Account</label>
                            <select class="form-select" aria-label="Default select example" wire:model="account.{{ $value }}">
                                <option selected>Account</option>
                                <option value="facebook">Facebook</option>
                                <option value="instagram">Instagram</option>
                                <option value="twitter">Twitter</option>
                                <option value="github">Github</option>
                            </select>
                            @error('account.') <span class="text-danger error">{{ $message }}</span>@enderror
                        </div>
                        <div class="col-6">
                            <label class="visually-hidden">Username</label>
                            <input type="text" class="form-control" wire:model="username.{{ $value }}" placeholder="Your Username">
                            @error('username.') <span class="text-danger error">{{ $message }}</span>@enderror
                        </div>
                        <div class="col-2">
                            <button class="btn btn-light mb-3" wire:click.prevent="remove({{$key}})"><i class="bi bi-x"></i></button>
                        </div>
                        @endforeach
                        <div class="row">
                            <div class="col-12 ps-0">
                                 <button type="button" class="btn btn-primary" wire:click.prevent="store()">Save</button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
            @if (session()->has('message'))
                <div class="alert alert-success">
                {{ session('message') }}
                </div>
            @endif
            <table class="table table-responsive">
                <thead>
                    <tr>
                        <th scope="col">#</th>
                        <th scope="col">Account</th>
                        <th scope="col">Username</th>
                    </tr>
                </thead>
                <tbody>
                    @php
                    $no = 0;
                    @endphp
                    @foreach ($data as $data)
                    <tr>
                        <th scope="row">{{ ++$no }}</th>
                        <td>{{ $data->account }}</td>
                        <td>{{ $data->username }}</td>
                    </tr>
                    @endforeach
                </tbody>
            </table>
        </div>
    </div>
</div>

Kemudian buka file livewire/user-account yang telah kita generate pada step 5. Perbarui semua kode yan ada di file tersebut dengan seluruh kode seperti di atas. Dengan kode seperti di atas, kita membuat dynamic form input atau input fields dan membuat tampilan tabel yang berfungsi untuk menampilkan data account yang telah berhasil ditambahkan (store).

Step 8: Testing

dynamic form with laravel 8 & livewire

Setelah melalui prores-proses mulai dari install laravel versi terbaru, setup database, install dan generate livewire components hingga proses setup blade view, sekarang kita sudah tiba di step terakhir yang pengujian dynamic form atau input fields yang telah kita buat dengan laravel 8 dan livewire.

Silahkan jalankan server laravel project kalian dengan perintah php artisan serve, lalu buka di browser dengan URL 127.0.0.1:8000 atau dynamic-form-laravel-livewire.test. Kemudian silahkan coba mengisi data pada input field dan klik icon + untuk menambahkan input field lainnya, klik tombol save untuk menambahkan data ke database (store).

OK, sampai disini kita sudah berhasil membuat fitur dynamic form atau input fields seperti yang ada di facebook dengan menggunakan laravel 8 dan livewire. Selamat mencoba, semoga artikel ini bisa bermanfaat dan sampai jumpa di artikel berikutnya.

 

Credit: Online illustrations by Storyset

Tinggalkan Komentar
Loading Comments