salemaljebaly/filament-map-picker
Installation:
composer require salemaljebaly/filament-map-picker
No additional configuration is required for basic usage.
First Use Case:
Add the MapPicker component to a Filament form alongside hidden latitude/longitude fields:
use SalemAljebaly\FilamentMapPicker\MapPicker;
MapPicker::make('location')
->latlngFields('latitude', 'longitude')
->searchable();
Where to Look First:
config/filament-map-picker.php) for global defaults.->collapsibleSearch()).Form Integration:
Always pair MapPicker with hidden latitude/longitude fields (non-dehydrated). Example:
Forms\Components\Hidden::make('latitude')->rules(['nullable', 'numeric']),
Forms\Components\Hidden::make('longitude')->rules(['nullable', 'numeric']),
MapPicker::make('location')
->latlngFields('latitude', 'longitude')
->searchable();
Dynamic Updates:
Use live() for real-time updates (e.g., search-as-you-type):
MapPicker::make('location')
->latlngFields('latitude', 'longitude')
->searchable()
->live(); // Updates hidden fields on marker drag/search
Table Integration:
For read-only maps in tables, use the MapPicker widget:
use SalemAljebaly\FilamentMapPicker\Widgets\MapPicker;
MapPicker::make('location')
->latlngFields('latitude', 'longitude')
->readOnly();
Default Center: Set a default location (e.g., for a specific region):
MapPicker::make('location')
->latlngFields('latitude', 'longitude')
->defaultCenter([40.7128, -74.0060]); // New York
Custom Styling: Override Leaflet styles via published config:
// config/filament-map-picker.php
'map' => [
'tileLayer' => 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
'attribution' => '© OpenStreetMap contributors',
],
Localization: Use Filament’s built-in localization with RTL support (no extra config):
MapPicker::make('location')
->searchable()
->direction('rtl'); // Auto-detected via `dir="auto"` in search input
Livewire Integration: Ensure cleanup on navigation by leveraging Filament’s SPA-safe design (no manual cleanup needed).
Missing Hidden Fields:
latlngFields() throws Undefined array key if hidden fields are missing.Hidden components for latitude/longitude before MapPicker.Dehydrated Fields:
Hidden::make('latitude')->dehydrated(false),
API Key Misconceptions:
Dark Mode Quirks:
tileLayer in config to use a dark-compatible provider (e.g., https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png).Performance:
live() for non-critical maps to reduce OpenStreetMap API calls:
MapPicker::make('location')->live(false);
Console Logs: Enable Leaflet debug logs via config:
'debug' => env('MAP_PICKER_DEBUG', false),
Check browser console for errors (e.g., CORS issues with tile servers).
Marker Placement: If markers don’t appear, verify:
latitude/longitude) are populated.Search Not Working:
searchable() is called.Custom Tile Layers: Override the default OpenStreetMap layer in config:
'map' => [
'tileLayer' => 'https://{s}.tile.thunderforest.com/transport/{z}/{x}/{y}.png',
'tileLayerOptions' => [
'attribution' => '© Thunderforest',
'apiKey' => env('THUNDERFOREST_KEY'), // If required
],
],
Event Listeners:
Attach custom logic to map events (e.g., moveend):
MapPicker::make('location')
->latlngFields('latitude', 'longitude')
->extraAttributes([
'data-filament-map-picker-options' => json_encode([
'events' => [
'moveend' => 'console.log("Map moved!")',
],
]),
]);
Local Storage:
Persist user preferences (e.g., default zoom) using Filament’s useState:
use Filament\Forms\Components\Hidden;
Hidden::make('default_zoom')
->default(fn () => session('map_default_zoom', 13))
->afterStateUpdated(fn ($state) => session(['map_default_zoom' => $state]));
Testing: Mock the map component in PHPUnit:
$this->filament->mockMapPicker();
How can I help you explore Laravel packages today?