Batman
Batman
FFilament
Created by Batman on 3/28/2025 in #❓┊help
Populate Select with only a select subset of an enum
What I am trying to achieve is populating the Select with only certain values of an Enum based on permissions. It is likely I am approaching this entirely the wrong way, and have tried various solutions without success. Although this does not work, it shows what I am trying to achieve. The ArticleStatus is a backed Enum and the value of that enum is stored in the status attribute (it is casted). Everything works properly if I want to load all the values of the enum (->options(ArticleStatus::class)). Running the code below gives this error: Filament\Forms\Components\Select::isOptionDisabled(): Argument #2 ($label) must be of type string, App\Enums\ArticleStatus given
Select::make('status')
->selectablePlaceholder(false)
->options(fn (?Article $record, $operation) => Article::getStatusSelectBuilder($record, $operation))
->getOptionLabelUsing(fn ($value): ?string => ArticleStatus::from($value)->getLabel())
->required(),
Select::make('status')
->selectablePlaceholder(false)
->options(fn (?Article $record, $operation) => Article::getStatusSelectBuilder($record, $operation))
->getOptionLabelUsing(fn ($value): ?string => ArticleStatus::from($value)->getLabel())
->required(),
7 replies
FFilament
Created by Batman on 3/27/2025 in #❓┊help
Markdown Toolbar Buttons
Are these all the available toolbar buttons for the markdown component, or just the default applied? Hoping for H2 and H3 heading tags. >"You may set the toolbar buttons for the editor using the toolbarButtons() method. The options shown here are the defaults:"
MarkdownEditor::make('content')
->toolbarButtons([
'attachFiles',
'blockquote',
'bold',
'bulletList',
'codeBlock',
'heading',
'italic',
'link',
'orderedList',
'redo',
'strike',
'table',
'undo',
])
MarkdownEditor::make('content')
->toolbarButtons([
'attachFiles',
'blockquote',
'bold',
'bulletList',
'codeBlock',
'heading',
'italic',
'link',
'orderedList',
'redo',
'strike',
'table',
'undo',
])
9 replies
FFilament
Created by Batman on 3/24/2025 in #❓┊help
Are anonymous functions evaluated before ->assertFormField*?
The user being tested does not have permissions to edit $testUser's email. It works correctly via front end. If ->disabled() is set without the anonymous function the test passes. But with the anonymous function it always fails. I am assuming that the test is ran before the anonymous function executes, or am I doing something wrong. Test:
livewire(EditUser::class, [$testUser->id])
->assertFormFieldIsDisabled('email');
livewire(EditUser::class, [$testUser->id])
->assertFormFieldIsDisabled('email');
Field being tested:
TextInput::make('email')
->disabled(fn (User $user) => ! Auth::user()->can('update-email', $user))
TextInput::make('email')
->disabled(fn (User $user) => ! Auth::user()->can('update-email', $user))
29 replies
FFilament
Created by Batman on 3/24/2025 in #❓┊help
Test for current route (or query params)
I have a tab in ListUsers::class that only a Super Admin can see. If an Admin tries to view the route by directly putting it into the url, it correctly returns the first tab. This seems to be default behavior of Filament and is what I desire. Since it is not a redirect, and is the same component, I am having a hard time finding out how to correctly test that the url actually returned is ListUsers::class [activeTab=all] or admin/users?activeTab=all. Getting the current URL or Route returns a Livewire Testing Endpoint. Any help is appreciated.
it('disallows admins from viewing tab for deleted users', function () {
asAdmin();

livewire(ListUsers::class, ['activeTab=deleted']);
// assert that the current route is actually equal to:
// ListUsers::class, ['activeTab=all']
});
it('disallows admins from viewing tab for deleted users', function () {
asAdmin();

livewire(ListUsers::class, ['activeTab=deleted']);
// assert that the current route is actually equal to:
// ListUsers::class, ['activeTab=all']
});
2 replies
FFilament
Created by Batman on 3/20/2025 in #❓┊help
Modify query when loading edit/view form
What is the best way to modify the query when loading an edit or view page? Using soft deletes. So when I select a user in the table, I need to modify the query so that a soft deleted user can be loaded for editing/viewing. Otherwise, nothing is returned. This results in a 404 - Not Found when loading edit / view resource.
64 replies
FFilament
Created by Batman on 3/14/2025 in #❓┊help
Fileupload delete image on filesystem (avatar)
I am using Breezy. The upload works as expected. When you click on the X to remove the avatar from your account it does remove the database entry. I am trying to figure out how to correctly delete the physical file as well.
->avatarUploadComponent(fn () => FileUpload::make('avatar_url')
->directory('o-res/avatars')
->disk('public')
)
->avatarUploadComponent(fn () => FileUpload::make('avatar_url')
->directory('o-res/avatars')
->disk('public')
)
2 replies
FFilament
Created by Batman on 3/12/2025 in #❓┊help
Changing the default ui-avatars.com colors
How would I go about changing the color scheme of the default ui-avatars? We are currently using background=0D8ABC&color=fff for our users and would like to match that for the default ui-avatar. Currently getting around it this way. But is this the correct way of doing it?
public function getFilamentAvatarUrl(): ?string
{
return $this->avatar_url
? Storage::disk('profile-photos')->url($this->avatar_url)
: 'https://ui-avatars.com/api/?background=0D8ABC&color=fff&name='.urlencode($this->name);
}
public function getFilamentAvatarUrl(): ?string
{
return $this->avatar_url
? Storage::disk('profile-photos')->url($this->avatar_url)
: 'https://ui-avatars.com/api/?background=0D8ABC&color=fff&name='.urlencode($this->name);
}
5 replies
FFilament
Created by Batman on 3/11/2025 in #❓┊help
Setting default on select adds a second "Uncategorized" option
When I set the default on a SelectInput it adds the value in default to the options list. So after this there are two Uncategorized options. It is not eager loading, it is loading when you select the dropdown.
Select::make('category')
->label('Category')
->required()
->preload()
->searchable()
->relationship('category', 'name')
->default('Uncategorized'),
Select::make('category')
->label('Category')
->required()
->preload()
->searchable()
->relationship('category', 'name')
->default('Uncategorized'),
4 replies
FFilament
Created by Batman on 3/10/2025 in #❓┊help
Set visibility of component based on current resource
I would like to put a list in a common area to share with the ArticleResource and ArticlesRelationManager (for users resource). Since this is to show articles for a specific user, I do not need the author column to be visible. I have searched here and in the Docs and I have not found anything with the terminology I was trying to search for. How can I set visibility based on the resource it is being used in similarly to how I have visibility based on $operation below? ` TextColumn::make('author.name') ->visible(fn (string $operation) => $operation !== 'edit') ->searchable() ->sortable(),
4 replies
FFilament
Created by Batman on 3/10/2025 in #❓┊help
Globally set redirect for create and edit forms
Is there a way to globally set redirection for forms to IndexResource instead of having to set it in every CreateResource and EditResource?
protected function getRedirectUrl(): string
{
return $this->previousUrl ?? $this->getResource()::getUrl('index');
}
protected function getRedirectUrl(): string
{
return $this->previousUrl ?? $this->getResource()::getUrl('index');
}
5 replies
FFilament
Created by Batman on 3/6/2025 in #❓┊help
Persist tab in InfoList when using getTabs function
How do I persist Tabs when using the getTabs() function in the List Resource? I see how in the docs when building up a Tab using ->persistTabInQueryString('settings-tab').
public function getTabs(): array
{
return [
'all' => Tab::make('All Talks'),
'submitted' => Tab::make('Submitted')
->modifyQueryUsing(function ($query) {
return $query->where('status', TalkStatus::SUBMITTED->value);
}),
'accepted' => Tab::make('Approved')
->modifyQueryUsing(function ($query) {
return $query->where('status', TalkStatus::APPROVED->value);
}),
'rejected' => Tab::make('Rejected')
->modifyQueryUsing(function ($query) {
return $query->where('status', TalkStatus::REJECTED->value);
}),
];
}
public function getTabs(): array
{
return [
'all' => Tab::make('All Talks'),
'submitted' => Tab::make('Submitted')
->modifyQueryUsing(function ($query) {
return $query->where('status', TalkStatus::SUBMITTED->value);
}),
'accepted' => Tab::make('Approved')
->modifyQueryUsing(function ($query) {
return $query->where('status', TalkStatus::APPROVED->value);
}),
'rejected' => Tab::make('Rejected')
->modifyQueryUsing(function ($query) {
return $query->where('status', TalkStatus::REJECTED->value);
}),
];
}
6 replies