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
Step2: create liveware component in controller and blade file using commands
php artisan make:livewire CrudSearch
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
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();
}
}
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>
step 6: for update and create generate liveware component
php artisan make:livewire UpdateSearch
php artisan make:livewire CreateSearch
<!-- 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>
<!-- 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>
output
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>
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']);
}
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
Top comments (0)