codewithdennis/filament-price-filter
Installation:
composer require codewithdennis/filament-price-filter
Publish config (optional):
php artisan vendor:publish --tag="filament-price-filter-config"
Basic Usage:
Register the widget in your Filament resource's getTableWidgets():
use CodeWithDennis\FilamentPriceFilter\Widgets\PriceFilter;
public static function getTableWidgets(): array
{
return [
PriceFilter::make()
->queryUsing(fn (Builder $query, $min, $max) => $query
->whereBetween('price', [$min, $max])
),
];
}
First Use Case: Add to a product listing table to filter by price range. Example:
PriceFilter::make('price')
->label('Price Range')
->min(0)
->max(1000)
Dynamic Range Filtering:
PriceFilter::make('price')
->queryUsing(fn ($query, $min, $max) => $query
->where(function ($q) use ($min, $max) {
if ($min) $q->where('price', '>=', $min);
if ($max) $q->where('price', '<=', $max);
})
)
Integration with Existing Filters:
Combine with other Filament widgets (e.g., SelectFilter):
public static function getTableWidgets(): array
{
return [
PriceFilter::make('price'),
SelectFilter::make('category')
->options(['electronics', 'clothing'])
];
}
Custom Currency Handling:
Override globally in config/filament-price-filter.php:
'currency' => 'EUR',
'cents' => false,
Or per-instance:
PriceFilter::make('price')
->currency('GBP')
->hideCents()
Localization: Publish translations:
php artisan vendor:publish --tag="filament-price-filter-translations"
Override in resources/lang/vendor/filament-price-filter/....
Multi-Column Filtering:
Filter by multiple price-related columns (e.g., base_price, discounted_price):
PriceFilter::make(['base_price', 'discounted_price'])
->queryUsing(fn ($query, $min, $max) => $query
->where(function ($q) use ($min, $max) {
$q->where(function ($q) use ($min, $max) {
$q->where('base_price', '>=', $min)
->orWhere('discounted_price', '>=', $min);
})
->where(function ($q) use ($min, $max) {
$q->where('base_price', '<=', $max)
->orWhere('discounted_price', '<=', $max);
});
})
)
Conditional Filtering: Enable/disable based on user role or context:
PriceFilter::make('price')
->visible(fn () => auth()->user()->can('view_prices'))
API Integration: Use the same filter logic in API routes:
$min = request('min_price');
$max = request('max_price');
$query->whereBetween('price', [$min, $max]);
Query Builder Conflicts:
queryUsing returns a valid Builder instance. Test with dd($query) if filtering fails.whereBetween with null values (e.g., whereBetween('price', [null, 100]) will fail).Decimal Precision:
cents: false, prices are rounded to integers. Ensure your database column matches (e.g., DECIMAL(10,0) vs DECIMAL(10,2)).Translation Overrides:
php artisan view:clear
Performance:
queryUsing logic can impact performance. Test with DB::enableQueryLog() to analyze queries:
$query->toSql(); // Inspect generated SQL
Log Filter Values:
Add debug output to queryUsing:
->queryUsing(fn ($query, $min, $max) => {
\Log::info("Price filter applied: min=$min, max=$max");
return $query->whereBetween('price', [$min, $max]);
})
Check Config:
Verify config/filament-price-filter.php for unexpected behavior (e.g., currency symbols).
Widget Visibility: If the filter doesn’t appear, check:
getTableWidgets() method.visible() callback).Custom UI:
Extend the widget’s view (resources/views/vendor/filament-price-filter/...) or use modifyQueryUsing to alter the underlying query logic.
Additional Features: Add presets (e.g., "Under $50", "$50-$100"):
PriceFilter::make('price')
->presets([
'under_50' => ['min' => 0, 'max' => 50],
'50_to_100' => ['min' => 50, 'max' => 100],
])
Local Storage:
Persist filter state using Filament’s useForm:
use Filament\Forms\Components\Hidden;
public static function getTableWidgets(): array
{
return [
PriceFilter::make('price')
->extraInput(Hidden::make('min_price')->column('min_price')),
// ...
];
}
Testing: Test filters in PHPUnit:
public function test_price_filter()
{
$widget = PriceFilter::make('price');
$query = $widget->modifyQuery(
Builder::make('products'),
10, 100
);
$query->toSql(); // Assert expected SQL
}
How can I help you explore Laravel packages today?