Skip to main content
Tutorial Free

Filament Infolist: Custom Entry with "Show More" Button

December 02, 2023
3 min read

Filament 3 Infolist feature has a few entry types like TextEntry and others. But what if you need something custom? In this tutorial, we will create a custom Infolist entry to add a Show more/Show less button.

This is based on a question from our YouTube channel.

In this example, we have a Post Model with a title and a body.


First, we must create a custom infolist class.

php artisan make:infolist-layout PostBody

Now, we can call the newly created infolist entry in the Filament Resource infolist method.

use App\Infolists\Components\PostBody;
use Filament\Infolists\Components\TextEntry;
 
class PostResource extends Resource
{
// ...
 
public static function infolist(Infolist $infolist): Infolist
{
return $infolist
->schema([
TextEntry::make('title')
->columnSpanFull(),
PostBody::make('body')
->columnSpanFull(),
]);
}
 
// ...
}

We can use the {{ $getState() }} in the view file to access the current state. Using Alpine.js, we can now add a button to show or hide trimmed text. Also, using Alpine.js, we will trim the text.

resources/views/infolists/components/post-body.blade.php:

<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry">
<div x-data="{ isCollapsed: false, maxLength: 20, originalContent: '', content: '' }"
x-init="originalContent = @js($getState()); content = originalContent.slice(0, maxLength) + '...'"
>
<span x-text="isCollapsed ? originalContent : content"></span>
<x-filament::button
size="xs"
color="gray"
@click="isCollapsed = !isCollapsed"
x-show="originalContent.length > maxLength"
x-text="isCollapsed ? 'Show less' : 'Show more'"
></x-filament::button>
</div>
</x-dynamic-component>

The view page shows our created custom infolist entry for a post body with a working Show more/Show less button.


We can also make the length of a text configurable. We must add a protected property in the PostBody infolist entry. We will call it $maxLength, and two public methods, maxLength, and getMaxLength.

app/Infolists/Components/PostBody.php:

class PostBody extends Entry
{
protected string $view = 'infolists.components.post-body';
 
protected int | \Closure | null $maxLength = 20;
 
public function maxLength(int | \Closure | null $maxLength): static
{
$this->maxLength = $maxLength;
 
return $this;
}
 
public function getMaxLength(): ?int
{
return $this->evaluate($this->maxLength);
}
}

Now, we can call the maxLength method in the resource when using the PostBody entry.

class PostResource extends Resource
{
// ...
 
public static function infolist(Infolist $infolist): Infolist
{
return $infolist
->schema([
TextEntry::make('title')
->columnSpanFull(),
PostBody::make('body')
->maxLength(50)
->columnSpanFull(),
]);
}
 
// ...
}

In the view file, we must change the hard-coded maxLength value to use provided. We need to use the $getMaxLength() to get this value.

resources/views/infolists/components/post-body.blade.php:

<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry">
<div x-data="{ isCollapsed: false, maxLength: 20, originalContent: '', content: '' }"
<div x-data="{ isCollapsed: false, maxLength: @js($getMaxLength()), originalContent: '', content: '' }"
x-init="originalContent = @js($getState()); content = originalContent.slice(0, maxLength) + '...'"
>
<span x-text="isCollapsed ? originalContent : content"></span>
<x-filament::button
size="xs"
color="gray"
@click="isCollapsed = !isCollapsed"
x-show="originalContent.length > maxLength"
x-text="isCollapsed ? 'Show less' : 'Show more'"
></x-filament::button>
</div>
</x-dynamic-component>

As you can see, the text is longer now.


The full source code is available in this GitHub repository.


If you want more Filament examples, you can find more real-life projects on our FilamentExamples.com.

Enjoyed This Tutorial?

Get access to all premium tutorials, video and text courses, and exclusive Laravel resources. Join our community of 10,000+ developers.

Comments & Discussion

No comments yet…

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.