如何在 Livewire 中创建动态表单

How to Create Dynamic Form in Livewire

早上好,请帮帮我。我正在 laravel livewire 中创建一个动态表单。

问题是,当我尝试通过单击“Tambah Opsi”按钮添加新表单(选项或 Opsi 2)时,“选项或 Opsi 1”中的输入表单将消失,只会出现标签.如何解决这个问题呢?这样,当点击“Tambah Opsi”按钮添加新表单时,选项或opsi 1 中的输入表单仍将显示。

PengajuanMagang.php

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use Illuminate\Support\Facades\Validator;
use App\Models\{Magang, Peserta};
use App\Notifications\PengajuanMagang as NotificationsPengajuanMagang;

class PengajuanMagang extends Component
{
    public $nama, $email, $nama_perusahaan, $alamat_perusahaan, $telp_perusahaan, $email_perusahaan, $contact_person;
    public $updateMode = False;
    public $inputs = [];
    public $i = 1;

    protected $rules = [
        'email'                 => 'required|exists:pesertas,email',
        'nama_perusahaan.0'     => 'required',
        'alamat_perusahaan.0'   => 'required',
        'telp_perusahaan.0'     => 'required',
        'email_perusahaan.0'    => 'required'
    ];

    protected $messages = [
        'email.required'                => 'Email tidak boleh kosong.',
        'email.exists'                  => 'Alamat email tidak terdaftar di program kami.',
        'nama_perusahaan.0.required'    => 'Nama perusahaan tidak boleh kosong.',
        'alamat_perusahaan.0.required'  => 'Alamat perusahaan tidak boleh kosong.',
        'telp_perusahaan.0.required'    => 'Telephone perusahaan tidak boleh kosong.',
        'email_perusahaan.0.required'   => 'Email perusahaan tidak boleh kosong.'
    ];

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

    private function resetInputFields(){
        $this->nama = '';
        $this->email = '';
        $this->nama_perusahaan = '';
        $this->alamat_perusahaan = '';
        $this->telp_perusahaan = '';
        $this->email_perusahaan = '';
        $this->contact_person = '';
        $this->i = 1;
    }

    public function save()
    {
        $this->validate();

        $peserta = Peserta::where('email',$this->email)->first();
        
        foreach ($this->nama_perusahaan as $key => $value) {
            Magang::create([
                'peserta_id'        => $peserta->id,
                'nama_perusahaan'   => $this->nama_perusahaan[$key],
                'alamat_perusahaan' => $this->alamat_perusahaan[$key],
                'telp_perusahaan'   => $this->telp_perusahaan[$key],
                'email_perusahaan'  => $this->email_perusahaan[$key],
                'contact_person'    => $this->contact_person[$key],
                'status'            => 0
            ]);
        }

        $this->inputs = [];
   
        $this->resetInputFields();

        $peserta->notify(new NotificationsPengajuanMagang($peserta));

        $this->alert('success', 'Data Berhasil Terkirim', [
            'position' =>  'center', 
            'timer' =>  3000,  
            'toast' =>  false, 
            'text' =>  'Kami Akan Segera Melakukan Pemeriksaan Data', 
            'confirmButtonText' =>  'Ok', 
            'cancelButtonText' =>  'Cancel', 
            'showCancelButton' =>  false, 
            'showConfirmButton' =>  false, 
        ]);


        
    }

    public function render()
    {
        return view('livewire.pengajuan-magang')
                ->extends('layouts.front')
                ->section('content');
    }
}

form.blade.php

<div class="card rounded-3">
    <div class="card-body">
        <div class="alert alert-primary" role="alert">
            Silakan usulkan 3 nama Industry terdekat (bisa Hotel, Resto, Coffee Shop, atau Bakery Shop)  yang ingin kamu jadikan tempat Practical Learning.
        </div>
        <form class="row g-3" wire:submit.prevent="save">
            @csrf
            <label><strong>Pengajuan Magang</strong></label>
            <div class="col-md-6">
                <label for="nama" class="form-label">Nama</label>
                <input type="text" wire:model="nama" class="form-control @error('nama') is-invalid @enderror" id="nama" placeholder="Nama Kamu">
                @error('nama')
                <div class="invalid-feedback">
                    {{ $message }}
                </div>
                @enderror
            </div>
            <div class="col-md-6">
                <label for="email" class="form-label">Email</label>
                <input type="email" wire:model="email" class="form-control @error('email') is-invalid @enderror" id="email" aria-describedby="email" placeholder="Email Kamu">
                @error('email')
                <div class="invalid-feedback">
                    {{ $message }}
                </div>
                @enderror
                <div id="email" class="form-text"><span class="text-danger">*</span> Masukkan alamat email yang kamu gunakan saat mendaftar program.</div>
            </div>
            <label><strong>Opsi 1</strong></label>
            <div class="col-md-6">
                <label for="nama_perusahaan" class="form-label">Nama Perusahaan</label>
                <input type="text" wire:model="nama_perusahaan.0" class="form-control @error('nama_perusahaan.0') is-invalid @enderror" id="nama_perusahaan" placeholder="Nama Perusahaan">
                @error('nama_perusahaan.0')
                <div class="invalid-feedback">
                    {{ $message }}
                </div>
                @enderror
            </div>
            <div class="col-md-6">
                <label for="telp_perusahaan" class="form-label">Telp Perusahaan</label>
                <input type="text" wire:model="telp_perusahaan.0" class="form-control @error('telp_perusahaan.0') is-invalid @enderror" id="telp_perusahaan" placeholder="Telephone Perusahaan">
                @error('telp_perusahaan.0')
                <div class="invalid-feedback">
                    {{ $message }}
                </div>
                @enderror
            </div>
            <div class="col-md-6">
                <label for="email_perusahaan" class="form-label">Email Perusahaan</label>
                <input type="email" wire:model="email_perusahaan.0" class="form-control @error('email_perusahaan.0') is-invalid @enderror" id="email_perusahaan" placeholder="Email Perusahaan">
                @error('email_perusahaan.0')
                <div class="invalid-feedback">
                    {{ $message }}
                </div>
                @enderror
            </div>
            <div class="col-md-6">
                <label for="contact_person" class="form-label">Contact Person</label>
                <input type="text" wire:model="contact_person.0" class="form-control @error('contact_person.0') is-invalid @enderror" id="contact_person" placeholder="Contact Person">
                @error('contact_person.0')
                <div class="invalid-feedback">
                    {{ $message }}
                </div>
                @enderror
            </div>
            <div class="col-12">
                <label for="alamat_perusahaan" class="form-label">Alamat Perusahaan</label>
                <input type="text" wire:model="alamat_perusahaan.0" class="form-control @error('alamat_perusahaan.0') is-invalid @enderror" id="alamat_perusahaan" placeholder="Contoh: Kec. Pakem, Kab. Sleman">
                @error('alamat_perusahaan.0')
                <div class="invalid-feedback">
                    {{ $message }}
                </div>
                @enderror
            </div>
            @foreach ($inputs as $key => $value)
            <hr>
            <div class="d-flex mx-auto">
                <label><strong>Opsi {{ $value }}</strong></label>
            </div>
            <div class="col-md-6">
                <label for="nama_perusahaan" class="form-label">Nama Perusahaan</label>
                <input type="text" wire:model="nama_perusahaan.{{ $value }}" class="form-control @error('nama_perusahaan.'.$value) is-invalid @enderror" id="nama_perusahaan" placeholder="Nama Perusahaan">
                @error('nama_perusahaan.'.$value)
                <div class="invalid-feedback">
                    {{ $message }}
                </div>
                @enderror
            </div>
            <div class="col-md-6">
                <label for="telp_perusahaan" class="form-label">Telp Perusahaan</label>
                <input type="text" wire:model="telp_perusahaan.{{ $value }}" class="form-control @error('telp_perusahaan.'.$value) is-invalid @enderror" id="telp_perusahaan" placeholder="Telephone Perusahaan">
                @error('telp_perusahaan.'.$value)
                <div class="invalid-feedback">
                    {{ $message }}
                </div>
                @enderror
            </div>
            <div class="col-md-6">
                <label for="email_perusahaan" class="form-label">Email Perusahaan</label>
                <input type="email" wire:model="email_perusahaan.{{ $value }}" class="form-control @error('email_perusahaan.'.$value) is-invalid @enderror" id="email_perusahaan" placeholder="Email Perusahaan">
                @error('email_perusahaan.'.$value)
                <div class="invalid-feedback">
                    {{ $message }}
                </div>
                @enderror
            </div>
            <div class="col-md-6">
                <label for="contact_person" class="form-label">Contact Person</label>
                <input type="text" wire:model="contact_person.{{ $value }}" class="form-control @error('contact_person.'.$value) is-invalid @enderror" id="contact_person" placeholder="Contact Person">
                @error('contact_person.'.$value)
                <div class="invalid-feedback">
                    {{ $message }}
                </div>
                @enderror
            </div>
            <div class="col-12">
                <label for="alamat_perusahaan" class="form-label">Alamat Perusahaan</label>
                <input type="text" wire:model="alamat_perusahaan.{{ $value }}" class="form-control @error('alamat_perusahaan.'.$value) is-invalid @enderror" id="alamat_perusahaan" placeholder="Contoh: Kec. Pakem, Kab. Sleman">
                @error('alamat_perusahaan.'.$value)
                <div class="invalid-feedback">
                    {{ $message }}
                </div>
                @enderror
            </div>
            @endforeach
            <div>
                <button class="btn btn-success" type="button" wire:click.prevent="add({{$i}})" {{ $i == 3 ? 'disabled' : '' }}>Tambah Opsi</button>
            </div>
            <div class="d-grid gap-2">
                <button class="btn btn-submit" wire:target="save" wire:loading.attr="disabled">
                <span wire:loading.remove wire:target="save">
                Ajukan
                </span>
                <span wire:loading wire:target="save" class="text-center">
                <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
                Loading...
                </span>
                </button>
            </div>
        </form>
    </div>
</div>

将 foreach 代码包装到根 div 并为其定义 wire:key 指令

@foreach ($inputs as $key => $value)
<hr>
<div wire:key="opsi-key-{{ $key }}" // or some unique identifier
    <div class="d-flex mx-auto">
            <label><strong>Opsi {{ $value }}</strong></label>
        </div>
        <div class="col-md-6">
            <label for="nama_perusahaan" class="form-label">Nama Perusahaan</label>
            <input type="text" wire:model="nama_perusahaan.{{ $value }}" class="form-control @error('nama_perusahaan.'.$value) is-invalid @enderror" id="nama_perusahaan" placeholder="Nama Perusahaan">
            @error('nama_perusahaan.'.$value)
            <div class="invalid-feedback">
                {{ $message }}
            </div>
            @enderror
        </div>
        //.......
</div>