Skip to content

Filter Builder โ€‹

Introduction โ€‹

The Filter Builder is a plugin (FilterBuilderPlugin). It adds a header button that opens a modal where users stack conditions from your filters() definitions. Conditions are validated against that allowlist and applied to Eloquent, Query Builder, and Collection datasources.

You do not redeclare columns for the builder. Types and operators in the modal come from filters(). The plugin is disabled when filters() is empty.

Additional rows can be joined with AND or OR. There is no nested grouping. match() only sets the default connector when the modal opens.

Supported filters() types: inputText, number, select / enumSelect, boolean, datepicker, datetimepicker. Multi-select and dynamic filters are skipped.

Theme Support โ€‹

The plugin renders when a view exists for the active theme.

  • Flux ships a <flux:modal> view
  • Other themes render the builder when header.filter_builder.view points at a Blade view, or when a packaged variant exists

If no view resolves, the plugin renders nothing and the table is unchanged.

Setup โ€‹

Opt in from setUp() and keep filters():

phpapp/Livewire/ProductTable.php
use PowerComponents\LivewirePowerGrid\Facades\PowerGrid;
use PowerComponents\LivewirePowerGrid\Facades\Filter;

public function setUp(): array
{
    return [
        PowerGrid::header()->showSearchInput(),
        PowerGrid::filterBuilder(),
    ];
}

public function filters(): array
{
    return [
        Filter::inputText('name'),
        Filter::number('price'),
        Filter::datepicker('created_at'),
        Filter::boolean('in_stock'),
    ];
}

Configuration โ€‹

All methods are chainable on PowerGrid::filterBuilder().

MethodDescriptionDefault
match(string $match)Default connector for additional rows when the modal opens (and or or).and
maxConditions(int $max)Hard cap on how many conditions may be applied.30
hideDefaultFilters(bool $hide = true)Hide inline / dropdown / flyout filters so the builder is the only filtering UI. Pills stay visible.false
only(array $fields)Restrict which filters() columns appear (empty = all). Matches field or column.[]
except(array $fields)Hide specific filters() columns from the builder.[]
persist(bool $persist = true)Persist applied conditions across requests.false
title(string $title)Header button title.โ€”
icon(string $icon)Header button icon.โ€”
phpapp/Livewire/ProductTable.php
public function setUp(): array
{
    return [
        PowerGrid::filterBuilder()
            ->match('or')
            ->maxConditions(10)
            ->only(['name', 'price', 'created_at'])
            ->hideDefaultFilters()
            ->title('Filter')
            ->icon('funnel'),
    ];
}

Before Query Hook โ€‹

Override beforeFilterBuilderApply() to run right before the builder applies conditions. It receives the query (or collection) plus the validated { match, rows } payload. Return the (optionally modified) query.

phpapp/Livewire/ProductTable.php
public function beforeFilterBuilderApply(mixed $query, array $conditions): mixed
{
    logger()->info('Filter Builder applied', $conditions);

    return $query->where('tenant_id', auth()->user()->tenant_id);
}

The $conditions shape:

phpapp/Livewire/ProductTable.php
[
    'match' => 'and',
    'rows' => [
        ['column' => 'name', 'operator' => 'contains', 'value' => 'a', 'value2' => '', 'boolean' => 'and'],
    ],
]

boolean on each row after the first is the AND / OR connector used in the query. The hook fires only when there is at least one applied condition.

Validating Before Apply โ€‹

Override validateFilterBuilder() to reject a submission. Throw to keep the previous state. Conditions have already been validated against your filters() allowlist.

phpapp/Livewire/ProductTable.php
public function validateFilterBuilder(array $conditions): void
{
    foreach ($conditions['rows'] as $row) {
        if ($row['column'] === 'price' && (float) $row['value'] < 0) {
            throw new \InvalidArgumentException('Price cannot be negative.');
        }
    }
}

Persistence โ€‹

The builder uses the same persist driver as the rest of PowerGrid (cookies, session, or cache). Builder conditions are stored with regular filters when 'filters' is persisted, or on their own via PowerGrid::filterBuilder()->persist().

phpapp/Livewire/ProductTable.php
public function setUp(): array
{
    $this->persist(['filters']);

    return [
        PowerGrid::filterBuilder(),
    ];
}

Builder only:

phpapp/Livewire/ProductTable.php
public function setUp(): array
{
    return [
        PowerGrid::filterBuilder()->persist(),
    ];
}

When only the builder is persisted, its enabled-filter pills are rebuilt from the restored conditions.

See Persist State.

Created By Luan Freitas and @DanSysAnalyst