Dynamic input fields using Livewire

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.

Leave a Comment