Laravel 11 Livewire 3: Build a Complete CRUD Application with Forms

featured_img1737365887.webp

Laravel 11 Livewire 3: Build a Complete CRUD Application with Forms

Table of Contents

    What is Livewire?

    Livewire is a full-stack framework for Laravel that allows you to build dynamic interfaces directly in PHP. It eliminates the need for complex JavaScript, offering a simple yet powerful way to enhance your applications.

    In this tutorial, we’ll walk through creating a CRUD application for managing categories. The application includes features such as:

    • Category creation, updating, and deletion
    • Dynamic form validation
    • File uploads
    • Parent-child category relationships

    This guide ensures a beginner-friendly and practical approach to using Laravel Livewire.

    Step 1: Setting Up the Laravel Project

    1. Create a New Laravel Application

      Run the following command to create a fresh Laravel application

                                                  
                                                      composer create-project laravel/laravel CategoryManagementSystem
                                                  
                                                  
    2. Configure Database

      Open the .env file and update your database details:

                                                  
                                                      DB_CONNECTION=mysql
                                                      DB_HOST=127.0.0.1
                                                      DB_PORT=3306
                                                      DB_DATABASE=<DATABASE NAME>
                                                      DB_USERNAME=<DATABASE USERNAME>
                                                      DB_PASSWORD=<DATABASE PASSWORD>
                                                  
                                                  

    Step 2: Create a Database and Model

    1. Generate a Model and Migration

      Run the following command to create the Category model and migration file:

                                                  
                                                      php artisan make:model Category -m
                                                  
                                                  
    2. Define the Migration Schema

      Update the database/migrations/xxxx_xx_xx_create_categories_table.php file:

                                                  
                                                          public function up(): void
                                                          {
                                                              Schema::create('categories', function (Blueprint $table) {
                                                                  $table->id();
                                                                  $table->foreignId('parent_id')->nullable()->constrained('categories')->onDelete('cascade');
                                                                  $table->string('name')->index();
                                                                  $table->string('slug')->unique()->index();
                                                                  $table->text('description')->nullable();
                                                                  $table->string('image')->nullable();                                                           
                                                                  $table->boolean('status')->default(true);  
                                                                  $table->timestamps();
                                                              });
                                                          }
                                                  
                                                 
    3. Run the Migration

      Execute the migration to create the categories table:

                                                  
                                                      php artisan migrate
                                                  
                                                  
    4. Update the Category Model

      Define relationships and fillable fields in app/Models/Category.php:

                                                  
                                                      namespace App\Models;
                                                      
                                                      use Illuminate\Database\Eloquent\Factories\HasFactory;
                                                      use Illuminate\Database\Eloquent\Model;
                                                      
                                                      class Category extends Model
                                                      {
                                                          use HasFactory;
                                                      
                                                          protected $table = 'categories';
                                                      
                                                          protected $fillable = ['parent_id','name','slug','description','image','status'];
                                                      
                                                          public function parent()
                                                          {
                                                              return $this->belongsTo(Category::class, 'parent_id');
                                                          }
                                                      
                                                          public function children()
                                                          {
                                                              return $this->hasMany(Category::class, 'parent_id');
                                                          }                                                
                                                          
                                                      }                                               
                                                  
                                                  

    Step 3: Installing Livewire V3

    Install Livewire in Laravel with the following command in your application root directory

    Next, install Livewire using this command:

                                        
                                            composer require livewire/livewire
                                        
                                        

    Step 4: Creating a Template Layout

    Generate a layout file:

                                        
                                            php artisan livewire:layout
                                        
                                        

    This will create resources/views/components/layouts/app.blade.php. Customize it with Bootstrap and Livewire assets:

                                        
                                            <!doctype html>
                                            <html lang="en">
                                            <head>
                                                    <meta charset="UTF-8">
                                                    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
                                                    <title>Category Management System</title>
                                                    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
                                            </head>
                                            <body>
                                                    @yield('content')
                                                    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
                                                    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
                                            </body>
                                            </html>                                       
                                        
                                        

    Step 5: Reusable Form Component

    Livewire provides a dedicated command to create reusable form components. The CategoryCreateEditForm will handle the validation logic for creating and editing categories. Follow the steps below:

    1. Generate the Form Component

      Run the following command to generate the form:

                                                  
                                                      php artisan livewire:form CategoryCreateEditForm
                                                  
                                                  

      This command creates the following file:

    2. Update the Form Logic

      Open the generated file CategoryCreateEditForm.php and update it as follows:

                                                  
                                                      namespace App\Livewire\Forms;
                                                      
                                                      use Livewire\Attributes\Validate;
                                                      use Livewire\Form;
                                                      use App\Models\Category;
                                                      use Illuminate\Support\Str;
                                                      class CategoryCreateForm extends Form
                                                      {     
                                                          #[Validate] public $parent_id = "";
                                                          #[Validate] public $name = "";  
                                                          #[Validate] public $description = "";  
                                                          #[Validate] public $status = 1;   
                                                          #[Validate] public $image;
                                                      
                                                      
                                                          public function rules($modal_primary_id = null)
                                                          {
                                                              return [          
                                                                  'name' => ['required', 'string', 'max:255', 'unique:categories,name,' . ($modal_primary_id ?? 'NULL')],
                                                                  'image' => ['nullable', 'image', 'max:2048', 'mimes:jpeg,png,jpg,gif,svg'],
                                                              ];
                                                          }
                                                    
                                                          public function messages()
                                                          {
                                                              return [        
                                                                    'name.required' => 'The name field is required.'          
                                                              ];
                                                          }
                                                     
                                                          public function store($modal_primary_id = null){        
                                                           
                                                              $rules = $this->rules($modal_primary_id);
                                                              $this->validate($rules, $this->messages());
                                                      
                                                              $slug = Str::slug($this->name);
                                                           
                                                              $input_data= [  
                                                                  'name' => $this->name,
                                                                  'description' => $this->description,
                                                                  'status' => $this->status            
                                                              ];      
                                                      
                                                              if(!empty($this->parent_id)){
                                                                  $input_data['parent_id'] = $this->parent_id;
                                                              }                                                
                                                      
                                                              if(!$modal_primary_id){
                                                                  $input_data['slug'] = $slug;
                                                              }                                                
                                                      
                                                              if($this->image){
                                                                  $input_data['image'] = $this->storeImage($this->image, 'catgory_img', 'uploads/Categories/');
                                                              }
                                                             
                                                              Category::updateOrCreate(['id' => $modal_primary_id], $input_data);
                                                     
                                                              $this->reset();
                                                          }
                                                      
                                                      
                                                          protected function storeImage($image, $prefix, $path)
                                                          {
                                                              if ($image) {
                                                                  $filename = $prefix . time() . '.' . $image->getClientOriginalExtension();
                                                                  $image->storeAs($path, $filename, 'public');
                                                                  return $filename;
                                                              }
                                                          }
                                                      }
                                                     
                                                  
                                                  
    3. Using the Form in Components

      To use this form in your Create and Edit components:

      Import the form and define it in your component:

                                                  
                                                      use App\Livewire\Forms\CategoryCreateEditForm;
                                                      class Create extends Component
                                                      {
                                                        public CategoryCreateEditForm $form;
                                                  
                                                  

      Access form properties and methods using $this->form, e.g., $this->form->store()

    4. Benefits of Using a Form Component

      • Reusability: The same form logic can be used for creating and editing categories.
      • Centralized Validation: All validation logic resides in one place, reducing redundancy.
      • Ease of Maintenance: Any updates to the form logic or design are reflected across all components.

    Step 6: Creating Livewire Components for CRUD Operations

    To manage categories with CRUD functionality, we’ll create multiple Livewire components. Each component will handle specific tasks, such as listing, creating, editing, and deleting categories. Below are the detailed steps:

    1. Category Listing

      Run the following command to generate the Category/Index component:

                                                      
                                                          php artisan make:livewire Category\\Index
                                                      
                                                  

      This will create the following files:

      Update the Component Logic (Index.php)

      Edit the Index.php file to handle data fetching and listing categories.

                                                      
                                                              namespace App\Livewire\Category;
      
                                                              use Livewire\Component;
                                                              use Livewire\WithPagination;
                                                              use Livewire\WithoutUrlPagination;
                                                              use Livewire\Attributes\{Computed,On,Locked,Title};
                                                              use Illuminate\Support\Facades\Auth;
                                                              use App\Models\Category;                                                   
      
                                                              class Index extends Component
                                                              {
                                                                  use WithPagination, WithoutUrlPagination;
      
                                                                  public $page_id = "";  
                                                                  public $is_show_details_page = false;
                                                                  public $edit_page_id = "";
                                                                  public $is_show_create_edit_page = false;
                                                                  public $parent_id;
      
                                                                  public function mount($parent_id=null){
                                                                      if($parent_id){
                                                                          $this->parent_id = base64_decode($parent_id);
                                                                      }      
                                                                       $this->authorizeAdminUser();                                                                
                                                                  }
      
                                                                  public function render()
                                                                  {
                                                                      $component_records =  $this->getCategoryData();
                                                                      return view('livewire.category.index', [
                                                                          'component_records' => $component_records
                                                                      ])
                                                                      ->extends('layouts.app')
                                                                      ->title('category');
                                                                  }
                                                               
                                                                  protected function authorizeAdminUser()
                                                                  {
                                                                      $user = Auth::guard('admin')->user();
                                                                      if (!$user || !$user->hasAnyRole(['super-admin', 'admin', 'blog-manager'])) {
                                                                          abort(403);
                                                                      }
                                                                  }
      
                                                                  protected function getCategoryData(){
                                                                  
                                                                      $new_query = Category::query();    
                                                                      if(!empty($this->parent_id)){
                                                                          $new_query = $new_query->where('parent_id',$this->parent_id);
                                                                      }else{
                                                                          $new_query = $new_query->whereNull('parent_id');
                                                                      }  
                                                                      if(!empty($this->filter_search)){
                                                                          $new_query = $new_query->where("name","LIKE","%".$this->filter_search."%");
                                                                      }
                                                                      if($this->filter_status!==""){
                                                                          $new_query = $new_query->where("status",'=', $this->filter_status);
                                                                      }
                                                                      if(!empty($this->filter_from_date) && !empty($this->filter_to_date)){
                                                                          $new_query = $new_query->whereBetween('created_at', [$this->filter_from_date, $this->filter_to_date]);
                                                                      }  
                                                                      $records = $new_query->latest()->paginate(10);
                                                                      return $records;
                                                                  }
      
                                                                  #[On('delete-category')] 
                                                                  public function delete($id)
                                                                  {
                                                                      $this->authorizeAdminUser(); 
                                                                      try {         
                                                                              $id = base64_decode($id);
                                                                              $record = Category::with('children')->where("id",$id)->first();
                                                                          if($record){
                                                                              $record->delete();
                                                                              session()->flash('success','Category removed successfully!');
                                                                          }else{
                                                                              session()->flash('error','Something goes wrong!!');
                                                                          }
                                                                          $this->resetPage(); 
                                                                          } catch (\Exception $ex) {
                                                                              session()->flash('error','Something goes wrong!!');
                                                                          }
                                                                  }
      
                                                                  public function showDetailsPage($id){
                                                                      $this->is_show_details_page = true;
                                                                      $this->page_id = $id;
                                                                      $this->dispatch('open-details-page-modal');   
                                                                  }
      
                                                                  public function closeDetailsPage(){
                                                                      $this->is_show_details_page = false;
                                                                      $this->dispatch('close-details-page-modal');  
                                                                  }
                                                                  
                                                                  public function showCreateEditModal($id=null){
                                                                      $this->edit_page_id = $id;        
                                                                      $this->is_show_create_edit_page = true;   
                                                                      $this->dispatch('open-edit-page-modal');   
                                                                  }    
      
                                                                  #[On('close-category-create-modal')]
                                                                  public function closeaddCategoryModal(){ 
                                                                      $this->page_id = null;
                                                                      $this->edit_page_id = null;  
                                                                      $this->is_show_create_edit_page = false;    
                                                                      $this->resetPage();       
                                                                      $this->dispatch('refresh-category-create-modal'); 
                                                                  }
                                                              }
                                                            
                                                      
                                                  

      Update the Component View (index.blade.php)

      Edit the index.blade.php file to design the UI for displaying the category list.

                                                      
                                                                                                                                                                
                                                              <div>
                                                                  <section class="section">
                                                                      <div class="card">
                                                                          <div class="card-header">
                                                                              <div class="float-start">
                                                                                  Category List
                                                                              </div>
                                                                              <div class="float-end">
                                                                              @if(empty($this->parent_id))  
                                                                              <button type="button" data-bs-toggle="tooltip" title="Add Category" class="btn btn-primary btn-sm my-2"  wire:click="showCreateEditModal()">
                                                                                  <i class="bi bi-plus-circle"></i> Add New Category
                                                                              </button>                                                                       
                                                                              @else
                                                                                  <a href="{{ route('categories') }}" class="btn btn-primary btn-sm" wire:navigate>&larr; Back</a>
                                                                              @endif
                                                                              </div>
                                                                          </div>
                                                                          <div class="card-body">
                                                                              <div class="table-responsive">
                                                                              <table class="table table-striped table-bordered">
                                                                                  <thead>
                                                                                      <tr>
                                                                                          <th scope="col">S#</th>
                                                                                          <th scope="col">NAME</th>
                                                                                          <th scope="col">SLUG</th>
                                                                                          <th scope="col">DESCRIPTION</th>
                                                                                          <th scope="col">STATUS</th>
                                                                                          <th scope="col">Date</th>
                                                                                          @if(empty($this->parent_id))
                                                                                          <th scope="col">Manage Sub Category</th>
                                                                                          @endif
                                                                                          <th scope="col">ACTION</th>
                                                                                      </tr>
                                                                                  </thead>
                                                                                  <tbody>
                                                                                      @if(count($component_records) > 0)
                                                                                      @foreach ($component_records as $key=>$record)
                                                                                      <tr wire:key="{{"role-".$key}}">
                                                                                          <th scope="row">{{ $loop->iteration }}</th>
                                                                                          <td>{{ $record->name }}</td>
                                                                                          <td>{{ $record->slug }}</td>
                                                                                          <td>{{ $record->description }}</td>
                                                                                          <td>
                                                                                              @if($record->status==1)
                                                                                                  <span class="badge bg-success">Active</span> 
                                                                                              @else
                                                                                              <span class="badge bg-danger">Inactive</span>
                                                                                              @endif
                                                                                          </td>               
                                                                                          <td>{{  !empty($record->created_at) ? date('Y-m-d', strtotime($record->created_at)) : '' }}</td>
                                                                                          @if(empty($this->parent_id))
                                                                                          <td><a class="" href="{{route('categories', ['parent_id' => base64_encode($record->id)])}}">Child Category</a></td>
                                                                                          @endif
                                                                                          <td>    
                                                                                              <button data-bs-toggle="tooltip" title="View Details" wire:click="showDetailsPage('{{base64_encode($record->id)}}')" class="btn btn-warning btn-sm m-1"><i class="bi bi-eye"></i></button> 
                                                                                             
                                                                                              <button data-bs-toggle="tooltip" title="Edit Category" wire:click="showCreateEditModal('{{base64_encode($record->id)}}')" class="btn btn-primary btn-sm m-1"><i class="bi bi-pencil-square"></i> </button>
                                                                                             
                                                                                              <button data-bs-toggle="tooltip" title="Remove Category"  wire:click="$dispatch('delete-category', { id: '{{ base64_encode($record->id) }}' })"
                                                                                                          class="btn btn-danger btn-sm" 
                                                                                                          wire:confirm="Are you sure you want to delete this record?"><i class="bi bi-trash"></i> </button>
                                                                                                     
                                                                                          </td>
                                                                                      </tr>
                                                                                      @endforeach
                                                                                      @else
                                                                                          <tr>
                                                                                              <td colspan="7">
                                                                                                  <span class="text-danger">
                                                                                                      <strong>Record does not exist.</strong>
                                                                                                  </span>
                                                                                              </td>
                                                                                          </tr>
                                                                                      @endif
                                                                                  </tbody>
                                                                              </table>
                                                                              </div>
                                                                              {{$component_records->links(data:['scrollTo' => '#paginated-section'])}} 
                                                                          </div>
                                                                      </div>
                                                                  </section>
                                                              
                                                                  @if($is_show_create_edit_page)
                                                                  <livewire:category.create :edit_page_id="$edit_page_id"/>  
                                                                  @endif  
                                                                  
                                                                  @if($is_show_details_page)
                                                                  <livewire:category.show :id="$page_id" />
                                                                  @endif
                                                              
                                                              </div>
                                                              
                                                              @script
                                                              
                                                              
                                                              $wire.on('close-details-page-modal', event => {
                                                                  console.log("event-close",event);
                                                                  $('#categoryDetailsPageModal').modal('hide');
                                                              });
                                                              
                                                              $wire.on('open-details-page-modal', event => {
                                                                      setTimeout(() => {
                                                                          $('#categoryDetailsPageModal').modal('show');
                                                                      }, 100);
                                                              });
                                                              
                                                              $wire.on('open-edit-page-modal', event => {
                                                                      setTimeout(() => {
                                                                          $('#addCategoryModal').modal('show');
                                                                      }, 100);
                                                              });
                                                              
                                                              $wire.on('browser-event-status-update-success', event => {
                                                                  console.log("event",event);
                                                                      Toastify({
                                                                          text: "Success",
                                                                          duration: 3000,
                                                                          close: true,
                                                                          gravity: "top",
                                                                          position: "center",
                                                                          backgroundColor: "#4fbe87",
                                                                      }).showToast()
                                                              
                                                                  if(event.action_modal_close){
                                                                      $('#addCategoryModal').modal('hide');
                                                                  }
                                                              });
                                                              
                                                              
                                                              @endscript                                                         
                                                                                                               
                                                      
                                                  
    2. Category Creation & Editing

      Run the following command to generate the Category/Create component:

                                                      
                                                          php artisan make:livewire Category\\Create
                                                      
                                                  

      This will create the following files:

      Update the Component Logic (Create.php)

      Edit the Create.php file to include:

      • Form properties (e.g., name, description, status, etc.).
      • Validation rules for the input fields.
      • A method to handle form submission and save category data.
                                                      
                                                             namespace App\Livewire\Category;
      
                                                              use Livewire\Component;
                                                              use App\Livewire\Forms\CategoryCreateEditForm ;
                                                              use Livewire\Attributes\{Computed,On,Locked,Title,Reactive};
                                                              use Illuminate\Support\Facades\Auth;
                                                              use App\Models\Category;
                                                              use Livewire\WithFileUploads;                                                        
      
                                                              class Create extends Component
                                                              {
      
                                                                  use WithFileUploads;
                                                                  public CategoryCreateEditForm  $form;  
                                                                  public $edit_page_id;
      
                                                                  public function mount($edit_page_id = null){
                                                                      $this->authorizeAdminUser();
                                                                      if($edit_page_id){            
                                                                          $this->edit_page_id = base64_decode($edit_page_id);
                                                                          $this->initializeFormFields();
                                                                      }
                                                                  }
      
                                                                  public function render()
                                                                  {
                                                                      $categories = Category::whereNull('parent_id')->where('status',1)->get();
      
                                                                      return view('livewire.category.create',[
                                                                          "categories" => $categories                                                                   
                                                                      ])->extends('layouts.app')->title('category create');
                                                                  }
      
                                                                  protected function authorizeAdminUser()
                                                                  {
                                                                      $user = Auth::guard('admin')->user();
                                                                      if (!$user || !$user->hasAnyRole(['super-admin', 'admin'])) {
                                                                          abort(403);
                                                                      }
                                                                  }
      
                                                                  protected function initializeFormFields()
                                                                  {
                                                                      $category = Category::where("id",$this->edit_page_id)->first();
                                                                      if ($category) { 
                                                                          $this->form->fill([                                                                      
                                                                              'parent_id' => $category->parent_id,
                                                                              'name' => $category->name,
                                                                              'description' => $category->description,                                                                      
                                                                              'status' => $category->status,
                                                                          ]);
                                                                  }
                                                                  }
      
                                                                  public function save(){
                                                                  
                                                                      $this->authorizeAdminUser();
                                                                      
                                                                      $this->form->store($this->edit_page_id); 
                                                                      $this->dispatch('close-category-create-modal');  
                                                                      $this->dispatch('browser-event-status-update-success', action_modal_close:true );         
                                                                  }
      
                                                                  #[On('refresh-category-create-modal')]
                                                                  public function reFreshPage(){        
                                                                      $this->form->reset();
                                                                      $this->dispatch('$refresh');
                                                                  } 
                                                              }
      
                                                      
                                                  

      Update the Component View (create.blade.php)

      Edit the create.blade.php file to design the form for category creation and updation.

                                                  
                                                                                               
                                                  <div wire:ignore.self class="modal fade text-left" id="addCategoryModal" tabindex="-1" role="dialog"
                                                  aria-labelledby="myModalLabel17" aria-hidden="true" data-bs-backdrop="static" 
                                                  data-bs-keyboard="false">
                                                  <div class="modal-dialog modal-dialog-centered modal-dialog-scrollable modal-md"
                                                      role="document">
                                                      <div class="modal-content">
                                                          <div class="modal-header">
                                                              <h4 class="modal-title" id="myModalLabel17">Add Category</h4>
                                                              <button  wire:ignore type="button" class="close" data-bs-dismiss="modal"
                                                                  aria-label="Close" wire:click="$parent.closeaddCategoryModal()">
                                                                  <span aria-hidden="true">×</span>
                                                              </button>            
                                                          </div>
                                                          <div class="modal-body">
                                                              <form wire:submit.prevent="save" enctype="multipart/form-data">
                                                                  @csrf                
                                                                  <div class="card m-0">
                                                                            <div class="card-body px-4">
                                                                              <div class="mb-3 row">
                                                                                  <label for="type" class="col-form-label">Parent Category</label>
                                                                                  <div class="">
                                                                                      <select class="form-select" id="parent_id" name="form.parent_id" wire:model.blur="form.parent_id">
                                                                                          <option disabled="disabled" value="">Please select an option</option>
                                                                                          @foreach ($categories as $key => $category)
                                                                                              <option wire:key="{{$category->id}}" value="{{ $category->id }}">
                                                                                                  {{ $category->name }}
                                                                                              </option>
                                                                                           @endforeach
                                                                                      </select>
                                                                                  @error('form.parent_id') <span class="error text-danger">{{ $message }}</span> @enderror   
                                                                                  </div>
                                                                              </div>
                                                  
                                                                                  <div class="mb-3 row" >
                                                                                      <label for="name" class="col-form-label text-start">Name</label>
                                                                                      <div class="">
                                                                                      <input type="text"  class="form-control" id="name" name="form.name"  placeholder="Name" wire:model.blur="form.name">
                                                                                      @error('form.name') <span class="error text-danger">{{ $message }}</span> @enderror   
                                                                                      </div>
                                                                                  </div>
                                                  
                                                                                  <div class="mb-3 row" >
                                                                                      <label for="name" class="col-form-label text-start">Description</label>
                                                                                      <div class="">
                                                                                      
                                                                                      @error('form.description') <span class="error text-danger">{{ $message }}</span> @enderror 
                                                                                      </div>
                                                                                  </div>  
                                                                                  
                                                                                  <div class="col-md-6">
                                                                                      <div class="form-group field mb-3">
                                                                                         <fieldset>
                                                                                             <div class="input-group mb-3">
                                                                                                 <label for="">Image</label>
                                                                                                 <div class="input-group mb-3">                                       
                                                                                                     <input type="file" name="image" class="form-control @error('image') is-invalid @enderror"  accept="image/*" wire:model.blur="form.image">
                                                                                                 </div>                                                
                                                                                             </div>
                                                                                             @error('form.image') <span class="error text-danger">{{ $message }}</span> @enderror 
                                                                                         </fieldset>                                           
                                                                                      </div>
                                                                                 </div>                                           
                                                  
                                                                                  <div class="form-group field mb-3">
                                                                                      <label for="">Status :  </label>
                                                                                      <div class="form-check form-check-inline pl-2">
                                                                                          <input class="form-check-input" type="radio" value="1" name="form.status" id="active" wire:model.blur="form.status" @checked($form->status=="1")>
                                                                                          <label class="form-check-label" for="active">
                                                                                              Active
                                                                                          </label>
                                                                                      </div>
                                                                                      <div class="form-check form-check-inline">
                                                                                          <input class="form-check-input" type="radio" value="0"  name="form.status" id="deactive" wire:model.blur="form.status" @checked($form->status=="0")>
                                                                                          <label class="form-check-label" for="deactive">
                                                                                              Deactive
                                                                                          </label>
                                                                                      </div>
                                                                                  </div>                                            
                                                  
                                                                             <div class="form-actions d-flex justify-content-end">
                                                                              <button type="submit" class="btn btn-primary" wire:offline.attr="disabled">Save <span wire:loading wire:target="save" class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> </button>
                                                                             </div>
                                                                          </div>
                                                                      </div>                          
                                                              </form>
                                                          </div>
                                                      </div>
                                                  </div>
                                                  </div>                                         
                                                   
                                                  
                                                  
    3. Category Details

      Run the following command to generate the Category/Show component:

                                                      
                                                          php artisan make:livewire Category\\Show
                                                      
                                                  

      This will create the following files:

      Update the Component Logic (Show.php)

      Edit the Show.php file to fetch and display a specific category's details.

                                                      
                                                              namespace App\Livewire\Category;
      
                                                              use Livewire\Component;
                                                              use App\Models\Category;
                                                              use Illuminate\Support\Facades\Auth;
      
                                                              class Show extends Component
                                                              {
      
                                                                  public $user_primary_id;
      
                                                                  public function mount($id){
                                                                      $this->authorizeAdminUser();
                                                                      $this->user_primary_id = base64_decode($id);
                                                                  }
      
                                                                  public function render()
                                                                  {
                                                                      $records_info = Category::where("id",$this->user_primary_id)->first();        
                                                                      return view('livewire.category.show', [
                                                                          "records_info" => $records_info
                                                                      ])->extends('layouts.app');
                                                                  }
      
                                                                  protected function authorizeAdminUser()
                                                                  {
                                                                      $user = Auth::guard('admin')->user();
                                                                      if (!$user || !$user->hasAnyRole(['super-admin', 'admin'])) {
                                                                          abort(403);
                                                                      }
                                                                  }
                                                              }
                                                      
                                                  

      Update the Component View (show.blade.php)

      Edit the show.blade.php file to Design the UI to display the category details.

                                                  
                                                  
                                                  <div wire:ignore.self>
                                                      <div class="modal fade" id="categoryDetailsPageModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel4" aria-hidden="true" data-bs-backdrop="static">
                                                           <div class="modal-dialog modal-dialog-slideout modal-md" role="document">
                                                             <div class="modal-content">
                                                               <div class="modal-header">
                                                                 <h5 class="modal-title" id="exampleModalLabel">Category Details  </h5>
                                                                 <button wire:ignore type="button" class="close" data-bs-dismiss="modal" aria-label="Close" wire:click="$parent.closeDetailsPage">
                                                                   <span aria-hidden="true">×</span>
                                                                 </button>
                                                               </div>
                                                               <div class="modal-body">
                                                                   <div class="b-sidebar-body">
                                                                       <p class="text-center font-bold d-block font-size-lg">Category</p>
                                                                       <div class="separator separator-dashed mb-2"></div>
                                                                       <div class="table-responsive pr-5 pl-5">
                                                  
                                                                          <table class="table table-head-custom table-head-bg table-vertical-center">
                                                                             <tbody>                            
                                                                                <tr>
                                                                                   <td><b>Name</b></td>
                                                                                   <td class="text-right fw-500"> {{ $records_info->name }}</td>
                                                                                </tr>
                                                                                <tr>
                                                                                  <td><b>Slug</b></td>
                                                                                  <td class="text-right fw-500">{{ $records_info->slug }}</td>
                                                                               </tr>
                                                                               <tr>
                                                                                  <td><b>Description</b></td>
                                                                                  <td class="text-right fw-500">{{ $records_info->description }}</td>
                                                                               </tr>                                                                        
                                                                               <tr>
                                                                                <td><b>Status</b></td>
                                                                                <td class="text-right fw-500"> 
                                                                                   @if($records_info->status==1)
                                                                                   <span class="badge bg-success">Active</span> 
                                                                                   @else
                                                                                   <span class="badge bg-danger">Deactive</span>
                                                                                   @endif
                                                                                </td>
                                                                             </tr>
                                                                                <tr>
                                                                                   <td><b>Date</b></td>
                                                                                   <td class="text-right fw-500">
                                                                                       {{  !empty($records_info->created_at) ? date('Y-m-d', strtotime($records_info->created_at)) : '' }}
                                                                                   </td>
                                                                                </tr>
                                                                                <tr>
                                                                                   <td><b>Image</b></td>
                                                                                   <td class="text-right fw-500">
                                                                                      @if(isset($records_info->image) && !empty($records_info->image))
                                                                                       <img src="{{ asset('uploads/Categories/'.$records_info->image) }}" class="img-fluid img-thumbnail" width="50" height="50"> 
                                                                                      @endif
                                                                                   </td>
                                                                                </tr>
                                                                               
                                                                             </tbody>
                                                                          </table>
                                                                       </div>
                                                                    </div>           
                                                               </div>
                                                            </div>
                                                       </div>
                                                      </div>                                           
                                                   
                                                  
                                                  

    Step 7: Setting Up Routes And Run Project

    1. Add Route

      Define the route in routes/web.php

                                                  
                                                      use App\Livewire\Category
                                                      //Module :: Category
                                                      Route::get('/categories', Category\Index::class)->name('categories');                                            
                                                  
                                              
    2. Run the Project

      Start the development server:

                                                  
                                                      php artisan serve                                         
                                                  
                                              
    3. Preview the Application

      Open your web browser and navigate to the following URL to view the code preview:

      Preview:

      Category Listing:

      Category Creation & Editing:

      Category Details:

    Conclusion

    Congratulations! You’ve successfully built a Laravel Livewire CRUD application. This tutorial demonstrated the integration of dynamic forms, file uploads, and parent-child category relationships. With Livewire, you can efficiently develop dynamic interfaces without relying heavily on JavaScript.

    Did this solution work for you? Drop a like or comment below!

    Satish Parmar

    Satish Parmar

    Experienced Full-Stack Web Developer

    I'm a passionate full-stack developer and blogger from India, dedicated to sharing web development tips and solutions. As the creator of TipInfoTrove.com, my goal is to help developers and tech enthusiasts solve real-world challenges with expertise in PHP, Laravel, JavaScript, Vue, React, and more. Through detailed guides and practical insights, I strive to empower others to excel in their projects and stay ahead in the ever-evolving world of technology.

    0 Comments

    Post Comment

    Your email address will not be published. Required fields are marked *