We will see how to create the CRUD process in Livewire
The routes rutas:
Route::group(['prefix' => 'post'],function () {
Route::get('/', App\Http\Livewire\Dashboard\Post\Index::class)->name("d-post-index"); // listado
Route::get('/create', App\Http\Livewire\Dashboard\Post\Save::class)->name("d-post-create"); // crear
Route::get('/edit/{id}', App\Http\Livewire\Dashboard\Post\Save::class)->name("d-post-edit");// edit
});
Next, the code for the section of creating and updating a post is presented:
app/Http/Livewire/Dashboard/Post/Save.php
<?php
namespace App\Http\Livewire\Dashboard\Post;
use App\Models\Category;
use App\Models\Post;
use Illuminate\Support\Facades\Log;
use Livewire\Component;
use Livewire\WithFileUploads;
class Save extends Component
{
use WithFileUploads;
public $title;
public $date;
public $text;
public $description;
public $posted;
public $type;
public $category_id;
public $image;
public $post;
protected $rules = [
'title' => "required|min:2|max:255",
'description' => "required|min:2|max:255",
'date' => "required",
'type' => "required",
'category_id' => "required",
'posted' => "required",
'text' => "required|min:2|max:5000",
'image' => "nullable|image|max:1024",
];
public function mount($id = null)
{
if ($id != null) {
$this->post = Post::findOrFail($id);
$this->title = $this->post->title;
$this->text = $this->post->text;
$this->date = $this->post->date;
$this->description = $this->post->description;
$this->posted = $this->post->posted;
$this->type = $this->post->type;
$this->category_id = $this->post->category_id;
}
}
public function render()
{
$categories = Category::get();
return view('livewire.dashboard.post.save', compact('categories'));
}
public function submit()
{
// validate
$this->validate();
// save
if ($this->post) {
$this->post->update([
'title' => $this->title,
'text' => $this->text,
'description' => $this->description,
'date' => $this->date,
'posted' => $this->posted,
'type' => $this->type,
'category_id' => $this->category_id,
]);
$this->dispatch("updated");
} else {
$this->post = Post::create(
[
'title' => $this->title,
'slug' => str($this->title)->slug(),
'text' => $this->text,
'description' => $this->description,
'date' => $this->date,
'posted' => $this->posted,
'type' => $this->type,
'category_id' => $this->category_id,
]
);
$this->dispatch("created");
}
// upload
if ($this->image) {
$imageName = $this->post->slug . '.' . $this->image->getClientOriginalExtension();
$this->image->storeAs('images/post', $imageName, 'public_upload');
$this->post->update([
'image' => $imageName
]);
}
}
}
And its view which as an important detail remembers to place the field for the dates as date type in HTML:
resources/views/livewire/dashboard/post/save.blade.php
<div>
<div class="container">
<x-action-message on="created">
<div class="box-action-message">
{{ __('Created post success') }}
</div>
</x-action-message>
<x-action-message on="updated">
<div class="box-action-message">
{{ __('Updated post success') }}
</div>
</x-action-message>
<x-form-section submit='submit'>
<x-slot name="title">
{{ __('Post') }}
</x-slot>
<x-slot name="description">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Neque hic voluptates quaerat accusantium a. Est
voluptate voluptatibus necessitatibus a non iure rerum, nesciunt nisi assumenda quaerat nam incidunt ab.
Facilis.
</x-slot>
@slot('form')
<div class="col-span-10 sm:col-span-3">
<x-label for="">Title</x-label>
<x-input type="text" wire:model.live='title' class="w-full" />
@error('title')
{{ $message }}
@enderror
</div>
<div class="col-span-10 sm:col-span-3">
<x-label for="">Date</x-label>
<x-input type="date" wire:model='date' class="w-full" />
@error('date')
{{ $message }}
@enderror
</div>
<div class="col-span-10 sm:col-span-3">
<x-label for="">Description</x-label>
<textarea wire:model='description' class="block w-full"></textarea>
@error('description')
{{ $message }}
@enderror
</div>
<div class="col-span-10 sm:col-span-3">
<x-label for="">Text</x-label>
<textarea wire:model='text' class="block w-full"></textarea>
@error('description')
{{ $message }}
@enderror
</div>
<div class="col-span-10 sm:col-span-3">
<x-label for="">Posted</x-label>
<select class="block w-full" wire:model='posted'>
<option value=""></option>
<option value="yes">Yes</option>
<option value="not">Not</option>
</select>
@error('posted')
{{ $message }}
@enderror
</div>
<div class="col-span-10 sm:col-span-3">
<x-label for="">Type</x-label>
<select class="block w-full" wire:model='type'>
<option value=""></option>
<option value="Advert">Advert</option>
<option value="post">Post</option>
<option value="course">Course</option>
<option value="movie">Movie</option>
</select>
@error('type')
{{ $message }}
@enderror
</div>
<div class="col-span-10 sm:col-span-3">
<x-label for="">Category</x-label>
<select class="block w-full" wire:model='category_id'>
<option value=""></option>
@foreach ($categories as $c)
<option value="{{ $c->id }}">{{ $c->title }}</option>
@endforeach
</select>
@error('category')
{{ $message }}
@enderror
</div>
<div class="col-span-10 sm:col-span-3">
<x-label for="">Image</x-label>
<x-input type="file" wire:model='image' class="w-full" />
@error('image')
{{ $message }}
@enderror
@if ($post && $post->image)
<img class="w-40 my-3" src="{{ $post->getImageUrl() }}" alt="{{ $post->title }}">
@endif
</div>
@endslot
@slot('actions')
<x-button type="submit">Send</x-button>
@endslot
</x-form-section>
</div>
</div>
In this short section as I mentioned in the introduction we are going to want to do the crud for our posts It is something that should be done relatively quickly Although we have more fields because we already did the crud for the categories we are going to take advantage of this in the next section where we will work with the filters and the search fields Therefore you could take this section as a challenge completely as a practice what we did before and there you develop it as you want from scratch expand what we already have for the categories etc and obviously I am going to try to move forward as quickly as possible because it is already seen material So I am going to replace what we already have Remember that every time it is a challenge it is basically replicating and adapting what we already have so I am going to try to move forward as much as possible because of what was mentioned before because it is a topic that we have already seen So in this part we are going to start with the save part that is save and update or create and update therefore we have to create the routes Well here I will show you quickly
We have to create the routes for this purpose in this case well you can create everything at once But they would be these two and you leave this one commented for the Index we add the link here in the navigation menu Here also for the responsive which is good Here I think I dont reference it right now I check and here also the part of The save of course is the component in Yes with all the new Fields The upload Of course is its view which would be good this would be the most tedious part curiously that is the pile of html even a component could be created for this an anonymous component in this case a Laravel component to avoid all this pile of classes could be interesting but it would be a mess there with the Textareas and the inputs and passing the type Well especially the textarea and the inputs but well there it could be it could be that it is defined as a slot or something like that I dont know but suddenly we see it later as some challenge or something at the moment we can replicate everything as we have it so well expressed what is expressed go ahead well perfect lets go there
Lets start here by defining the fields We have a public property for the date here Im going to duplicate it several times Here Im going to put for the Well Im going to put the title here first to continue the game that we have below here Im going to put the loot we can autogenerate it so that we have a field Im going to put the description The text I think is here below here it is here below Im going to put the text here the type Here is type and poed I put type I put posted I put category ID and we put the image I think I didnt put it no I didnt put one missing we put image Ah we already have the fields they would be all of them
class Save extends Component
{
use WithFileUploads;
public $title;
public $date;
public $text;
public $description;
public $posted;
public $type;
public $category_id;
public $image;
Perfect I can close this and lets go here Here you will allow me to already define the fields to duplicate what we already have Because if not we will take a world here and I dont want to take so much time here the initialization part I will bring this and we will start from this then Here more or less this same thing The image is fine all this we have to add here some like the date would be I dont want to worry too much I will simply indicate that it is a required field but we could do something with the format but again that is not the idea Anything if you are interested you can request it for the end of the course since I do not want it is not something specific to Livewire then I want to exploit what we have in lightware category ID a bit the same Sorry here it was not category ID the post also duplicate from here since it is the same that has been required the tex here we already have it in this case if it is going to be required because it would be the content that we are going to place to place it here above inclusive and the image we are going to keep it as it is then I review here quickly title I missed the description I put description here 255 Here Im going to put up to 5000 you can actually put whatever you want or just remove it but since its the long text field we put the category ID posted text and image perfect lets go with the part of the mount here we look for its obviously for the post so well no Music this curiously doesnt find it Ah no Here is the category Well it was deleted for some reason well we havent imported it Better said over here Im going to duplicate this several times over here Im going to put the same thing that we have above we put category ID we put posted we put type we put the image obviously we dont put description and to see I think to see the date is missing I think with this it would be all
Perfect now here we finish the initialization lets go with the submit part and also the lad theres nothing else perfect Im going to copy this come back here and put it right We continue here adapting to see no if I can bring this no I cant bring it well I come back here I duplicate here several times we put description we put here the category ID we put the date for I dont want to forget we put the type we put the posted and thats it
class Save extends Component
{
public function submit()
{
// validate
$this->validate();
}
}
Very important the slot this would be bu this would be for upate if we can Well here it depends on you as I am an example application Well here is the slug sorry I will also update it but that would be a topic that should be elaborated a little more because if it is a blog type application and we change the title usually we do not want to change the slug because there you lose the positioning strength that you had for the original publication but that is an seo factor I do not want to mix so many things and it is up to you how you want to do any questions and you can comment I place post I place well all the content that we brought here we create the image would be here publish it the folder that we created before the extension and the rest and here we update our post Well here also okay important point Here also from the part of The render would be We also have to get the categories here an important detail categories will be equal to category points colon get and I pass the categories here we import There it is perfect in principle this would be all
Lets go with the heaviest part for me which would be the one you know to see here it is here we have it so again I apologize Im going to start from what we already have Because I dont want this to last half an hour I put it here then Well here I change to pos there it changes post here it would be post title that you want to put the title the text image perfect we dont put it well we put the rest of the fields well here Lets start with the date I put date here it would be date too and date also the text Okay here we have it the next one would be the description that would be similar to the texar that we have This is an n input also that we put for here We dont put the textaare Well here Im going to look for In the same way in case I dont see it textarea for with the zoom no there is nothing good here we had to use fexar in an input since we have more text functionally it is the same but obviously a Tex aras is more comfortable Im going to bring all this Im going to put it here and additionally Im going to put it as blot type so that it occupies the entire width all the as who says the row would be very perfect this same thing would be for the content I am going to remove this I say this same thing would be for the description that I am going to place better above description here I place description Well I cant use the multicursor if not it will change in many parts this doesnt go I was left here dead and here also perfect we would be missing the Select this is going to be the last one that I am going to leave Simply because I like to organize it this way lets go with the Select I am going to start with the type I place here type I place type Here also and here type Sorry here type doesnt go here right away we kill this one we place the Select here we indicate some classes the same ones that we have above a blot so that we are 100 sure that it will occupy the entire row and a with full so that it occupies the entire width here we place the option Well this depends a bit on you I always place a dead option here and from here I place the options I am going to place Yes you can also use the Translate of laravel if you want and not perfect lets go with the next field that would be good this was sorry I mixed it up This was the one posted posted here I also did not place the question this posted and posted this would be the type I put it Here also the type and here we handle the different types that we have placed that hopefully not of advertising as it is said this Would be for post duplicate here Well if not select it this would be the course and this would be the movie good pending that they are the same values that you have there in the in the migration if not it will give you an error there for the relationship that does not Count the types and is in principle missing from the category also already with this would be practically everything here would be the field the category ID category category ID here we use the forage the B for each and over here would be the category we put category I put categories I bring here the option here we print by the ID well the Cid that we print the title It would be thet well I think that would be everything over here it seems to me
The style it depends on you it appears like this because here we have or for the form here we have the grid Remember that this component that we are expanding to see where it is here is the form section it works based on a grid here are the grids and here we are using a grid of type three you could put four here for example and there it takes up more space well four no sorry it would be six so that it takes up the entire width since it is six and you would go like this for the rest of the fields if that is what you really want I dont care now the presentation is here we have everything Ill give it a go lets see what happens I already gave another error it says that the day property has not been found How strange because if I placed the validation and I think that I also placed the field and no I did not place the field Poor thing I deleted her I put date there Perfect Well Ill put anything here quickly to see if we can finish well This happens if we put the input of type date this is already html And surely it changes the style according to the browser and operating system I am going to put post and the categories we are sending and another nice error here it says that it did not find the route dashboard post save which in theory is the one we have created here here we call it dashboard post to create and then to see here It would be to see Oh no sorry This is not the route this is the category property that indicates what it is going to do correct here it indicates that it did not find the category Okay sure here this one I did not change this one and here is post I simply saw the fields and I did not see the property and it deleted the Data what a shame we come again we hit send and it seems that I think then And at least there we have something we check the database here there it is I am going to create another to have something in the list and that is all it takes so with this we are going to go to the list part But we do that in the next class
- Andrés Cruz
Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter
I agree to receive announcements of interest about this Blog.
!Courses from!
10$
On Udemy
There are 1d 16:42!
!Courses from!
4$
In Academy
View courses!Books from!
1$
See the books