
[{"content":"","date":"28 October 2025","externalUrl":null,"permalink":"/","section":"August's Blog","summary":"","title":"August's Blog","type":"page"},{"content":"","date":"28 October 2025","externalUrl":null,"permalink":"/posts/","section":"Posts","summary":"","title":"Posts","type":"posts"},{"content":"","date":"28 February 2025","externalUrl":"https://github.com/asosick/filament-layout-manager/","permalink":"/posts/filament-layout-manager/","section":"Posts","summary":"","title":"Filament Layout Manager","type":"posts"},{"content":"","date":"28 February 2025","externalUrl":null,"permalink":"/tags/filamentphp/","section":"Tags","summary":"","title":"FilamentPHP","type":"tags"},{"content":"","date":"28 February 2025","externalUrl":null,"permalink":"/tags/laravel/","section":"Tags","summary":"","title":"Laravel","type":"tags"},{"content":"","date":"28 February 2025","externalUrl":null,"permalink":"/tags/php/","section":"Tags","summary":"","title":"PHP","type":"tags"},{"content":"","date":"28 February 2025","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"17 January 2025","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","date":"17 January 2025","externalUrl":null,"permalink":"/categories/filamentphp/","section":"Categories","summary":"","title":"Filamentphp","type":"categories"},{"content":"You can fix this issue without resorting to publishing the filament table\u0026rsquo;s vendor file!\nThe Issue # The built in table as part of FilamentPHP has a recurring issue (IMO) where selecting a row causes the table to move downwards due to the insert of a \u0026lsquo;selection indicator\u0026rsquo; element above the table.\nThis can cause grief for users who need to reposition their mouse after selecting a row.\nCustom CSS # To fix this issue, we\u0026rsquo;re simply going to rearrange the order of some of the table components. For example, placing the selection indicator at the bottom of the table. This was my choice for a solution.\nWhy not publish the blade file? # Using custom css hooks are recommended by Filament itself over publishing vendor files. Doing this reduces your application\u0026rsquo;s risk profile and maintenance load when updating Filament versions. See more here\nRegistering your custom CSS file # Don\u0026rsquo;t forget to register your custom css class to override filament styling.\nnamespace App\\Providers; use Filament\\Support\\Assets\\Css; use Filament\\Support\\Facades\\FilamentAsset; use Illuminate\\Support\\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function boot(): void { FilamentAsset::register([ Css::make(\u0026#39;custom-stylesheet\u0026#39;, __DIR__.\u0026#39;/../../resources/css/custom.css\u0026#39;), ]); } } When you\u0026rsquo;ve created your custom css file, you can publish it using php artisan filament:assets\nCustom CSS # /* file path: resources/css/custom.css Tip: Open your table and inspect the html to gain greater clarity on where these css classes apply on the page /* /*table container*/ .fi-ta-ctn { display: grid !important; } /*header container*/ .fi-ta-header-ctn{ order: 1 !important; } /*table rows*/ .fi-ta-content { order: 2 !important; } /*!*selection indicator*!*/ .fi-ta-selection-indicator{ order: 3 !important; } /*pagination section*/ .fi-pagination{ order:4 !important; } Now that I\u0026rsquo;ve highlighted which css classes to use to change the table, you may want a different look than I selected - that\u0026rsquo;s totally cool, use your inspection tool \u0026amp; go crazy!; I just chose this because I think it still looks nice.\nFinal Styling Issues # No searching or bulk actions # If you use the css provided above and your table only has the filter icon with no search bar or bulk actions above the table (like in my example GIFs), you\u0026rsquo;ll notice a little bit of movement.\nThat is because any search bars or buttons will expand that region dynamically. You can fix this by:\nMoving the filter section below the table Fixing the filter section height ⬅ my choice /* Add to your custom css file */ .fi-ta-header-toolbar{ height: 58px; /* This height accounts for the button\u0026#39;s size plus padding. May not work on every screen. Test it 🤷‍♂️ */ } Rearanging the filter section # FilamentPHP supports fixing filters to the bottom of the page which may conflict with this custom CSS.\nI did not test the recommeneded css changes on every table combination ever; I recommend you do if you have a cacophony of different table styles.\nResult # No more movement :)\n","date":"17 January 2025","externalUrl":null,"permalink":"/posts/filament-move-selection-indicator/","section":"Posts","summary":"","title":"FilamentPHP - Fix \"bouncing table\" on row selection with CSS","type":"posts"},{"content":" Desired Feature # Using a header button, the \u0026lsquo;company\u0026rsquo; filter is toggled on and off with a custom option (\u0026ldquo;Google\u0026rdquo;).\nMultiple Selection Filter Example # /* Company filter is applied to the \u0026#39;company\u0026#39; field on the Company model Table function defined in the CompanyResource.php file as created by Filament */ namespace App\\Filament\\Resources; public static function table(Table $table): Table { return $table -\u0026gt;headerActions([ Tables\\Actions\\Action::make(\u0026#39;google_filter\u0026#39;) -\u0026gt;badge() -\u0026gt;label(\u0026#39;Google\u0026#39;) -\u0026gt;icon(fn (ListRecords|TableWidget $livewire) =\u0026gt; in_array(Companies::Google-\u0026gt;value, Arr::get($livewire-\u0026gt;tableFilters ?? [], \u0026#39;company.values\u0026#39;, [])) ? \u0026#39;heroicon-s-funnel\u0026#39; : \u0026#39;heroicon-o-funnel\u0026#39; ) -\u0026gt;action(fn (ListRecords|TableWidget $livewire) =\u0026gt; self::buttonFilterApply($livewire, \u0026#39;company\u0026#39;, Companies::Google-\u0026gt;value)), Tables\\Actions\\Action::make(\u0026#39;apple_filter\u0026#39;) -\u0026gt;badge() -\u0026gt;label(\u0026#39;Apple\u0026#39;) -\u0026gt;icon(fn (ListRecords|TableWidget $livewire) =\u0026gt; in_array(Companies::Apple-\u0026gt;value, Arr::get($livewire-\u0026gt;tableFilters ?? [], \u0026#39;company.values\u0026#39;, [])) ? \u0026#39;heroicon-s-funnel\u0026#39; : \u0026#39;heroicon-o-funnel\u0026#39; ) -\u0026gt;action(fn (ListRecords|TableWidget $livewire) =\u0026gt; self::buttonFilterApply($livewire, \u0026#39;company\u0026#39;, Companies::Apple-\u0026gt;value)), ]) -\u0026gt;filters([ SelectFilter::make(\u0026#39;company\u0026#39;) -\u0026gt;multiple() -\u0026gt;native(false) -\u0026gt;options(Companies::class), ]) -\u0026gt;columns([ TextColumn::make(\u0026#39;name\u0026#39;), TextColumn::make(\u0026#39;job_title\u0026#39;), TextColumn::make(\u0026#39;location\u0026#39;), TextColumn::make(\u0026#39;company\u0026#39;), ]); } private static function buttonFilterApply(ListRecords|TableWidget $livewire, string $filter, string $option): void { $filter_value = (array) Arr::get($livewire-\u0026gt;tableFilters ?? [], $filter, []); if (empty($filter_value)) { return; } if (in_array($option, $filter_value[\u0026#39;values\u0026#39;])) { $livewire-\u0026gt;tableFilters[$filter][\u0026#39;values\u0026#39;] = array_diff($filter_value[\u0026#39;values\u0026#39;], [$option]); } else { $livewire-\u0026gt;tableFilters[$filter][\u0026#39;values\u0026#39;][] = $option; } } Single Selection Filter Example # namespace App\\Filament\\Resources; public static function table(Table $table): Table { return $table -\u0026gt;headerActions([ Tables\\Actions\\Action::make(\u0026#39;google_filter\u0026#39;) -\u0026gt;badge() -\u0026gt;label(\u0026#39;Google\u0026#39;) -\u0026gt;icon(fn (ListRecords|TableWidget $livewire) =\u0026gt; Arr::get($livewire-\u0026gt;tableFilters ?? [], \u0026#39;company.value\u0026#39;) === Companies::Google-\u0026gt;value ? \u0026#39;heroicon-s-funnel\u0026#39; : \u0026#39;heroicon-o-funnel\u0026#39; ) -\u0026gt;action(fn (ListRecords|TableWidget $livewire) =\u0026gt; self::buttonFilterApply($livewire, \u0026#39;company\u0026#39;, Companies::Google-\u0026gt;value)), ]) -\u0026gt;filters([ SelectFilter::make(\u0026#39;company\u0026#39;) -\u0026gt;native(false) -\u0026gt;options(Companies::class), ]) -\u0026gt;columns([ TextColumn::make(\u0026#39;name\u0026#39;), TextColumn::make(\u0026#39;job_title\u0026#39;), TextColumn::make(\u0026#39;location\u0026#39;), TextColumn::make(\u0026#39;company\u0026#39;), ]); } private static function buttonFilterApply(ListRecords|TableWidget $livewire, string $filter, string $option): void { $filter_value = Arr::get($livewire-\u0026gt;tableFilters ?? [], $filter); if (empty($filter_value)) { return; } $new_value = Arr::get($filter_value, \u0026#39;value\u0026#39;) === $option ? \u0026#39;\u0026#39; : $option; $livewire-\u0026gt;tableFilters[$filter] = [\u0026#39;value\u0026#39; =\u0026gt; $new_value]; } Support # Companies Enum # /* Optional enum class for additional clarity above */ use Filament\\Support\\Contracts\\HasLabel; enum Companies: string implements HasLabel { case Google = \u0026#39;Google\u0026#39;; case Apple = \u0026#39;Apple\u0026#39;; case Yahoo = \u0026#39;Yahoo\u0026#39;; public function getLabel(): ?string { return $this-\u0026gt;name; } } Livewire Type # In order for LaraStan to be happy, we need the correct livewire type applied to our icon() \u0026amp; action() methods on our header action - types that have the $tableFilters property.\nThat Filament class is Filament\\Resources\\Pages\\ListRecords, however, in the event you utilize this table in a table widget you\u0026rsquo;ll need to union that type with Filament\\Widgets\\TableWidget, hence ListRecords|TableWidget $livewire.\n","date":"17 January 2025","externalUrl":null,"permalink":"/posts/filament-table-header-filter-buttons/","section":"Posts","summary":"","title":"FilamentPHP - Apply filters from table header buttons","type":"posts"},{"content":"","externalUrl":null,"permalink":"/hello/","section":"August's Blog","summary":"","title":"","type":"page"},{"content":" Tools # https://tools.sosick.ca ","externalUrl":null,"permalink":"/links/","section":"August's Blog","summary":"","title":"","type":"page"},{"content":"Hey!\nI am a software engineer located in Toronto 🇨🇦\nRight now I am working full-time on my open-source project called Iridium. That\u0026rsquo;ll be released publicly sometime this year.\nI am originally from Calgary, where I graduated from the University of Calgary with degrees in Software Engineering and Business. I\u0026rsquo;ve been fortunate to work across a few industries including aerospace, telecommunications, banking, and healthcare.\nI spend most of my free-time hanging out with my lovely partner, and training for the upcoming Vancouver marathon.\nSite Notes # This site was built using hugo, and the excellent blowfish theme! All the images for previews \u0026amp; backgrounds were taken or created by me. Feel free to borrow any images (except the Iridium branded stuff) if you like them. Just include a link to my site :)️ ","externalUrl":null,"permalink":"/about/","section":"August's Blog","summary":"","title":"About Me","type":"page"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"}]