CT
CT
FFilament
Created by CT on 10/1/2024 in #❓┊help
How to increase SelectFilter's dropdown width?
No description
3 replies
FFilament
Created by CT on 7/24/2024 in #❓┊help
How to add an ->orderBy() *after* all other orderBy's? Or modify query *after* query is built?
I have a resource with around 300 items in it. I am using ->defaultSort('created_at', 'desc') on the resource. It works well, but there is a bug. Because many of the items were added in chunks, say 15 a time, some have the same created_at date. The issue I have now is that when paginating with an offset, due to the non-guaranteed nature of MySQL I am getting some of the same items on page 2 as on page 1. I have verified this by running the queries directly against the database. The solution here would be to orderBy created_at and then id to ensure a consistent order. I know that ->defaultSort() accepts a closure and I could do this, but I will run into the same issue when the user sorts by any other columns that have many same values. I looked at ->modifyQueryUsing() but any orderBy is added before the default sort, or before the user sort, which ruins the sorting. Does anyone have a good solution? Thanks in advance.
3 replies
FFilament
Created by CT on 4/30/2024 in #❓┊help
Correct way to add/create a Livewire table column component?
I have a table that when clicked opens a modal and runs some calculations. The calculations are expensive so I do not want to do them until the button is clicked. I have a working solution, but the problem is it will break when switching views with errors such as: Snapshot missing on Livewire component with id: R1rsgkBVrClAl8P8eYzL" The code I have is as follows;
Tables\Columns\TextColumn::make('score_100')
->label(__('Score 100'))
->state(function (Site $site) {
if (!$site->score_100) {
return null;
}

return new HtmlString(view('components.score', [
'site' => $site,
'score' => $site->score_100
])->render());
}),
Tables\Columns\TextColumn::make('score_100')
->label(__('Score 100'))
->state(function (Site $site) {
if (!$site->score_100) {
return null;
}

return new HtmlString(view('components.score', [
'site' => $site,
'score' => $site->score_100
])->render());
}),
and components.score looks like this:
<livewire:score-modal :siteId="$site->id" :score="$score" :key="$site->id . '-modal-' . $score">

</livewire:score-modal>
<livewire:score-modal :siteId="$site->id" :score="$score" :key="$site->id . '-modal-' . $score">

</livewire:score-modal>
The livewire score modal looks like this:
<div :key="container-{{ $siteId }}">
<button wire:click="openModal({{ $siteId }})" class="cursor-pointer">
{{ $score }}
</button>

@if (isset($selectedSite))
<x-filament::modal
width="4xl"
id="score-modal-{{ $selectedSite->id . '-' . $score }}">
... rest of the modal
<div :key="container-{{ $siteId }}">
<button wire:click="openModal({{ $siteId }})" class="cursor-pointer">
{{ $score }}
</button>

@if (isset($selectedSite))
<x-filament::modal
width="4xl"
id="score-modal-{{ $selectedSite->id . '-' . $score }}">
... rest of the modal
And all the calculations happen within the /app/Livewire/ScoreModal.php component... As I mentioned before everything is working but I keep getting these livewire errors. I've tried adding :key or wire:key to wherever possible but it seems to make no difference. I'm probably missing something obvious/simple here?
3 replies
FFilament
Created by CT on 3/29/2024 in #❓┊help
Correct way to apply a `withCount()` and `->having()` in a SelectFilter?
I have a Domain that has many Sites and I want to filter by the total number of sites each domain has. ie a drop down with eg 1, 2, 3 etc. I feel I am sort of close, but can't seem to get the last part working;
Tables\Filters\SelectFilter::make('sites_count')
->label(__('# Sites'))
->modifyQueryUsing(fn ($query, Tables\Filters\BaseFilter $filter) => $query->withCount('sites')->having('sites_count', $filter->getState()))
->options(Site::getDomainCountAsArray())
->multiple(),
Tables\Filters\SelectFilter::make('sites_count')
->label(__('# Sites'))
->modifyQueryUsing(fn ($query, Tables\Filters\BaseFilter $filter) => $query->withCount('sites')->having('sites_count', $filter->getState()))
->options(Site::getDomainCountAsArray())
->multiple(),
This seems to produce the following SQL;
SELECT `domains`.*, (SELECT count(*) FROM `sites` WHERE `domains`.`id` = `sites`.`domain_id`) AS `sites_count` FROM `domains` ORDER BY `created_at` DESC LIMIT 50 OFFSET 0
SELECT `domains`.*, (SELECT count(*) FROM `sites` WHERE `domains`.`id` = `sites`.`domain_id`) AS `sites_count` FROM `domains` ORDER BY `created_at` DESC LIMIT 50 OFFSET 0
So it seems to not take ->having() into account at all? Basically I'm able to get ->withCount('sites') working, but unable to use it in the query.
4 replies
FFilament
Created by CT on 3/27/2024 in #❓┊help
Adding plugins to Clusters
I have two third-party plugins that I am trying to add to a cluster, but they don't seem to natively support it. Is there some way to do this? Or even perhaps by say hiding the default navigation, then adding a new one manually to the cluster navigation?
3 replies
FFilament
Created by CT on 3/19/2024 in #❓┊help
How to correctly override the table container blade view?
No description
3 replies
FFilament
Created by CT on 2/27/2024 in #❓┊help
->disabled() on dependant Select broken on create page, works fine on edit modal.
I have the following two Selects, Contact is a dependant select based upon the Company selected. The below code works perfectly on an edit modal, but doesn't work on the create page. On the create page it starts as disabled, then once I select a Company, it becomes clickable but nothing happens (not even the usual "type ... to search" appears. No console errors and I can see in Clockwork that the requests to the database look correct.
Forms\Components\Select::make('company_id')
->live(onBlur: true)
->required()
->label('Company')
->preload()
->searchable()
->relationship(name: 'company', titleAttribute: 'name')
->afterStateUpdated(function (Forms\Contracts\HasForms $livewire, Forms\Set $set) {
// If we change the company make sure we null the contact to prevent errors.
$set('contact_id', null);
}),

Forms\Components\Select::make('contact_id')
->label('Contact')
->searchable()
->disabled(fn(Forms\Get $get) => !filled($get('company_id'))) // If I disable this line everything works correctly on the create page also
->preload()
->getOptionLabelFromRecordUsing(fn(Contact $contact) => $contact->full_name)
->relationship(
name: 'contact',
titleAttribute: 'first_name',
modifyQueryUsing: fn(Builder $query, Forms\Get $get) => $query->where('contacts.company_id', $get('company_id'))
),
Forms\Components\Select::make('company_id')
->live(onBlur: true)
->required()
->label('Company')
->preload()
->searchable()
->relationship(name: 'company', titleAttribute: 'name')
->afterStateUpdated(function (Forms\Contracts\HasForms $livewire, Forms\Set $set) {
// If we change the company make sure we null the contact to prevent errors.
$set('contact_id', null);
}),

Forms\Components\Select::make('contact_id')
->label('Contact')
->searchable()
->disabled(fn(Forms\Get $get) => !filled($get('company_id'))) // If I disable this line everything works correctly on the create page also
->preload()
->getOptionLabelFromRecordUsing(fn(Contact $contact) => $contact->full_name)
->relationship(
name: 'contact',
titleAttribute: 'first_name',
modifyQueryUsing: fn(Builder $query, Forms\Get $get) => $query->where('contacts.company_id', $get('company_id'))
),
Anyone got any ideas?
6 replies
FFilament
Created by CT on 2/13/2024 in #❓┊help
Very slow server performance when rendering large number of rows and columns - slow blade rendering
No description
7 replies
FFilament
Created by CT on 2/9/2024 in #❓┊help
How to eager load within a select using Form Builder?
I have the following:
Forms\Components\Select::make('registrar_username_id')
->label('Registrar')
->relationship(name: 'registrarUsername', titleAttribute: 'username')
->getOptionLabelFromRecordUsing(fn(RegistrarUsername $record) => "{$record->registrar->name} -> {$record->username}")
->preload()
->searchable(),
Forms\Components\Select::make('registrar_username_id')
->label('Registrar')
->relationship(name: 'registrarUsername', titleAttribute: 'username')
->getOptionLabelFromRecordUsing(fn(RegistrarUsername $record) => "{$record->registrar->name} -> {$record->username}")
->preload()
->searchable(),
As you can see the call to $record->register->name is lazy loaded, which triggers an error for me because I am using Model::shouldBeStrict(). I realize that since it's an edit page there is no real benefit to eager loading, but I would like to keep strict mode active, but also remove this error. Perhaps there is some way to modify or access the query before the page is loaded? Anyone got any ideas?
7 replies
FFilament
Created by CT on 2/7/2024 in #❓┊help
How to keep both modal Edit action and generate an edit route url?
I have a client who specifically needs both the edit modal and the edit link itself to work (ie modal opens from all table cells), but also needs from other pages a working link to the edit page, ie /{record}/edit should be a valid url. I can get either one working fine, but the problem is as follows:
public static function getPages(): array
{
return [
'index' => Pages\ListSites::route('/'),
'create' => Pages\CreateSite::route('/create'),
'edit' => Pages\EditSite::route('/{record}/edit'),
];
}
public static function getPages(): array
{
return [
'index' => Pages\ListSites::route('/'),
'create' => Pages\CreateSite::route('/create'),
'edit' => Pages\EditSite::route('/{record}/edit'),
];
}
When edit is commented modal works, but there is no edit route generated (verified with php artisan route:list) When edit is uncommented there is no modal but the edit route is correctly generated. Anyone tackled something like this before? Thanks
5 replies
FFilament
Created by CT on 2/2/2024 in #❓┊help
How to disable click to edit on particular column in a table row?
I have a table with an extra column that contains a custom blade component with an external link. It works fine, but when I click on it, the edit modal is also triggered. I have tried the following with no luck:
Tables\Columns\TextColumn::make('deferred')
->url(null)
->action(null)
...etc
Tables\Columns\TextColumn::make('deferred')
->url(null)
->action(null)
...etc
Is there something I am missing here? What do I have to do to disable the click on this table cell? If it matters, it is an edit modal that is triggered.
5 replies
FFilament
Created by CT on 1/24/2024 in #❓┊help
On TextColumn using an HTML ->prefix() with <svg> results in the svg being stripped from the output
I am trying to add an icon with a link as a prefix to my table. I can add text no problem but the <svg> tag seems to be stripped. Any idea why and how to resolve? Code looks like this:
Tables\Columns\TextColumn::make('name')
->label('Domain Name')
->prefix(function (): ?HtmlString {
return new HtmlString(view('components.external-link-button', [])->render());
})
Tables\Columns\TextColumn::make('name')
->label('Domain Name')
->prefix(function (): ?HtmlString {
return new HtmlString(view('components.external-link-button', [])->render());
})
the blade component looks like this (just for testing):
<p class="text-2xl">
foobar
<svg height="100" width="100">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
</p>
<p class="text-2xl">
foobar
<svg height="100" width="100">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
</p>
and I can see that the p class along with "foobar" is rendered but the svg code is completely strippped. Any ideas why?
3 replies
FFilament
Created by CT on 1/12/2024 in #❓┊help
Expected behaviour or bug? Global ->orderBy() scope not being respected by Filament Tables
I have many models that are each sorted using a global scope. The global scope remains, but it is the secondary orderBy as Filament always sets a default orderBy. For example here is the query with the global scope: SELECT * FROM categories ORDER BY categories.id ASC, name ASC LIMIT 50 OFFSET 0 and here it is without the global scope: SELECT * FROM categories ORDER BY categories.id ASC LIMIT 50 OFFSET 0 The problem I can see is that if ->defaultSort() on the table is undefined or even if ->defaultSort(null) is set then inside of vendor/filament/tables/src/Concerns/CanSortRecords.php we have this line here: return $query->orderBy($query->getModel()->getQualifiedKeyName()); So that means every query is always sorted by the model's key. Of course I can simply run ->defaultSort('name') and that will solve it, but with dozens of models this seems kind of redundant and unnecessary considering I've already setup the global scopes? As per the FilamentPHP docs: By default, Filament will observe all global scopes that are registered to your model. However, this may not be ideal if you wish to access, for example, soft deleted records. which i would argue is not entirely accurate if model global scopes are being overridden. To me it seems strange that 1) we are always setting a default orderBy and 2) it also seems strange that setting null on the orderBy continues to set an orderBy. Is this expected behavior or a bug? I'm happy to submit a PR but just wanted to check first I am not missing something obvious. Thanks.
2 replies