In this tutorial, we’ll create dynamic input fields using Livewire, a full-stack framework for Laravel to make reactive components.
We’ll use Laravel 9 for this tutorial, however any latest version of Laravel should also work. Laravel 9.x requires a minimum PHP version of 8.0. This tutorial assumes that Composer and PHP 8 along with required modules i.e., bcmatch, mbstring, xml, zip, gd, mcrypt are properly installed.
Using composer, enter following command in terminal to create a fresh Laravel 9 app:
composer create-project laravel/laravel app 9.*
Now go inside newly created app folder by executing:
cd app
Then, add Livewire package by executing following command in project’s parent folder:
composer require livewire/livewire
We’re all set to create Livewire components, so execute the following command to generate a new Livewire component called dynamic:
php artisan make:livewire dynamic
Running the above command will create following two files;
- app/Http/Livewire/Dynamic.php
- resources/views/livewire/dynamic.blade.php
Now, insert following code inside app/Http/Livewire/Dynamic.php:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class Dynamic extends Component
{
public $rows = [['item'=>'', 'quantity'=>'', 'rate'=>'']];
public function render()
{
return view('livewire.dynamic');
}
public function add()
{
array_push($this->rows ,['item'=>'', 'quantity'=>'', 'rate'=>'']);
}
public function remove($key)
{
unset($this->rows[$key]);
}
}
Then, insert following code in resources/views/livewire/dynamic.blade.php:
<div>
<div class="bg-gray-100 rounded-lg shadow m-4">
<div class="grid grid-cols-8">
<div class="col-span-2">
<label class="text-gray-700 p-2 m-2">Item</label>
</div>
<div class="col-span-2">
<label class="text-gray-700 p-2 m-2">Quantity</label>
</div>
<div class="col-span-2">
<label class="text-gray-700 p-2 m-2">Rate</label>
</div>
<div class="col-span-2">
</div>
</div>
@foreach($rows as $key => $value)
<div class="grid grid-cols-8">
<div class="col-span-2 m-1">
<input type="text" class="p-1 w-full rounded-md border border-gray-300" wire:model="rows.{{ $key }}.item">
</div>
<div class="col-span-2 m-1">
<input type="text" class="p-1 w-full rounded-md border border-gray-300" wire:model="rows.{{ $key }}.quantity" >
</div>
<div class="col-span-2 m-1">
<input type="text" class="p-1 w-full rounded-md border border-gray-300" wire:model="rows.{{ $key }}.rate" >
</div>
<div class="col-span-2 m-1">
@if($key > 0)
<button class="border bg-red-600 hover:bg-red-700 text-white rounded-md px-2 py-1 ml-2 inline-block" wire:click.prevent="remove({{$key}})">X</button>
@endif
</div>
</div>
@endforeach
<div class="p-4">
<button class="bg-indigo-600 hover:bg-indigo-700 text-white text-center text-sm rounded-md px-4 py-1" wire:click.prevent="add">Add Row</button>
</div>
</div>
</div>
In order to test this dynamic Livewire component, let’s execute following command to create resources/views/home.blade.php:
touch resources/views/home.blade.php
And then, insert following code inside resources/views/home.blade.php:
<!DOCTYPE html>
<html>
<head>
<title>Livewire Dynamic Input Fields</title>
<script src="https://cdn.tailwindcss.com"></script>
<livewire:styles />
</head>
<body>
<div>
<livewire:dynamic />
</div>
<livewire:scripts />
</body>
</html>
Finally, open routes/web.php and enter following new route into it:
Route::get('/home', function () {
return view('home');
});
Run PHP development server by executing following command:
php artisan serv
Then, enter following URL into the browser:
http://localhost:8000/home
Caution: This article is for educational purposes only; technologies like Livewire should cautiously be used only in scenarios where they are appropriate enough to use such as fetching data from back-end based on search query or filling in simple forms. Obviously, front-end tasks such as hiding / unhiding a menu bar should not be dependent upon a variable defined in back-end code – this approach will result in sluggish UI experience.