Table with infolist
I'm trying to render a section of an infolist and it's just a table, but there doesn't seem to be a table component of the infolist components.
Is there a way to do this?
6 Replies
look into grid
https://filamentphp.com/docs/3.x/infolists/layout/grid
or failing that make a custom layout (where you would basically just set up a custom blade view with your infolist stuff in it
https://filamentphp.com/docs/3.x/infolists/layout/custom
I've found some ways to render tables with an infolist on a
As the data comes from a source other than my DB, I always use
ViewRecord
page, but the tables usually render data that comes from the DB.
Currently I need to render a list of players that comes from a game, this data is obtained via the RCON
protocol.
In the end I have an array of data, but I can't render it on the page
In my infolist, I have 2 sections, one for server information, and another for the players currently connected.
Section::make('Informações do Servidor')
->columns(3)
->schema([
TextEntry::make('hostname')
->label('Hostname')
->getStateUsing(fn () => $this->serverData['HostName'] ?? 'Unknown')
->weight('bold'),
TextEntry::make('ip_port')
->label('IP:Port')
->getStateUsing(fn ($record) => "{$record->ip}:{$record->port}")
->copyable()
->copyMessage('Copied!')
->copyMessageDuration(1500),
ImageEntry::make('mod')
->label('Mod')
->getStateUsing(fn ($record) => asset('images/games/' . $record->mod->mod . '.png'))
->height('30px')
->width('30px')
->columnSpan(1),
ImageEntry::make('os')
->label('OS')
->getStateUsing(function () {
$os = $this->serverData['Os'] ?? 'N/A';
if ($os === 'N/A') {
return null;
}
return asset("images/os/{$os}.png");
})
->height('30px')
->width('30px')
->visible(fn () => isset($this->serverData['Os']) && $this->serverData['Os'] !== 'N/A')
->columnSpan(1),
ImageEntry::make('vac')
->label('VAC')
->getStateUsing(function () {
$secure = $this->serverData['Secure'] ?? false;
return asset('images/vac/' . ($secure ? 'shield' : 'smac') . '.png');
})
->height('30px')
->width('30px'),
TextEntry::make('vac_status')
->label('VAC Status')
->getStateUsing(function () {
$secure = $this->serverData['Secure'] ?? false;
return $secure ? 'Protected' : 'Not Protected';
})
->badge()
->color(fn (string $state): string => $state === 'Protected' ? 'success' : 'warning'),
TextEntry::make('map')
->label('Map')
->getStateUsing(fn () => $this->serverData['Map'] ?? 'N/A'),
TextEntry::make('players')
->label('Players')
->getStateUsing(function () {
$players = $this->serverData['Players'] ?? 'N/A';
$maxPlayers = $this->serverData['MaxPlayers'] ?? 'N/A';
if ($players === 'N/A' || $maxPlayers === 'N/A') {
return 'N/A';
}
return "{$players}/{$maxPlayers}";
})
->badge()
->color('gray'),
])
->columns(2),
Section::make('Informações do Servidor')
->columns(3)
->schema([
TextEntry::make('hostname')
->label('Hostname')
->getStateUsing(fn () => $this->serverData['HostName'] ?? 'Unknown')
->weight('bold'),
TextEntry::make('ip_port')
->label('IP:Port')
->getStateUsing(fn ($record) => "{$record->ip}:{$record->port}")
->copyable()
->copyMessage('Copied!')
->copyMessageDuration(1500),
ImageEntry::make('mod')
->label('Mod')
->getStateUsing(fn ($record) => asset('images/games/' . $record->mod->mod . '.png'))
->height('30px')
->width('30px')
->columnSpan(1),
ImageEntry::make('os')
->label('OS')
->getStateUsing(function () {
$os = $this->serverData['Os'] ?? 'N/A';
if ($os === 'N/A') {
return null;
}
return asset("images/os/{$os}.png");
})
->height('30px')
->width('30px')
->visible(fn () => isset($this->serverData['Os']) && $this->serverData['Os'] !== 'N/A')
->columnSpan(1),
ImageEntry::make('vac')
->label('VAC')
->getStateUsing(function () {
$secure = $this->serverData['Secure'] ?? false;
return asset('images/vac/' . ($secure ? 'shield' : 'smac') . '.png');
})
->height('30px')
->width('30px'),
TextEntry::make('vac_status')
->label('VAC Status')
->getStateUsing(function () {
$secure = $this->serverData['Secure'] ?? false;
return $secure ? 'Protected' : 'Not Protected';
})
->badge()
->color(fn (string $state): string => $state === 'Protected' ? 'success' : 'warning'),
TextEntry::make('map')
->label('Map')
->getStateUsing(fn () => $this->serverData['Map'] ?? 'N/A'),
TextEntry::make('players')
->label('Players')
->getStateUsing(function () {
$players = $this->serverData['Players'] ?? 'N/A';
$maxPlayers = $this->serverData['MaxPlayers'] ?? 'N/A';
if ($players === 'N/A' || $maxPlayers === 'N/A') {
return 'N/A';
}
return "{$players}/{$maxPlayers}";
})
->badge()
->color('gray'),
])
->columns(2),
getStateUsing
to render the dataAnd it works fine

But it doesn't work on the players anyway.
$this->playerData = [
[
'Id' => 0,
'Name' => 'Player 1',
'Frags' => 0,
'Time' => 1143,
'TimeF' => '19:03',
],
[
'Id' => 1,
'Name' => 'Player 2',
'Frags' => 5,
'Time' => 1200,
'TimeF' => '20:00',
],
]
Section::make('Connected Players')
->schema([
RepeatableEntry::make('players')
->hiddenLabel()
->state(fn () => $this->playerData ?? [])
->schema([
Grid::make(2)
->schema([
TextEntry::make('Name')
->label('Jogador')
->weight('bold')
->columnSpan(1),
Grid::make(2)
->schema([
TextEntry::make('Frags')
->label('Pontuação')
->badge()
->color('success'),
//->getStateUsing(fn () => $this->playerData['Frags'] ?? '0'), // Uncommenting this causes the application to crash with an error 500.
TextEntry::make('TimeF')
->label('Tempo')
->color('gray'),
//->getStateUsing(fn () => $this->playerData['Time'] ?? '00:00:00'),
])
->columnSpan(1),
])
->columnSpan('full'),
])
->columns(2)
->contained(true)
])
->collapsible()
->visible(fn () => $this->serverData['IsOnline'] ?? false)
$this->playerData = [
[
'Id' => 0,
'Name' => 'Player 1',
'Frags' => 0,
'Time' => 1143,
'TimeF' => '19:03',
],
[
'Id' => 1,
'Name' => 'Player 2',
'Frags' => 5,
'Time' => 1200,
'TimeF' => '20:00',
],
]
Section::make('Connected Players')
->schema([
RepeatableEntry::make('players')
->hiddenLabel()
->state(fn () => $this->playerData ?? [])
->schema([
Grid::make(2)
->schema([
TextEntry::make('Name')
->label('Jogador')
->weight('bold')
->columnSpan(1),
Grid::make(2)
->schema([
TextEntry::make('Frags')
->label('Pontuação')
->badge()
->color('success'),
//->getStateUsing(fn () => $this->playerData['Frags'] ?? '0'), // Uncommenting this causes the application to crash with an error 500.
TextEntry::make('TimeF')
->label('Tempo')
->color('gray'),
//->getStateUsing(fn () => $this->playerData['Time'] ?? '00:00:00'),
])
->columnSpan(1),
])
->columnSpan('full'),
])
->columns(2)
->contained(true)
])
->collapsible()
->visible(fn () => $this->serverData['IsOnline'] ?? false)

Table widget inside a blade applied to an infolist.