Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Tall Datatables Laravel Package

team-nifty-gmbh/tall-datatables

Livewire datatables for Laravel's TALL stack. Quickly add responsive, sortable, searchable, and filterable tables with pagination, customizable columns, bulk actions, query builder filters, row actions, and Blade-friendly views to admin panels and dashboards.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and wire up the TALL dependencies first. The package assumes Livewire 3, Alpine (bundled with Livewire — do not add a second Alpine CDN tag), and Tailwind. Install with composer require team-nifty-gmbh/tall-datatables, then publish anything it ships:

php artisan vendor:publish --tag=tall-datatables-config
php artisan vendor:publish --tag=tall-datatables-views   # only if you plan to override markup

Look here first, in this order:

  1. README.md — the package is small and the examples are the de-facto API docs.
  2. The published config/tall-datatables.php — it controls default per-page counts, view paths, and feature toggles.
  3. vendor/team-nifty-gmbh/tall-datatables/src/ — the base Livewire component and the column/filter classes are short and readable; when the README is thin, the source answers questions faster than guessing.
  4. Any resources/views in the package — this is what you'll override for custom cells.

First use case: a read-only index page. Create a Livewire component that extends the package's datatable base, declare columns for a User model (name, email, created_at), and mount it in a Blade view:

{{-- resources/views/users/index.blade.php --}}
<x-app-layout>
    <livewire:users-table />
</x-app-layout>

Make sure your tailwind.config.js content array includes ./vendor/team-nifty-gmbh/tall-datatables/resources/views/**/*.blade.php (and your own app/Livewire + resources/views), otherwise the table renders unstyled. Get sorting + search + pagination working on one flat table before touching filters or actions — that validates the whole Livewire/Alpine/Tailwind loop end to end.

Implementation Patterns

Column definitions drive everything. The normal workflow is one Livewire component per table, with columns declared in a method and the query built in another. Keep both declarative so the table stays a thin view of the model layer:

protected function columns(): array
{
    return [
        TextColumn::make('name')->searchable()->sortable(),
        TextColumn::make('email')->searchable(),
        BadgeColumn::make('status')->colors(['active' => 'green', 'banned' => 'red']),
        DateColumn::make('created_at')->sortable(),
        ActionColumn::make(), // edit / delete buttons
    ];
}

Query scoping belongs in the builder, not the column. Pass an Eloquent builder and eager-load anything a column touches (->with('team')) so a 25-row page doesn't become 26 queries. Filter callbacks should mutate that same builder.

Filters: start with the built-ins, then go custom. Select and date-range filters cover most admin screens. For anything domain-specific (tenant, "only mine", soft-deleted), add a custom filter that receives the builder and applies a where. Remember filters should call resetPage() — otherwise users sit on page 7 of a 2-page result set.

Row actions and bulk actions. Use action columns for per-row edit/delete and the package's bulk-action hook for multi-select operations. Prefer dispatching an event ($this->dispatch('user-deleted')) over mutating sibling components directly; it keeps the table reusable across pages. Wrap destructive actions in wire:confirm or a confirmation modal.

Custom cell rendering. When a value needs more than a string (avatar + name, progress bar, status pill with tooltip), point the column at a small Blade partial rather than fighting the built-in formatters. This is the main extension point you'll use week to week, and it keeps formatting logic out of PHP.

Compose, don't fork. For a project with many tables, create your own App\Support\DataTable base extending the package's component, set house defaults there (per-page, empty-state text, action styling), and extend that everywhere. Upgrades then touch one file.

Test with Livewire's own harness. Livewire::test(UsersTable::class)->assertSee('[email protected]') plus assertions on set('search', ...) and call('sortBy', ...) catches most regressions without a browser. Add one Dusk/Pest browser test for the Alpine-dependent bits (dropdowns, bulk-select) since those don't run in the component test.

Gotchas and Tips

  • Tailwind purging is the #1 "it's broken" bug. Classes used inside the package's views, and any class names you build dynamically in PHP ("text-{$color}-600"), get stripped. Add the vendor view path to content and safelist dynamic color/badge classes.
  • Alpine double-loading. Livewire 3 ships Alpine. If your layout also includes Alpine via CDN, dropdowns and row menus behave erratically. Remove the extra script.
  • Stale published views after upgrade. If you published views, composer update won't refresh them. Pin the version in composer.json, read the changelog before bumping, and diff your overrides against the new package views. With 14 stars and a fast-moving repo, treat minor versions as potentially breaking.
  • Sorting/searching relationship columns. sortable() on team.name typically needs a join or subquery in the builder; otherwise you get an SQL error or a silent no-op. Same for accessor/computed columns — search won't see them unless you supply a custom search callback.
  • Config caching. After changing config/tall-datatables.php, run php artisan config:clear. In production with config:cache, the published config is baked in — deploy scripts that skip the rebuild will serve old defaults.
  • Multiple tables on one page. Give each component a distinct wire:key and check that Alpine x-data IDs don't collide; two instances of the same table with shared filter state is a common bug source.
  • N+1 sneaking in via badges/actions. Anything a column renders (relation counts, latest activity) runs per row. Eager-load or use withCount.
  • Debugging order: inspect the rendered HTML first (missing classes vs. missing data are different bugs), then Livewire::test() to isolate PHP from Alpine, then the browser console. Most "the table is empty" reports are a base query returning nothing — log the builder's toSql()/getBindings() before blaming the package.
  • Extension points to remember: published Blade views, custom column classes, custom filter callbacks, the config file, and Livewire event dispatch. Between those you can cover almost any requirement without patching vendor code — which you should never do.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager