Hi, Gurpreet this side again with some new stuff. I would love share my todays learning in this article today. Before this I was working with Laravel Breeze + JQuery. But after watching many videos on Youtube and I looked into open source then I saw that most of the developers are using livewire. So, I decided to move on livewire. It’s first that I have used livewire and after using livewire I decided that do follow livewire as much as possible because JQuery isn’t that much helpful for me(personal Opinion).
This is the biggest reason that I am going to use Livewire that is you don’t have to write Javascript in your blade or anywhere else. You just need to use Livewire component methods to perform the actions.
I have used Jetstream with Livewire but the action I am going to perform as a very beginner action you don’t have to consider any kind of Authentication package there. So, I would love to share that how I start it from beginning..
I assume that you have installed Laravel with below command or other command.
composer create-project laravel/laravel blog
If you are going forward with Jetstream. Then do consider that you should not have any other package installed before this, then it might can cause some errors.
Installed Jetstream
Actually, this is the first day as well, I started working with Jetstream I heard that It provides some advance features than Breeze. But If you are a beginner don’t get stuck into the Jetstream package, I would recommend to start with Breeze. Because It provides very easy way to setup your project and move further. I installed Jetstream first.
composer require laravel/jetstream
php artisan jetstream:install livewire
OR
php artisan jetstream:install livewire --teams//when you do work with big projects/team.
Install Dependencies and Migrate The Database
So, now after installing Jetstream and livewire, It’s time to build your NPM dependencies.
-> <span style="background-color: inherit; font-family: inherit; font-size: inherit; color: initial;">npm install</span>
-> npm run build
One more thing that I was going to miss that when you do run this NPM command <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">npm install</mark>
then it provides you the tailwind CSS UI.
Make Migration and Model
Now, As I have said that, we will insert a post data into database so for that we need a database table and for our Laravel logic we need a migration file and a model. Let’s create the migration and model.
php artisan make:model Post --migration
Now, we will have a model called Post and a migration file in under the database directory called create_post_table. Now we will create migration first.
Migration File
<?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('posts', function (Blueprint $table) {
$table->id();
$table->string('title')->nullable();
$table->string('author')->nullable();
$table->string('content')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
};
Model File ( Post)
In model file I would recommend to add fillable array with three of these columns.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory;
protected $fillable = ['title', 'author', 'content'];
}
After running these commands don’t forget to run the migrate command so that you can have the database ready.
Configure your database details in .Env file also so that below command can work well.
php artisan migrate
So, Now we are moving to the main point in which you will learn about inserting data into database by passing from a form to Livewire component.
Add Livewire Component and Page
In Livewire you basically do play with components and pass data through components. So, now I am going to create a post component. I will show you that how I did this today. It was interesting because without thinking about the Ajax/API I have saved the post data easily using Livewire.
Create Component
First of all, I’ll make a livewire component and when you do create a livewire component then you also get a class with that component. It’s not a big different task just bit different from as we do in core Laravel.
php artisan make:livewire createpost //this is how we create livewire component
You can check generated files here in path below.
your-project\resources\views\livewire\createpost.blade.php //component
your-project\app\Http\Livewire\Createpost.php //generated class for component
Now we will have class and components of livewire.
you can check whether your application is working or not by running initial “php artisan serve” command.
When you have installed the authentication package then you might have a dashboard so where you will have a page called dashboard.
Now, let’s add one more page to there for create a post or insert a post.
Create a View file
Now, let’s move on your view folder and create an another folder under your view which will be admin folder.
your-project/resource/view/admin //should be in this way
Create an another file in this folder with the name of posts.blade.php
it will be the page where we will render some of our components related to posts.
your-project/resource/view/admin/posts.blade.php //should be in this way
Now, We will extend this page with our app layout. After extending this page with our app layout we will see how we can render the component.
posts.blade.php
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Posts') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-xl sm:rounded-lg py-4 px-4">
This is post page.
</div>
</div>
</div>
</x-app-layout>
Jump to your layouts folder in view, which will be your app’s layout. Jump to app.blade.php
and see it will be rendering the @livewire('navigation-menu')
then move to navigation-menu.blade.php
component and add one more page with the name of Create Post.
<div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex">
<x-jet-nav-link href="{{ route('posts') }}" :active="request()-routeIs('posts')">
{{ __('Create Post') }}
</x-jet-nav-link>
</div>
Now let’s create route for this page and go to web.php
Route::middleware([
'auth:sanctum',
config('jetstream.auth_session'),
'verified'
])->group(function () {
Route::get('/dashboard', function () {
return view('dashboard');
})->name('dashboard');
Route::get('/posts', function () {
return view('admin.posts');
})->name('post');
});
Note: I have used Create Post in Navigation so this is not a big difference.
Design The Component
Now, We almost near to create the content. But Now as you can see “the page above” we have to replace the component with “This is post page” content.
As I said we have a component called <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">createpost.blade.php</mark>
it’s time to render this component and use a button to open the model to create this all stuff.
Createpost.blade.php
Componenet File
<div>
<x-jet-button <strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">wire:click="showCreatePostModal"</mark></strong>> //explained below
{{ __('Create') }}
</x-jet-button>
<!-- Create post modal -->
<x-jet-dialog-modal wire:model="createPostModal"> //explained below
<x-slot name="title">
{{ __('Create Post') }}
</x-slot>
<x-slot name="content">
<div class="col-span-6 sm:col-span-4">
<x-jet-label for="title" value="{{ __('Title') }}" />
<x-jet-input id="title" type="text" class="mt-1 block w-full" autofocus />
<x-jet-input-error for="title" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-4">
<x-jet-label for="author" value="{{ __('Author') }}" />
<x-jet-input id="author" type="text" class="mt-1 block w-full" autofocus />
<x-jet-input-error for="author" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-4">
<x-jet-label for="content" value="{{ __('Content') }}" />
<x-jet-input id="content" type="text" class="mt-1 block w-full" autofocus />
<x-jet-input-error for="content" class="mt-2" />
</div>
</x-slot>
<x-slot name="footer">
<x-jet-secondary-button>
{{ __('save') }}
</x-jet-secondary-button>
</x-slot>
</x-jet-dialog-modal>
</div>
Call the component in Post file
We have build the component and now we have to call that component in the parent file which we have created in admin folder.
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Posts') }}
</h2>
</x-slot>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-xl sm:rounded-lg py-4 px-4 justify-end flex">
<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color"> <strong><em><livewire:createpost/></em></strong></mark>
</div>
</div>
</div>
</x-app-layout>
I have copied some already built component because then I don’t need to style them. You also can use if you don’t want to write Tailwind.
In above code I have used wire:model=”createPostModal” and wire:click=”showCreatePostModal”. So, what is this?
Let me explain, we have create button component in the top and If we want to open the modal then we have to use wire:click and in this we have targeted the model method in which we will show and hide the model.
I have did this stuff in the component’s class.
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class Createpost extends Component
{
public $createPostModal = false;
public function showCreatePostModal()
{
$this->createPostModal = true;
}
public function render()
{
return view('livewire.createpost');
}
}
After doing this we would have an interface as in the video below.
Insert the Content into database using Livewire
I have modified the all files and added some functionality and this I gonna share with you.
In the component class createpost.php
I have added two methods and three properties.
public $title;
public $author;
public $content;
public function create()
{
Post::create($this->modelData());
$this->createPostModal = false; //here we are hiding the modal aftersaving the data.
}
public function modelData()
{
return [
'title' => $this->title,
'author' => $this->author,
'content' => $this->content,
];
}
<strong><em>createmethod()</em></strong>
I have created for, save the data in database.<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color"><strong><em>modelData()</em></strong> </mark>
method I have created to get the data from model in an array. We are getting this direct into our properties.
Target methods with Buttons in component File
Here’s the final look of blade file.
<div>
<x-jet-button <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">wire:click="showCreatePostModal"</mark>>
{{ __('Create') }}
</x-jet-button>
<x-jet-dialog-modal <strong><mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">wire:model="createPostModal"</mark></strong>>
<x-slot name="title">
{{ __('Create Post') }}
</x-slot>
<x-slot name="content">
<div class="col-span-6 sm:col-span-4">
<x-jet-label for="title" value="{{ __('Title') }}" />
<x-jet-input id="title" type="text" class="mt-1 block w-full" autofocus
<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">wire:model.debounce.1000ms="title" </mark>/>
<x-jet-input-error for="title" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-4">
<x-jet-label for="author" value="{{ __('Author') }}" />
<x-jet-input id="author" type="text" class="mt-1 block w-full" autofocus
<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">wire:model.debounce.1000ms="author"</mark> />
<x-jet-input-error for="author" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-4">
<x-jet-label for="content" value="{{ __('Content') }}" />
<x-jet-input id="content" type="text" class="mt-1 block w-full" autofocus
<mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">wire:model.debounce.1000ms="content"</mark> />
<x-jet-input-error for="content" class="mt-2" />
</div>
</x-slot>
<x-slot name="footer">
<x-jet-secondary-button <mark style="background-color:rgba(0, 0, 0, 0)" class="has-inline-color has-vivid-red-color">wire:click="create"</mark>> // to target the create method
{{ __('Save') }}
</x-jet-secondary-button>
</x-slot>
</x-jet-dialog-modal>
</div>
If you are a beginner who just trying to learn Laravel, then you can learn how to make CRUD in Laravel.
You can read about wire:model.debounce in the official website “Livewire debounce explained“
Conclusion
After making this small change, I get confident that now I can start building my blog further in using Livewire. See, In this way I forget my jQuery and like how easy it is you can imagine. It has lot of other functionalities. Which I would like to learn and share with you in the next blogs.
Thanks For Read.