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

Filament Auto Filters Laravel Package

ptplugins/filament-auto-filters

Filament Auto Filters automatically generates table filters for Filament resources, reducing boilerplate and keeping admin panels consistent. Configure filters with minimal setup and give users faster, more intuitive ways to narrow down records.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install the package with Composer and publish its config so you can tune distinct_max_options before you have real data:
    composer require <vendor>/<package>
    php artisan vendor:publish --tag=<package>-config
    
  • Look first at the class that exposes distinctOptionsUsing (the filter/field you attach to a table or form). That callback is the single extension point you'll spend most of your time in.
  • Set distinct_max_options to a sane cap (e.g. 50–200) up front. It guards both flat lists and associative maps, and it is the difference between a usable select and a dropdown with 40k rows.
  • First use case — start with the simplest thing that works, a flat list:
    ->distinctOptionsUsing(fn () => Order::query()->distinct()->pluck('status')->all())
    
    You get natural sort and the raw value as the label, with no extra work.
  • Upgrade to 1.4.1's associative map only when the raw value isn't presentable (amounts, dates, enum-backed codes).

Implementation Patterns

Flat list (unchanged behavior). Return an array of scalars. The package natural-sorts them and uses each value as its own label. This is still the right default for statuses, countries, and slugs — don't reach for the map just because it exists.

Associative value => label map (new in 1.4.1). Return a keyed array when the display string differs from the stored value:

->distinctOptionsUsing(function () {
    return Order::query()
        ->distinct()
        ->pluck('total')          // raw values
        ->mapWithKeys(fn ($v) => [$v => number_format((float) $v, 2)])
        ->all();
})

The order and labels you return are kept as-is — the package will not re-sort or relabel. That makes this mode the tool for:

  • Formatted amounts / currency (value => '$1,250.00').
  • Enum or code lookups ('P' => 'Pending').
  • Bucketed / humanized ranges where the key is the filter value and the label is prose.

Own your ordering in map mode. Because natural sort is skipped, build the map from an ordered query (orderBy('total')) or sort in PHP before keying it. Sorting after mapWithKeys is fine too, but don't assume the package will fix it for you.

Keep the callback cheap and side-effect free. It runs when options are resolved, potentially on every render. Prefer a single distinct()->pluck() over N+1 lookups, and memoize per request if you call it from more than one place:

->distinctOptionsUsing(fn () => Cache::remember('order.statuses', 300, fn () => ...))

Respect the cap deliberately. distinct_max_options still applies in map mode, so a formatted map can be truncated exactly like a flat list. If you know the domain is small and bounded (statuses, tiers), raise it; if it's user-generated (amounts, tags), keep it low and pair the filter with a search/autocomplete affordance instead of trying to render everything.

Integrate at the filter, not the query. The callback only produces options; the selected key is what gets applied to the query. Keep the key equal to the actual column value so filtering stays correct — the label is cosmetic.

Gotchas and Tips

  • Blank values are dropped in map mode. A '' => 'None' entry will not survive. If you need an explicit "empty/none" option, use a real sentinel key (e.g. '__none') and translate it in your query scope, or handle empty separately.
  • Numeric-string keys become ints. PHP casts '10' to 10 when used as an array key. For decimal amounts this is usually harmless, but for zero-padded codes ('007') or IDs you rely on as strings, cast deliberately or prefix the key. This is the most common source of "the filter sends the wrong value" bugs after switching to the map.
  • Unique keys, duplicate labels. The map is keyed by value, so two different values can share a label (e.g. two amounts formatting to $1,000.00). That's allowed, but it makes the select ambiguous to users — format with enough precision to disambiguate.
  • No natural sort in map mode. This is the biggest behavioral difference from the flat list. If your labels come out in insertion order and look random, that's your query's order, not a bug.
  • distinct_max_options applies to both modes. When a map silently loses entries, check the count after blank-dropping and keying against the threshold before debugging anything else.
  • Debugging: dump the callback's return value directly (dd($callback())) — check count, key types, and ordering in one shot. If options look right but filtering fails, the problem is the key type or the query scope, not the resolver.
  • Upgrade is non-breaking. 1.4.1 only widens what distinctOptionsUsing may return; existing flat-list callbacks keep natural sort and value-as-label. No config or migration changes required — you can adopt the map incrementally, one filter at a time.
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.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource