Hey guys, I have a weird problem which I can't replicate the problem with a working version because I didn't use version control (lesson learned). Anyway, I have trouble with the pagination method and data fetching while going to the next page of data in a table, shown in the app.
Thing is, the first page works perfectly fine. I'm getting the ErrorException [title name] error when I skip to another page of the table. Very weird stuff since it worked before..
The idea of it is that a user (gebruiker in Dutch) hasmany() registrations (registraties in Dutch) and for( every registration) I fetch the data and show it in a table for all to see.
Why does it only show the first page of my table and not fetch the data correctly (which I'm assuming is the case) on the second page of the paginated table?
Fetching data method:
public function showTableAll(User $user, Registratie $registraties) {
$registraties = Registratie::with('gebruiker')->paginate(5);
return view('table-all', [
'registraties' => $registraties
]);
}
Table html:
<table class="table table-hover" id="tableAll">
<thead>
<tr>
<th onclick="sortTable(0)"><strong>Lidnummer</strong></th>
<th onclick="sortTable(1)"><strong>Geslacht</strong></th>
<th onclick="sortTable(2)"><strong>Soort</strong></th>
<th onclick="sortTable(3)"><strong>Vangplaats</strong></th>
<th onclick="sortTable(4)"><strong>AS</strong></th>
<th onclick="sortTable(5)"><strong>KV</strong></th>
<th onclick="sortTable(6)"><strong>Notitie</strong></th>
<th onclick="sortTable(7)"><strong>Ondersoort</strong></th>
<th onclick="sortTable(8)"><strong>M/V</strong></th>
<th onclick="sortTable(9)"><strong>Aantal</strong></th>
<th onclick="sortTable(10)"><strong>Groep</strong></th>
<th onclick="sortTable(11)"><strong>Jongen</strong></th>
</tr>
</thead>
<tr>
@foreach ($registraties as $registratie)
<tr>
<td> <a href="mailto:{{ $registratie->gebruiker->email }}">{{ $registratie->gebruiker->lidnummer }}</a></td>
<td>{{ $registratie->geslachtsnaam }}</td>
<td>{{ $registratie->soortnaam }}</td>
<td>{{ $registratie->vangplaats }}</td>
<td>{{ $registratie->AS }}</td>
<td>{{ $registratie->KV }}</td>
<td>{{ $registratie->notitie }}</td>
<td>{{ $registratie->ondersoort }}</td>
<td>{{ $registratie->mv }}</td>
<td>{{ $registratie->aantal }}</td>
<td>{{ $registratie->groep }}</td>
<td>{{ $registratie->jongen }}</td>
</tr>
@endforeach
{{ $registraties->links() }}
</tr>
</table>
Registratie model:
<?php
namespace App\Models;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Registratie extends Model
{
use HasFactory;
public $table = 'registraties';
protected $fillable = [
"user_id",
"geslachtsnaam",
"soortnaam",
"vangplaats",
"AS",
"KV",
"notitie",
"ondersoort",
"aantal",
"mv",
"groep",
"jongen"
];
public function gebruiker() {
return $this->belongsTo(User::class, "user_id");
}
}
User model:
<?php
namespace App\Models;
use App\Models\Registratie;
use Laravel\Sanctum\HasApiTokens;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Contracts\Auth\CanResetPassword;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use HasApiTokens, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'lidnummer',
'naam',
'achternaam',
'email',
'password',
'verified',
'password_updated_at'
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
public function registraties() {
return $this->hasMany(Registratie::class, 'user_id', 'id');
}
}
Some Javascript for the table, don't know if it's relevant but:
<script>
console.log('hello :)');
// Export table data to Excel file
var btnXlsx = document.querySelectorAll('.action button')[0];
var btnXls = document.querySelectorAll('.action button')[1];
var btnCvs = document.querySelectorAll('.action button')[2];
btnXlsx.onclick = () => exportData('xlsx');
btnXls.onclick = () => exportData('xls');
btnCvs.onclick = () => exportData('csv');
function exportData(type) {
const fileName = 'exported-sheet.' + type;
const table = document.getElementById("tableAll");
const wb = XLSX.utils.table_to_book(table);
XLSX.writeFile(wb, fileName);
}
// Search through table data
function myFunction() {
// Declare variables
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
// Search through table data
function searchFunction() {
// Declare variables
var input, filter, table, tr, td, i, txtValue;
input = document.getElementById("searchInput");
filter = input.value.toUpperCase();
table = document.getElementById("tableAll");
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
function sortTable(n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("tableAll");
switching = true;
//Set the sorting direction to ascending:
dir = "asc";
/*Make a loop that will continue until
no switching has been done:*/
while (switching) {
//start by saying: no switching is done:
switching = false;
rows = table.rows;
/*Loop through all table rows (except the
first, which contains table headers):*/
for (i = 1; i < (rows.length - 1); i++) {
//start by saying there should be no switching:
shouldSwitch = false;
/*Get the two elements you want to compare,
one from current row and one from the next:*/
x = rows[i].getElementsByTagName("TD")[n];
y = rows[i + 1].getElementsByTagName("TD")[n];
/*check if the two rows should switch place,
based on the direction, asc or desc:*/
if (dir == "asc") {
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
//if so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
} else if (dir == "desc") {
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
//if so, mark as a switch and break the loop:
shouldSwitch = true;
break;
}
}
}
if (shouldSwitch) {
/*If a switch has been marked, make the switch
and mark that a switch has been done:*/
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
//Each time a switch is done, increase this count by 1:
switchcount++;
} else {
/*If no switching has been done AND the direction is "asc",
set the direction to "desc" and run the while loop again.*/
if (switchcount == 0 && dir == "asc") {
dir = "desc";
switching = true;
}
}
}
}
</script>
Pls help 🥹