Laravel 9 Livewire Pagination is not working at all - pagination

In my project(s) I want to make use of Livewire Pagination. I have setup everything according to the Livewire Docs. I make use of components to view everything.
I tried the same as you can find in the following code in my real projects, but nothing works.
Here is my code of a test setup (and also here nothing works):
Model User
<?php
namespace App\Models;
use App\Casts\UserRoleCast;
use App\Constants\UserRole;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Laravel\Jetstream\HasProfilePhoto;
use Laravel\Sanctum\HasApiTokens;
use Livewire\WithPagination;
class User extends Authenticatable
{
use HasApiTokens;
use HasFactory;
use HasProfilePhoto;
use Notifiable;
use TwoFactorAuthenticatable;
use WithPagination;
/**
* The attributes that are mass assignable.
*
* #var string[]
*/
protected $fillable = [ ....etc.....
UserPagination.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\User;
use Livewire\WithPagination;
class UserPagination extends Component
{
use WithPagination;
public function render()
{
return view('livewire.user-pagination', [
'users' => User::paginate(5)
])->layout('layouts.guest');
}
}
Blade view
<div>
<table class="table min-w-full mb-4">
<thead>
<tr class="border-b-2 border-gray-300">
<th class="px-6 py-3 text-left text-sm leading-4 tracking-wider">ID</th>
<th class="px-6 py-3 text-left text-sm leading-4 tracking-wider">Naam</th>
<th class="px-6 py-3 text-left text-sm leading-4 tracking-wider">Email</th>
<th class="px-6 py-3 text-left text-sm leading-4 tracking-wider">Password</th>
</tr>
</thead>
<tbody>
#forelse($users as $user)
{{-- <tr class="border-b border-gray-500" wire:key="user-{{ $user->id }}"> --}}
<tr class="border-b border-gray-500">
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5">
{{ $user->id }}
</td>
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5">
{{ $user->name }}
</td>
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5">
{{ $user->email }}
</td>
<td class="px-6 py-4 whitespace-no-wrap text-sm leading-5">
{{ $user->password }}
</td>
</tr>
#empty
<tr>
<td colspan="6" class="px-6 py-4 whitespace-no-wrap text-sm leading-5">Geen sponsors gevonden</td>
</tr>
#endforelse
</tbody>
</table>
{{ $users->links() }}
</div>
composer.json
"laravel/framework": "^9.19",
"laravel/jetstream": "^2.13",
"laravel/sanctum": "^3.0",
"laravel/tinker": "^2.7",
"livewire/livewire": "^2.5",
Furthermore
I have my #livewireStyles and my #livewireScripts at the right place. I know it's right, because the rest of the application is working.
But clicking on the links doesn't do anything. Nothing changes in de URI and nothing happens on screen.
What is wrong here? Why doesn't it working?
I tried everything according to the Livewire Docs and 'solutions' I found online.

SOLVED
I made a mistake by adding a use statement in the models, the use statement:
use WithPaginator
This is a Livewire trait and only for livewire components.
I removed the use statement and everything worked.
Another problem is when I load for example all Users with pagination in the mount method of a component I get an error. Solution here was to load all Users in de render method.

Related

The DELETE method is not supported for this route. Supported methods: GET, HEAD, POST. when deleting first item

I'm a beginner in Laravel 7. I am trying to create a checkout form when purchasing items. The problem is whenever I try to delete the first item the 'The DELETE method is not supported for this route. Supported methods: GET, HEAD, POST.' shows up. However, I am able to delete the following items under it that I put into the checkout form.
This is my CheckoutController
public function destroy($id)
{
Temp_order::where('id',$id)->delete();
return redirect('checkout')->with('success','Product deleted successfully');
}
And this is the code for the table
<tbody>
#forelse ($order as $item)
<tr>
<td id="item_code">{{ $item->item_code }}</td>
<td class="cart_product_img" id="image">
<img src="" alt="Unavailable" style="width: 70px; height:70px"></img>
</td>
<td id="item_name">
{{ $item->item_name }}
</td>
<td id="price">
₱ {{ number_format($item->price, 2) }}
</td>
<td class="qty" id="qty">
<div class="qty-btn d-flex">
<div class="quantity">
<input type="number" class="qty-text" id="qty" step="1" min="1" max="300" name="quantity" value="{{ $item->quantity }}">
</div>
</div>
</td>
<td id="subtotal">
₱ {{ number_format($item->subtotal, 2) }}
</td>
<td>
<form action="{{ route('checkout.destroy', $item->id) }}" method="post">
#csrf
#method('DELETE')
<button type="submit" class="btn btn-danger btn-sm">Remove</button>
</form>
</td>
</tr>
#empty
<tr>
<td>
<p> NO ITEMS IN CART </p>
</td>
</tr>
#endforelse
</tbody>
And this is my route
Route::get('/', function () {
return view('auth.login');
});
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
Route::resource('ordering', 'OrderingController')->middleware('auth');
Route::resource('inventory', 'InventoryController')->middleware('auth');
Route::resource('checkout', 'CheckoutController')->middleware('auth');
Can you help me masters?
Try to update CheckoutController
public function destroy(Temp_order $item)
{
$item->delete();
return redirect('checkout')->with('success','Product deleted successfully');
}

Bootstrap 4 - showing a list of items with texts and icons correctly

Using Bootstrap 4 I can create a list of list-items. Each list-item contains a text and a button with an icon. The icon is taken from Fontello.
On mobile screens (XS media) sometimes the button does not take the icon as button-content. The result is a very small button that does not contain the icon. This looks like on a mobile device:
On Chrome on my Desktop (F12, XS device) the result is as expected.
A diagnosis is: When I add a number of rows, then vertical size of the list-item gets smaller. Adding 10 items, and the list-item is just a few mm high! So, the size of the list-item gets less high, the button gets less high. Has this to do with 'flexbox'?
Why is this so? I know that when you omit to put anything (or any text) in the button, the button will remain very small. How to repair this?
The code for the button (inside Angular 6)
<ul class="list-group" id="cachesOnHikeList">
<li class="list-group-item d-flex flex-row" *ngFor="let cacheonhike of cachesonhike">
<div class="flex-grow-1">{{ cacheonhike.name| slice:0:22 }}</div>
<button type="button" class="btn btn-warning btn-sm" (click)="removeGeocache( cacheonhike.gcid)"><i class="icon-cancel-circled"></i></button>
</li>
</ul>
The 'cachesOnHikeList' CSS class is:
#cachesOnHikeList {
/*max-height: 250px;*/
max-height:35vh;
overflow:auto;
overflow-y:scroll;
}
Plan-B does not work either. This code (with 2 characters added as button text) produces the same results:
<button type="button" class="btn btn-warning btn-sm px-1"
(click)="removeGeocache( cacheonhike.gcid)"> <i class="icon-cancel-circled"></i> </button>
Plan-C: Adding a 'real' character as button text does not help. The 'X' is shown below the small button. The button is similar to the ones on the screenshot.
<button type="button" class="btn btn-warning btn-sm px-1 font-weight-bold"
(click)="removeGeocache( cacheonhike.gcid)">X</button>
The problem of the small buttons may be caused by (my/the) use of flexbox in combination with a scrollable list-groups
Solution 1:
Replace the flexbox solution with the BS4 grid.
<ul class="list-group" id="cachesOnHikeList">
<li class="list-group-item" *ngFor="let cacheonhike of cachesonhike">
<div class="row">
<div class="mr-auto">{{ cacheonhike.naam | slice:0:22 }}</div>
<button type="button" class="btn btn-warning btn-sm font-weight-bold col-2 col-sm-1 px-1" (click)="removeGeocache( cacheonhike.gcid)">X</button>
</div>
</li>
</ul>
Solution 2: responsive BS4 table
Using a Bootstrap 4 table that is Responsive. In this case the width of the columns is determine automatically by Bootstrap.
<div class="row mt-2">
<div class="listMaxEntries">
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>GcId</th>
<th>Naam</th>
<th class="d-none d-sm-table-cell">Type</th>
<th class="d-none d-md-table-cell">Actief</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let geocache of geocachesPage.geocaches"
(click)="saveGeocacheInApplicationDataAndEditIt( geocache)">
<td>{{ geocache.gcid | slice:0:9 }}</td>
<td>{{ geocache.naam }}</td>
<td class="d-none d-sm-table-cell">{{ geocache.type }}</td>
<td class="d-none d-md-table-cell">{{ geocache.actief }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
Solution 3: BS4 table with Flexbox.
Using this solution you can specify the column widths. In this case the row height is good!
<div class="row mt-2">
<div class="listMaxEntries">
<table id="productSizes" class="table">
<thead>
<tr class="d-flex">
<th class="col-3 col-md-2">GcId</th>
<th class="col-9 col-sm-7 col-md-5">Name</th>
<th class="col-sm-3 d-none d-sm-table-cell">Type</th>
<th class="col-md-2 d-none d-md-table-cell">Actief</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let geocache of geocachesPage.geocaches" class="d-flex"
(click)="saveGeocacheInApplicationDataAndEditIt( geocache)">
<td class="col-3 col-md-2">{{ geocache.gcid | slice:0:9 }}</td>
<td class="col-9 col-sm-7 col-md-5">{{ geocache.naam }}</td>
<td class="col-sm-3 d-none d-sm-table-cell">{{ geocache.type }}</td>
<td class="col-md-2 d-none d-md-table-cell">{{ geocache.actief }}</td>
</tr>
</tbody>
</table>
</div>
</div>
Enjoy Bootstrap 4 -- what a very nice package!

NotFoundHTTPException while pagination. Laravel

I'm trying to paginate my views. I have used following syntax to do that:
Route:
Route::get('Bill/view/month/history','BillController#monthHistory');
Controller:
public function monthHistory(Request $request)
{
$month= $request->month;
$bills=Bill::orderBy('created_at', 'desc')->where('month',$month)->paginate(7);
$bills->setPath('custom/url');
return view('Bill.monthResult',compact('bills'));
}
View:
<div class="row">
<div class="col-sm-12">
#section ('cotable_panel_title','Bills')
#section ('cotable_panel_body')
<table class="table table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Student</th>
<th>Grade</th>
<th>Month</th>
<th>Date Published</th>
<th>Amount</th>
<th>Paid</th>
<th>Balance</th>
<th>User</th>
</tr>
</thead>
<tbody>
#foreach($bills as $bill)
<tr class="info">
<td>{{$bill->id}}</td>
<td>{{$bill->student->first_name}}</td>
<td>{{$bill->grade->grade_name}}</td>
<td>{{$bill->month}}</td>
<td>{{$bill->date_published}}</td>
<td>{{$bill->amount}}</td>
<td>{{$bill->paid}}</td>
<td>{{$bill->fee_status}}</td>
<td>{{$bill->user}}</td>
</tr>
#endforeach
</tbody>
</table>
#endsection
#include('widgets.panel', array('header'=>true, 'as'=>'cotable'))
</div>
</div>
</div>
{!! $bills->render() !!}
While the Pagination works fine for the first page, When i click on next page it throws not foundhttpexception with URL:
http://localhost:8000/Bill/view/month/custom/url?page=2
How can i solve this problem? Can anyone help me?
you also need to have a GET route for
Route::get('Bill/view/month/history/custom/url','BillController#monthHistory');
in your routes file.
or you can do this to
use custom url as optional variables on your route as below.
Route::get('Bill/view/month/history/{custom?}/{url?}','BillController#monthHistory');
and do use set path like this in your controller
$bills->setPath('/Bill/view/month/history/custom/url');

Nested Repeaters Using Table Tags

I am using the following code to try and use nested repeaters in WinJS:
<table class="grid" id="rptCustomerHistory" data-win-control="WinJS.UI.Repeater">
<thead>
<tr>
<th colspan="4" class="groupHeader" data-win-bind="textContent: GroupDate.DateTime BindingConverter.toYearMonthDate"></th>
</tr>
</thead>
<tbody data-win-control="WinJS.UI.Repeater" data-win-bind="winControl.data: ch">
<tr>
<td data-win-bind="textContent: ContactDate.DateTime BindingConverter.toshortdate"></td>
<td data-win-bind="textContext: SalesPerson"></td>
<td data-win-bind="textContext: ContactMethod"></td>
<td><span class="symbol"></span></td>
</tr>
</tbody>
</table>
However, it is not rendering any results for the 2nd repeater.
When I use the same data source and similar markup using DIVs, it works:
<div id="rptCustomerHistory" data-win-control="WinJS.UI.Repeater">
<div>
<div data-win-bind="textContent: GroupDate.DateTime BindingConverter.toYearMonthDate"></div>
<div data-win-control="WinJS.UI.Repeater" data-win-bind="winControl.data: ch">
<span data-win-bind="textContent: ContactMethod"></span>
</div>
</div>
</div>
I don't really want to use Divs as this is tabular data. Any idea why using table tags behaves differently?
Did you assign give data to your outer repeater?
The following works in a blank project for me:
<script>
window.list = new WinJS.Binding.List([
new WinJS.Binding.List([1, 2, 3]),
new WinJS.Binding.List([4, 5, 6]),
]);
</script>
<div data-win-control="WinJS.UI.Repeater" data-win-options="{ data: list }">
<span data-win-control="WinJS.UI.Repeater" data-win-bind="winControl.data : this"></span>
</div>
Try replacing
data-win-bind="winControl.data: ch"
with:
data-win-options="{data: ch}"

Trying to use laravel pagination breaks my controller/view

I'm trying to get Pagination working in Laravel. I've not used pagination before so am trying to use some examples from the docs and google results. I'm wondering if I need to turn 'pagination' on somewhere in config.
Here's my simple working controller:
public function get_index() {
$locations = Location::all();
return View::make('location.index')->with('locations', $locations)->render();
}
When I try and add pagination like this it breaks:
public function get_index() {
$locations = Location::paginate(5);
return View::make('location.index')->with('locations', $locations)->render();
}
..and I get the error:
Unhandled Exception
Message:
Error rendering view: [location.index]
Trying to get property of non-object
Here's my location.index view:
#layout('layouts.blank')
#section('content')
<div class="row">
<div class="twelve columns">
<div role="main" id="content">
<h3>Locations - All</h3>
#if($locations)
<table class="twelve">
<thead>
<tr>
<th style="text-align: left;">Address</th>
<th>Area</th>
<th>Region</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
#foreach($locations as $location)
<tbody>
<tr>
<td style="text-align: left;">{{ $location->company,', ',$location->add_name,', ',$location->add_city }}</td>
<td> – </td>
<td> – </td>
<td>{{ HTML::link('location/update/'.$location->id, '',array('class'=>"foundicon-edit updateicon")) }}</td>
<td>{{ HTML::link('location/delete/'.$location->id, '',array('class'=>"foundicon-remove warnicon")) }}</td>
</tr>
</tbody>
#endforeach
</table>
#else
Looks like we haven't added any locations, yet!
#endif
<p>{{ HTML::link('location/create', 'Create a location', array('class'=>"small radius button")) }}</p>
</div>
</div>
</div>
#endsection
I hadn't read deeply enough into the subject. It's now working and here's what I had to change in the view:
//from:
#foreach($locations as $location)
//to:
#foreach($locations->results as $location)
That returned just 5 results. Then to add links to the footer of my table I added this HTML/Blade:
<tfoot>
<tr>
<td colspan="5"> {{ $locations->links() }} </td>
</tr>
</tfoot>
Hope someone else benefits as I didn't find this terribly clear in the docs.

Resources