malzariey/filament-daterangepicker-filter
Alpine.js-powered date range picker and filter for Filament. Pick day/month/year ranges with presets, optional time selection (12/24h), keyboard input validation, localization, accessibility, and modal/slide-over friendly dropdown teleport. Matches Filament v4 UI.
Installation
composer require malzariey/filament-daterangepicker-filter
Publish the config (if needed):
php artisan vendor:publish --provider="Malzariey\FilamentDateRangePickerFilter\FilamentDateRangePickerFilterServiceProvider"
Basic Usage Register the filter in a Filament resource:
use Malzariey\FilamentDateRangePickerFilter\Filters\DateRangePicker;
public static function getFilters(): array
{
return [
DateRangePicker::make('date_range')
->label('Date Range')
->column('created_at'), // Column to filter by
];
}
First Use Case
Add the filter to a table to filter records by a date range (e.g., created_at). The UI will render a date range picker (e.g., "Last 7 days," "This month") with a custom input for manual selection.
Dynamic Date Filtering Use the filter to dynamically adjust table data:
DateRangePicker::make('date_range')
->label('Custom Range')
->defaultRange('custom') // Start with a blank range
->column('published_at')
->query(fn (Builder $query, ?string $startDate, ?string $endDate) => $query
->when($startDate, fn ($q) => $q->whereDate('published_at', '>=', $startDate))
->when($endDate, fn ($q) => $q->whereDate('published_at', '<=', $endDate))
);
Integration with Filament Actions Combine with Filament actions (e.g., bulk actions) to restrict operations to the filtered date range:
public static function getTableActions(): array
{
return [
Tables\Actions\DeleteAction::make()->requiresConfirmation(),
];
}
Multi-Column Filtering
Filter by multiple date columns (e.g., start_date and end_date):
DateRangePicker::make('event_range')
->columns(['start_date', 'end_date'])
->query(fn ($query, ?string $start, ?string $end) => $query
->whereBetween('start_date', [$start, $end])
->orWhereBetween('end_date', [$start, $end])
);
Presets and Custom Ranges Define reusable date presets (e.g., "Last 30 days," "This year"):
DateRangePicker::make('date_range')
->presets([
'last_7_days' => 'Last 7 Days',
'this_month' => 'This Month',
->custom('Custom Range'),
]);
Customizing the UI Override the default view or blade components:
DateRangePicker::make('date_range')
->view('custom::filament.date-range-picker');
Localization Translate labels and presets:
DateRangePicker::make('date_range')
->label(__('filament-daterangepicker::labels.date_range'))
->presets([
'today' => __('filament-daterangepicker::presets.today'),
]);
Server-Side vs. Client-Side Filtering For large datasets, ensure the query is optimized:
->query(fn ($query, ?string $start, ?string $end) => $query
->whereDate('created_at', '>=', $start)
->whereDate('created_at', '<=', $end)
->select('id', 'name', 'created_at') // Limit columns for performance
);
Integration with Filament Forms Use the filter in forms for date-range-based submissions:
use Malzariey\FilamentDateRangePickerFilter\Components\DateRangePicker as DateRangePickerComponent;
public static function getFormSchema(): array
{
return [
DateRangePickerComponent::make('date_range')
->required()
->maxValue(now()->addDays(30)),
];
}
Column Mismatch
->column() doesn’t match the database.created_at vs. createdAt in Eloquent).->column('table.column') for disambiguation in polymorphic relations.Time Zone Confusion
->whereDate('created_at', '>=', $startDate->setTime(0, 0, 0))
Preset Overrides
->defaultRange() is set to a non-existent preset.'last_7_days' vs. 'last7days').Query Builder Incompatibility
$query = User::query()->with('posts');
$query = $this->applyDateRangeFilter($query, $start, $end);
Caching Issues
->ignoreCache() if needed.Log Filter Values
Add debug logs to inspect $startDate and $endDate:
->query(fn ($query, ?string $start, ?string $end) => {
\Log::info('Date Range Filter', ['start' => $start, 'end' => $end]);
return $query->whereBetween('created_at', [$start, $end]);
})
Inspect the Generated SQL Use Laravel’s query logging:
DB::enableQueryLog();
// Run the filtered query
\Log::info(DB::getQueryLog());
Check for JavaScript Errors
npm run dev or npm run build).Custom Date Ranges Extend the default presets by publishing the config:
// config/filament-daterangepicker.php
'presets' => [
'custom_preset' => [
'label' => 'Custom Label',
'start' => '2023-01-01',
'end' => '2023-12-31',
],
],
Dynamic Column Selection Use a closure to determine the column dynamically:
->column(fn () => $this->getDynamicColumn())
Event Listeners Listen for filter changes to trigger side effects:
use Malzariey\FilamentDateRangePickerFilter\Events\DateRangeFiltered;
DateRangeFiltered::listen(fn ($livewire, $start, $end) => {
// React to filter changes
});
Theme Customization Override Tailwind classes via Filament’s theme:
Filament::serving(fn () => Filament::registerTheme('custom-theme'));
Then target the date picker’s classes (e.g., .filament-date-range-picker).
Indexed Columns Ensure filtered columns are indexed in the database for large tables:
ALTER TABLE users ADD INDEX idx_created_at (created_at);
Lazy Loading For tables with many records, use pagination and lazy loading:
->paginate(20)
Avoid N+1 Queries Eager load relations in the filtered query:
->with(['posts' => fn ($q) => $q->whereBetween('published_at', [$start, $end])])
How can I help you explore Laravel packages today?