Debug School

rakesh kumar
rakesh kumar

Posted on • Updated on

How to use pagination with filter using liveware

step1: this Blade template extends a layout file, defines a content section where the main content of the user profile page will go, and includes a Livewire component (crud-search) within a Bootstrap container to render dynamic content

@extends('layouts.apps')

@section('content')
    <!-- Your user profile content here -->
    <div class="container">
        <div class="row">
            <div class="col-md-8 offset-md-2">
                <div class="text-center">

                    @livewire('crud-search')
                </div>
            </div>
        </div>
    </div>
@endsection
Enter fullscreen mode Exit fullscreen mode

Step2: create liveware component in controller and blade file using commands

php artisan make:livewire CrudSearch
Enter fullscreen mode Exit fullscreen mode

it generates component in blade file as well in controller

\laravel_livewire_crud\resources\views\livewire\crud-search.blade.php

\laravel_livewire_crud\app\Livewire\CrudSearch.php
Enter fullscreen mode Exit fullscreen mode

step3: crud operation in liveware controller component with pagination and filter

<?php

namespace App\Livewire;

use App\Models\Search;
use Livewire\Component;
use Illuminate\Support\Facades\Log;
use Livewire\WithPagination; // Import WithPagination trait

class CrudSearch extends Component
{
    use WithPagination; // Use WithPagination trait
    public $post;
    public $title;
    public $description;
    public $price;
    public $postId;
    public $updateMode = false;
    public $q;


    public function mount()
    {
        $this->q = '';
        $this->fetchpost();
    }


    public function fetchpost()
{
    if (empty($this->q)) {
        return Search::paginate(10); // Return paginated results
    } else {
        return Search::where('title', 'like', '%' . $this->q . '%')
            ->orWhere('description', 'like', '%' . $this->q . '%')
            ->paginate(10);
    }
}


public function render()
{
    $posts = $this->fetchpost(); // Fetch posts and assign to $posts variable

    return view('livewire.crud-search', [
        'posts' => $posts,
    ]);
}

    private function resetInputFields(){
        $this->title = '';
        $this->description = '';
        $this->price = '';
    }
    public function create()    
    {
        $validatedDate = $this->validate([
            'title' => 'required',
            'description' => 'required',
            'price' => 'required',
        ]);  
        Search::create($validatedDate);  
        session()->flash('message', 'Post Created Successfully.');  
        $this->resetInputFields();
    }

    public function edit($id)
    {
        $post = Search::findOrFail($id);
        $this->postId = $id;
        $this->title = $post->title;
        $this->description = $post->description;
        $this->price = $post->price;
        $this->updateMode = true;
    }

    public function update()
    {
        $post = Search::find($this->postId);
        if ($post) {
            $post->update([
                'title' => $this->title,
                'description' => $this->description,
                'price' => $this->price,
            ]);  
            $this->updateMode = false;  
            session()->flash('message', 'Post Updated Successfully.');
            $this->resetInputFields();
        } else {
            // Handle the case where the post is not found
            session()->flash('message', 'Post not found.');
        }

    }



    protected function resetFormFields()
    {
        $this->title = '';
        $this->description = '';
        $this->price = '';
    }
    public function updatedq()
    {
        Log::info("Search term updated: " . $this->q);
        $this->fetchpost();
    }

    public function cancel()
    {
        $this->updateMode = false;
        $this->resetFormFields();
    }
}
Enter fullscreen mode Exit fullscreen mode

step 5: display data in blade component

<div>
    @if (session()->has('message'))
        <div class="alert alert-success">
            {{ session('message') }}
        </div>
    @endif
    @auth 
        @if($updateMode)
            @include('livewire.update-search')
        @else
            @include('livewire.create-search')
        @endif
    @endauth

    <div>
    <div class="form-group mt-3">
    <input type="text" wire:model.live="q"  class="form-control" placeholder="Search by Title or Body">
</div>
    <table class="table table-bordered mt-5">
        <thead>
            <tr>
            <th>Title</th>
                <th>Description</th>
                <th>Price</th>
                @auth 
                <th width="150px">Action</th>
                @endauth
            </tr>
        </thead>
        <tbody>
        @foreach($posts as $singlePost)
                <tr>

                    <td>{{ $singlePost->title }}</td>
                    <td>{{ $singlePost->description }}</td>
                    <td>{{ $singlePost->price }}</td>
                    @auth  
                        <td>
                            <button wire:click="edit({{ $singlePost->id }})" class="btn btn-primary btn-sm">Edit</button>
                            <button wire:click="delete({{ $singlePost->id }})" class="btn btn-danger btn-sm">Delete</button>
                        </td>
                    @endauth
                </tr>
            @endforeach
        </tbody>



    </table>
    <span>
            {{ $posts->links() }}
</span>
</div>
</div>
<script>
    document.addEventListener('livewire:load', function () {
        Livewire.on('updatedSearchTerm', function () {
            console.log("updatedSearchTerm event triggered");
        });

        Livewire.on('re-render', function () {
            console.log("Component re-rendered");
        });
    });
</script>   
Enter fullscreen mode Exit fullscreen mode

step 6: for update and create generate liveware component

php artisan make:livewire UpdateSearch

php artisan make:livewire CreateSearch
Enter fullscreen mode Exit fullscreen mode
<!-- livewire/create-search.blade.php -->

<div>
    <form wire:submit.prevent="create">
        <div class="form-group">
            <label for="title">Title:</label>
            <input type="text" wire:model.defer="title" class="form-control" id="title">
            @error('title') <span class="error">{{ $message }}</span> @enderror
        </div>
        <div class="form-group">
            <label for="description">Description:</label>
            <textarea wire:model.defer="description" class="form-control" id="description"></textarea>
            @error('description') <span class="error">{{ $message }}</span> @enderror
        </div>
        <div class="form-group">
            <label for="price">Price:</label>
            <input type="text" wire:model.defer="price" class="form-control" id="price">
            @error('price') <span class="error">{{ $message }}</span> @enderror
        </div>
        <button type="submit" class="btn btn-primary">Create</button>
    </form>
</div>
Enter fullscreen mode Exit fullscreen mode
<!-- livewire/update-search.blade.php -->

<div>
    <form wire:submit.prevent="update">
        <div class="form-group">
            <label for="title">Title:</label>
            <input type="text" wire:model.defer="title" class="form-control" id="title">
            @error('title') <span class="error">{{ $message }}</span> @enderror
        </div>
        <div class="form-group">
            <label for="description">Description:</label>
            <textarea wire:model.defer="description" class="form-control" id="description"></textarea>
            @error('description') <span class="error">{{ $message }}</span> @enderror
        </div>
        <div class="form-group">
            <label for="price">Price:</label>
            <input type="text" wire:model.defer="price" class="form-control" id="price">
            @error('price') <span class="error">{{ $message }}</span> @enderror
        </div>
        <button type="submit" class="btn btn-primary">Update</button>
    </form>
</div>
Enter fullscreen mode Exit fullscreen mode

output

Image description

Image description

Image description

Custom pagination

Create a custom pagination view:
Create a new Blade file, let's call it custom-pagination.blade.php, and place it in your resources/views/components directory. In this file, customize the pagination view according to your requirements. If you want to remove the element, you can remove it from the SVG markup.

Example custom-pagination.blade.php:

<div>
    @if ($paginator->hasPages())
        <nav role="navigation" aria-label="{{ __('Pagination Navigation') }}" class="flex justify-between">
            <div>
                {{-- Previous Page Link --}}
                @if ($paginator->onFirstPage())
                    <span class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-l-md leading-5" aria-hidden="true" aria-disabled="true">
                        <span>{!! __('pagination.previous') !!}</span>
                    </span>
                @else
                    <button wire:click="previousPage" wire:loading.attr="disabled" rel="prev" class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-pointer rounded-l-md leading-5 focus:outline-none focus:ring ring-indigo-300 focus:border-indigo-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.previous') }}">
                        {!! __('pagination.previous') !!}
                    </button>
                @endif
            </div>

            <div>
                {{-- Next Page Link --}}
                @if ($paginator->hasMorePages())
                    <button wire:click="nextPage" wire:loading.attr="disabled" rel="next" class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-pointer rounded-r-md leading-5 focus:outline-none focus:ring ring-indigo-300 focus:border-indigo-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.next') }}">
                        {!! __('pagination.next') !!}
                    </button>
                @else
                    <span class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-r-md leading-5" aria-hidden="true" aria-disabled="true">
                        <span>{!! __('pagination.next') !!}</span>
                    </span>
                @endif
            </div>
        </nav>
    @endif
</div>
Enter fullscreen mode Exit fullscreen mode

Use the custom pagination view in your Livewire component:
In your Livewire component, specify the custom pagination view when rendering pagination links. You can do this by passing the name of the custom view to the links() method.

public function render()
{
    $posts = // Your pagination logic
    return view('livewire.your-component', [
        'posts' => $posts->paginate(),
    ])->layout('layouts.app', ['title' => 'Your Title']);
}
Enter fullscreen mode Exit fullscreen mode

Here, 'your-component' is the name of your Livewire component file, and 'layouts.app' is the layout file used to render the component.

By following these steps, you can create a custom pagination view and remove the element from the SVG icons in the pagination links. However, keep in mind that removing the element will result in pagination links without arrow icons.

How to adjust svg icon

<!-- resources/views/components/custom-pagination.blade.php -->
@if ($paginator->hasPages())
    <nav role="navigation" aria-label="{{ __('Pagination Navigation') }}" class="flex justify-between">
        <div>
            {{-- Previous Page Link --}}
            @if ($paginator->onFirstPage())
                <span class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-l-md leading-5" aria-hidden="true" aria-disabled="true">
                    <span>{!! __('pagination.previous') !!}</span>
                </span>
            @else
                <button wire:click="previousPage" wire:loading.attr="disabled" rel="prev" class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-pointer rounded-l-md leading-5 focus:outline-none focus:ring ring-indigo-300 focus:border-indigo-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.previous') }}">
                    <svg class="w-4 h-4 fill-current" viewBox="0 0 20 20">
                        <path d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" fill-rule="evenodd"></path>
                    </svg>
                </button>
            @endif
        </div>

        <div>
            {{-- Next Page Link --}}
            @if ($paginator->hasMorePages())
                <button wire:click="nextPage" wire:loading.attr="disabled" rel="next" class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-pointer rounded-r-md leading-5 focus:outline-none focus:ring ring-indigo-300 focus:border-indigo-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.next') }}">
                    <svg class="w-4 h-4 fill-current" viewBox="0 0 20 20">
                        <path d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" fill-rule="evenodd"></path>
                    </svg>
                </button>
            @else
                <span class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-r-md leading-5" aria-hidden="true" aria-disabled="true">
                    <span>{!! __('pagination.next') !!}</span>
                </span>
            @endif
        </div>
    </nav>
@endif
Enter fullscreen mode Exit fullscreen mode

refrence

Top comments (0)