First, we create a Laravel project called Alp-wire as follows:
composer create-project laravel/laravel Alp-wire
Then we install livewire with the following command in Laravel project:
composer require livewire/livewire
Then in the command line we use the following command to use livewire in Laravel project:
php artisan make:livewire welcome-page
Alp-wire / resources / views / welcome.blade.php
<!DOCTYPE html>
<html>
<head>
<title>Alp-wire</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
@livewireStyles
</head>
<body class="antialiased">
@livewire('welcome-page')
@livewireScripts
</body>
</html>
In the above code, we used Alpine cdn.
Alp-wire/app/Http/Livewire/WelcomePage.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class WelcomePage extends Component
{
public function render()
{
return view('livewire.welcome-page');
}
}
Alp-wire/resources/views/livewire/welcome-page.blade.php
<div>
<h1
class="text-3xl text-gray-200 hover:text-yellow-400 text-center mt-48 font-extrabold tracking-tight text-white sm:text-5xl">
Hello World!
</h1>
</div>
This way it is very easy to use livewire, of course you can also use tailwindcss along with livewire.
Then create a database and create a users table as follows:
Alp-wire/database/migrations/2014_10_12_000000_create_users_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->integer('phone');
$table->integer('package');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
};
Alp-wire/app/Models/User.php
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'phone',
'package',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
Then we create another component as follows:
php artisan make:livewire Home-page
Alp-wire/app/Http/Livewire/WelcomePage.php
<?php
namespace App\Http\Livewire;
use App\Models\User;
use Livewire\Component;
class WelcomePage extends Component
{
public $name;
public $email;
public $phone;
public $package;
protected $rules = [
"name" => "required|min:6",
"email" => "required|email|unique:users",
"phone" => "required|regex:/(0)[0-9]/|not_regex:/[a-z]/|min:9",
"package" => "required",
];
public function updated($propertyName)
{
$this->validateOnly($propertyName);
}
public function submit()
{
$data = [
'name' => $this->name,
'email' => $this->email,
'phone' => $this->phone,
'package' => $this->package
];
$data = $this->validate();
User::create($data);
}
public function render()
{
return view('livewire.Home-page');
}
}
Alp-wire/app/Http/Livewire/HomePage.php
<?php
namespace App\Http\Livewire;
use App\Models\User;
use Livewire\Component;
class HomeTable extends Component
{
public function render()
{
return view('livewire.Home-table');
}
}
Alp-wire/resources/views/livewire/welcome-page.blade.php
<div>
@livewire('Home-page')
</div>
Alp-wire/resources/views/livewire/Home-page.blade.php
<div class="mt-8 ml-12">
<h1 class="w-11/12 pb-4 text-4xl font-extrabold tracking-tight text-gray-900 border-b border-slate-300">
SignUp</h1>
<div class="flex">
<form class="pt-4" wire:submit.prevent="submit">
<div>
<label for="name" class="block text-sm font-medium text-gray-700">Name</label>
<input required type="text" name="name" wire:model="name" id="name"
class="block border rounded-md w-72">
@error('name')
<span class="text-red-500">{{ $message }}</span>
@enderror
</div>
<div class="mt-4">
<label for="email" class="block text-sm font-medium text-gray-700">Email</label>
<input required type="text" name="email" wire:model="email" id="email"
class="block border rounded-md w-72">
@error('email')
<span class="text-red-500">{{ $message }}</span>
@enderror
</div>
<div class="mt-4">
<label for="phone" class="block text-sm font-medium text-gray-700">Phone</label>
<input required type="text" name="phone" wire:model="phone" id="phone"
class="block border rounded-md w-72">
@error('phone')
<span class="text-red-500">{{ $message }}</span>
@enderror
</div>
<div class="mt-4">
<label for="package" class="block text-sm font-medium text-gray-700">Package</label>
<select wire:model="package" name="package" class="block border rounded-md w-72">
<option>
choose one package
</option>
<option value="5">
5 days in week
</option>
<option value="4">
4 days in week
</option>
<option value="3">
3 days in week
</option>
<option value="2">
2 days in week
</option>
</select>
</div>
<button type="submit"
class="flex items-center justify-center px-8 py-3 mt-10 text-base font-medium text-white bg-indigo-600 border border-transparent rounded-md w-72 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Add</button>
</form>
</div>
Now to use alpine, we do the following to add navigation:
Alp-wire/resources/views/livewire/Home-page.blade.php
<div class="mt-8 ml-12" x-data="{ open: false }">
<h1 class="w-11/12 pb-4 text-4xl font-extrabold tracking-tight text-gray-900 border-b border-slate-300">
SignUp</h1>
<div x-show="open" class="px-4 py-3 text-teal-900 bg-teal-100 border-t-4 border-teal-500 rounded-b shadow-md"
role="alert">
<div class="flex">
<div class="py-1"><svg class="w-6 h-6 mr-4 text-teal-500 fill-current"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<path
d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM9 11V9h2v6H9v-4zm0-6h2v2H9V5z" />
</svg></div>
<div>
<p class="font-bold">User Successfuly Saved!</p>
</div>
</div>
</div>
<div class="flex">
<form class="pt-4" wire:submit.prevent="submit" @submit.prevent="open = true">
<div>
<label for="name" class="block text-sm font-medium text-gray-700">Name</label>
<input required type="text" name="name" wire:model="name" id="name"
class="block border rounded-md w-72">
@error('name')
<span class="text-red-500">{{ $message }}</span>
@enderror
</div>
<div class="mt-4">
<label for="email" class="block text-sm font-medium text-gray-700">Email</label>
<input required type="text" name="email" wire:model="email" id="email"
class="block border rounded-md w-72">
@error('email')
<span class="text-red-500">{{ $message }}</span>
@enderror
</div>
<div class="mt-4">
<label for="phone" class="block text-sm font-medium text-gray-700">Phone</label>
<input required type="text" name="phone" wire:model="phone" id="phone"
class="block border rounded-md w-72">
@error('phone')
<span class="text-red-500">{{ $message }}</span>
@enderror
</div>
<div class="mt-4">
<label for="package" class="block text-sm font-medium text-gray-700">Package</label>
<select wire:model="package" name="package" class="block border rounded-md w-72">
<option>
choose one package
</option>
<option value="5">
5 days in week
</option>
<option value="4">
4 days in week
</option>
<option value="3">
3 days in week
</option>
<option value="2">
2 days in week
</option>
</select>
</div>
<button type="submit"
class="flex items-center justify-center px-8 py-3 mt-10 text-base font-medium text-white bg-indigo-600 border border-transparent rounded-md w-72 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Add</button>
</form>
</div>
Now to show the list of users using alpine, we do the following:
Alp-wire/app/Http/Livewire/WelcomePage.php
<?php
namespace App\Http\Livewire;
use App\Models\User;
use Livewire\Component;
class WelcomePage extends Component
{
public $name;
public $email;
public $phone;
public $package;
public $users;
public function mount()
{
$this->users = User::all();
}
protected $rules = [
"name" => "required|min:6",
"email" => "required|email|unique:users",
"phone" => "required|regex:/(0)[0-9]/|not_regex:/[a-z]/|min:9",
"package" => "required",
];
public function updated($propertyName)
{
$this->validateOnly($propertyName);
}
public function submit()
{
$data = [
'name' => $this->name,
'email' => $this->email,
'phone' => $this->phone,
'package' => $this->package
];
$data = $this->validate();
User::create($data);
}
public function render()
{
return view('livewire.Home-page');
}
}
Alp-wire/app/Http/Livewire/HomePage.php
<?php
namespace App\Http\Livewire;
use App\Models\User;
use Livewire\Component;
class BodyTable extends Component
{
public $users;
public function mount(User $users)
{
$this->users = $users;
}
public function render()
{
return view('livewire.body-table');
}
}
Alp-wire/routes/web.php
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Route::get('/users', function () {
return view('users');
});
Alp-wire/resources/views/livewire/Home-page.blade.php
<div class="mt-8 ml-12" x-data="{ open: false }">
<h1 class="w-11/12 pb-4 text-4xl font-extrabold tracking-tight text-gray-900 border-b border-slate-300">
SignUp</h1>
<div x-show="open" class="px-4 py-3 text-teal-900 bg-teal-100 border-t-4 border-teal-500 rounded-b shadow-md"
role="alert">
<div class="flex">
<div class="py-1"><svg class="w-6 h-6 mr-4 text-teal-500 fill-current"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<path
d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM9 11V9h2v6H9v-4zm0-6h2v2H9V5z" />
</svg></div>
<div>
<p class="font-bold">User Successfuly Saved!</p>
</div>
</div>
</div>
<div class="flex">
<form class="pt-4" wire:submit.prevent="submit" @submit.prevent="open = true">
<div>
<label for="name" class="block text-sm font-medium text-gray-700">Name</label>
<input required type="text" name="name" wire:model="name" id="name"
class="block border rounded-md w-72">
@error('name')
<span class="text-red-500">{{ $message }}</span>
@enderror
</div>
<div class="mt-4">
<label for="email" class="block text-sm font-medium text-gray-700">Email</label>
<input required type="text" name="email" wire:model="email" id="email"
class="block border rounded-md w-72">
@error('email')
<span class="text-red-500">{{ $message }}</span>
@enderror
</div>
<div class="mt-4">
<label for="phone" class="block text-sm font-medium text-gray-700">Phone</label>
<input required type="text" name="phone" wire:model="phone" id="phone"
class="block border rounded-md w-72">
@error('phone')
<span class="text-red-500">{{ $message }}</span>
@enderror
</div>
<div class="mt-4">
<label for="package" class="block text-sm font-medium text-gray-700">Package</label>
<select wire:model="package" name="package" class="block border rounded-md w-72">
<option>
choose one package
</option>
<option value="5">
5 days in week
</option>
<option value="4">
4 days in week
</option>
<option value="3">
3 days in week
</option>
<option value="2">
2 days in week
</option>
</select>
</div>
<button type="submit"
class="flex items-center justify-center px-8 py-3 mt-10 text-base font-medium text-white bg-indigo-600 border border-transparent rounded-md w-72 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Add</button>
</form>
<div class="max-w-2xl mx-auto" x-show="open">
<div class="relative overflow-x-auto shadow-md sm:rounded-lg">
<div class="p-4">
<label for="table-search" class="sr-only">Search</label>
<div class="relative mt-1">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg class="w-5 h-5 text-gray-500 dark:text-gray-400" fill="currentColor"
viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
clip-rule="evenodd"></path>
</svg>
</div>
<input type="text" id="table-search"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-80 pl-10 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
placeholder="Search for items">
</div>
</div>
<table class="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th scope="col" class="px-6 py-3">
name
</th>
<th scope="col" class="px-6 py-3">
email
</th>
<th scope="col" class="px-6 py-3">
phone
</th>
<th scope="col" class="px-6 py-3">
package
</th>
<th scope="col" class="px-6 py-3">
<span class="sr-only">Edit</span>
</th>
</tr>
</thead>
<tbody>
//codes
</tbody>
</table>
</div>
<script src="https://unpkg.com/flowbite@1.3.4/dist/flowbite.js"></script>
</div>
</div>
</div>
Alp-wire/resources/views/livewire/welcome-page.blade.php
<div>
@livewire('Home-page', ['users' => $users])
</div>
To use alpine, we do the following:
Alp-wire/resources/views/livewire/Home-page.blade.php
<div class="mt-8 ml-12" x-data="{ open: false }">
<h1 class="w-11/12 pb-4 text-4xl font-extrabold tracking-tight text-gray-900 border-b border-slate-300">
SignUp</h1>
<div x-show="open" class="px-4 py-3 text-teal-900 bg-teal-100 border-t-4 border-teal-500 rounded-b shadow-md"
role="alert">
<div class="flex">
<div class="py-1"><svg class="w-6 h-6 mr-4 text-teal-500 fill-current"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
<path
d="M2.93 17.07A10 10 0 1 1 17.07 2.93 10 10 0 0 1 2.93 17.07zm12.73-1.41A8 8 0 1 0 4.34 4.34a8 8 0 0 0 11.32 11.32zM9 11V9h2v6H9v-4zm0-6h2v2H9V5z" />
</svg></div>
<div>
<p class="font-bold">User Successfuly Saved!</p>
</div>
</div>
</div>
<div class="flex">
<form class="pt-4" wire:submit.prevent="submit" @submit.prevent="open = true">
<div>
<label for="name" class="block text-sm font-medium text-gray-700">Name</label>
<input required type="text" name="name" wire:model="name" id="name"
class="block border rounded-md w-72">
@error('name')
<span class="text-red-500">{{ $message }}</span>
@enderror
</div>
<div class="mt-4">
<label for="email" class="block text-sm font-medium text-gray-700">Email</label>
<input required type="text" name="email" wire:model="email" id="email"
class="block border rounded-md w-72">
@error('email')
<span class="text-red-500">{{ $message }}</span>
@enderror
</div>
<div class="mt-4">
<label for="phone" class="block text-sm font-medium text-gray-700">Phone</label>
<input required type="text" name="phone" wire:model="phone" id="phone"
class="block border rounded-md w-72">
@error('phone')
<span class="text-red-500">{{ $message }}</span>
@enderror
</div>
<div class="mt-4">
<label for="package" class="block text-sm font-medium text-gray-700">Package</label>
<select wire:model="package" name="package" class="block border rounded-md w-72">
<option>
choose one package
</option>
<option value="5">
5 days in week
</option>
<option value="4">
4 days in week
</option>
<option value="3">
3 days in week
</option>
<option value="2">
2 days in week
</option>
</select>
</div>
<button type="submit"
class="flex items-center justify-center px-8 py-3 mt-10 text-base font-medium text-white bg-indigo-600 border border-transparent rounded-md w-72 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">Add</button>
</form>
<div class="max-w-2xl mx-auto" x-show="open">
<div class="relative overflow-x-auto shadow-md sm:rounded-lg" x-data="{
search: '',
@foreach ($users as $user) items: ['{{ $user->name }}'], @endforeach
get filteredItems() {
return this.items.filter(
i => i.startsWith(this.search)
)
}
}">
<div class="p-4">
<label for="table-search" class="sr-only">Search</label>
<div class="relative mt-1">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<svg class="w-5 h-5 text-gray-500 dark:text-gray-400" fill="currentColor"
viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
clip-rule="evenodd"></path>
</svg>
</div>
<input type="text" id="table-search" x-model="search"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-80 pl-10 p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
placeholder="Search for items">
</div>
</div>
<table class="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th scope="col" class="px-6 py-3">
name
</th>
<th scope="col" class="px-6 py-3">
email
</th>
<th scope="col" class="px-6 py-3">
phone
</th>
<th scope="col" class="px-6 py-3">
package
</th>
<th scope="col" class="px-6 py-3">
<span class="sr-only">Edit</span>
</th>
</tr>
</thead>
<tbody>
@foreach ($users as $user)
<template x-for="item in filteredItems" :key="item">
<tr
class="bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600">
<td scope="row"
class="px-6 py-4 font-medium text-gray-900 dark:text-white whitespace-nowrap">
{{ $user->name }}
<span class="invisible" x-text="item"></span>
</td>
<td class="px-6 py-4">
{{ $user->email }}
</td>
<td class="px-6 py-4">
{{ $user->phone }}
</td>
<td class="px-6 py-4">
{{ $user->package }}
</td>
<td class="px-6 py-4 text-right">
<a href="#"
class="font-medium text-blue-600 dark:text-blue-500 hover:underline">Edit</a>
</td>
</tr>
</template>
@endforeach
</tbody>
</table>
</div>
<script src="https://unpkg.com/flowbite@1.3.4/dist/flowbite.js"></script>
</div>
</div>
</div>
I hope you like this article. To see the source codes, you can refer to the following link.