Custom table scroller actions with Alpine JS
I needed to create a way for my users to be able to scroll the table when a lot of columns or records are visible. We utilize our tables to filter data for large exportable sets. The following is really just meant to be a jumping off point and you should customize it to fit your needs.
We'll start by creating the scroller blade view.
resources/views/table-scroller.blade.php
<div class="table-scroller-actions" x-data="{ open: false }"> <button type="button" x-on:click="open = ! open" x-data="{ tooltip: {} }" class="text-white p-2 bg-primary-500 hover:bg-primary-800 focus:ring-2 focus:outline-none focus:ring-primary-300 font-medium rounded-full text-sm p-2.5 text-center inline-flex items-center mr-2" x-init="Alpine.effect(() => { if(open = open) { tooltip = false } else { tooltip = { content: 'Table Scroller', theme: Alpine.store('theme') === 'light' ? 'dark' : 'light', placement: document.dir === 'rtl' ? 'left' : 'right' } } }) " x-tooltip.html="tooltip" > <x-heroicon-o-switch-horizontal class="w-4 h-4"/> </button> <span x-show="open" x-transition:enter="transition ease-in duration-300" x-transition:enter-start="opacity-0 scale-90" x-transition:enter-end="opacity-100 scale-100" x-transition:leave="transition ease-out duration-300" x-transition:leave-start="opacity-100 scale-100" x-transition:leave-end="opacity-0 scale-90" ><button type="button" x-on:click="window.scroll({ top:0, left:0, behavior: 'smooth'})" class="text-white p-2 bg-primary-500 hover:bg-primary-800 focus:ring-2 focus:outline-none focus:ring-primary-300 font-medium rounded-full text-sm p-2.5 text-center inline-flex items-center mr-2"> <x-heroicon-o-chevron-up class="w-4 h-4"/></button> <button type="button" x-on:click="window.scrollTo({ top: document.body.scrollHeight, left: 0, behavior: 'smooth'})" class="text-white p-2 bg-primary-500 hover:bg-primary-800 focus:ring-2 focus:outline-none focus:ring-primary-300 font-medium rounded-full text-sm p-2.5 text-center inline-flex items-center mr-2"> <x-heroicon-o-chevron-down class="w-4 h-4"/> </button> <button type="button" x-on:click="document.querySelector('.filament-tables-table-container').scrollBy({ left: -document.querySelector('.filament-tables-table-container').scrollWidth, behavior: 'smooth' })" class="text-white p-2 bg-primary-500 hover:bg-primary-800 focus:ring-2 focus:outline-none focus:ring-primary-300 font-medium rounded-full text-sm p-2.5 text-center inline-flex items-center mr-2"> <x-heroicon-o-chevron-double-left class="w-4 h-4"/> </button> <button type="button" x-on:click="document.querySelector('.filament-tables-table-container').scrollBy({ left: -150, behavior: 'smooth' })" class="text-white p-2 bg-primary-500 hover:bg-primary-800 focus:ring-2 focus:outline-none focus:ring-primary-300 font-medium rounded-full text-sm p-2.5 text-center inline-flex items-center mr-2"> <x-heroicon-o-chevron-left class="w-4 h-4"/> </button> <button type="button" x-on:click="document.querySelector('.filament-tables-table-container').scrollBy({ left: +150, behavior: 'smooth' })" class="text-white p-2 bg-primary-500 hover:bg-primary-800 focus:ring-2 focus:outline-none focus:ring-primary-300 font-medium rounded-full text-sm p-2.5 text-center inline-flex items-center mr-2"> <x-heroicon-o-chevron-right class="w-4 h-4"/> </button> <button type="button" x-on:click="document.querySelector('.filament-tables-table-container').scrollBy({ left: +document.querySelector('.filament-tables-table-container').scrollWidth, behavior: 'smooth' })" class="text-white p-2 bg-primary-500 hover:bg-primary-800 focus:ring-2 focus:outline-none focus:ring-primary-300 font-medium rounded-full text-sm p-2.5 text-center inline-flex items-center mr-2"> <x-heroicon-o-chevron-double-right class="w-4 h-4"/> </button> </span></div>
Next we need to tell Filament where we want the table-scroller to render using some hooks in our service provider.
app/Providers/AppServiceProvider.php
use Filament\Facades\Filament;use Illuminate\Contracts\View\View; public function boot(): void{ Filament::registerRenderHook( 'resource.pages.list-records.table.end', fn (): View => view('table-scroller'), ); Filament::registerRenderHook( 'resource.relation-manager.end', fn (): View => view('table-scroller'), );}
The last thing we need to do is provide some positioning via a css class. I tried to make this work with Tailwind, but this was the simplest method.
.table-scroller-actions { position: fixed; left: 25px; bottom: 45px; z-index: 1;}
No comments yet…