Skip to main content
MapPickerField ← Back to Table of Contents

Summary

Mapbox-powered address picker with geocoding search, draggable pin, and configurable stored fields.
ClassBjanczak\FilamentFlexFields\Filament\Forms\Components\MapPickerField
State type (internal)Canonical array with keys from ALL_FIELDS
Dehydrated stateSubset of fields per fields(), or formatted string per storeFormat()
FieldTypemap_picker

Basic usage

use Bjanczak\FilamentFlexFields\Filament\Forms\Components\MapPickerField;

MapPickerField::make('location')
    ->label('Office address')
    ->fields(['lat', 'lng', 'street', 'city', 'postcode', 'country', 'place_name'])
    ->requiredFields(['lat', 'lng', 'city'])
    ->streetAddressesOnly()
    ->defaultCenter([52.2297, 21.0122])
    ->defaultZoom(12)
    ->countries(['PL', 'DE']);

MapPickerField::make('venue')
    ->storeFormat(MapPickerField::STORE_STRING)
    ->stringFormat('{street}, {city} ({country})');
Requires Mapbox token in config('filament-flex-fields.mapbox.access_token') or per-field mapboxToken().

State format

Canonical internal keys (ALL_FIELDS): lat, lng, street, city, region, postcode, country, country_name, place_name
storeFormatDehydrated value
structured (default)Array with only keys from fields()
stringSingle string from stringFormat() placeholders {field}
On hydrate, strings set place_name; arrays merge into canonical state. Coordinates rounded to 7 decimal places.

Validation

BehaviourDetail
required()At least one configured field must have a value
requiredFields()Listed fields must be filled when any value present
LatitudeMust be −90…90 when lat is in fields()
LongitudeMust be −180…180 when lng is in fields()
countries()country must be in whitelist when set
streetAddressesOnly()street must be filled; cities, regions, and other non-address results are rejected

Configuration API

fields(array|Closure $fields)

Which address parts to store and show. Must include at least one valid key from ALL_FIELDS. Default: lat, lng, street, city, postcode, country, place_name.
MapPickerField::make('field_name')
    ->fields(['value1', 'value2']);

storeFormat(string|Closure $format)

MapPickerField::STORE_STRUCTURED or MapPickerField::STORE_STRING.
MapPickerField::make('field_name')
    ->storeFormat('value');

stringFormat(string|Closure $format)

Template for string storage. Placeholders: {lat}, {lng}, {street}, etc. Default: {place_name}.
MapPickerField::make('field_name')
    ->stringFormat('value');

requiredFields(array|Closure $fields)

Fields required when the location is partially filled. Intersected with fields().
MapPickerField::make('field_name')
    ->requiredFields(['value1', 'value2']);

mapboxToken(string|Closure|null $token)

Override Mapbox access token. Falls back to config.
MapPickerField::make('field_name')
    ->mapboxToken('value');

defaultCenter(array|Closure $center)

[latitude, longitude]. Default: Warsaw [52.2297, 21.0122].
MapPickerField::make('field_name')
    ->defaultCenter(['value1', 'value2']);

defaultZoom(int|Closure $zoom)

Initial map zoom 122. Default: 12.
MapPickerField::make('field_name')
    ->defaultZoom(10);

searchable(bool|Closure $condition = true)

Address search box. Default: true.
MapPickerField::make('field_name')
    ->searchable(true);

countries(array|Closure|null $countries)

Restrict geocoding results to ISO country codes. null = worldwide.
MapPickerField::make('field_name')
    ->countries(['PL', 'DE', 'US']);

streetAddressesOnly(bool|Closure $condition = true)

Restrict search, map clicks, and pin drags to full street addresses only. Uses Mapbox types=address, filters autocomplete results client-side, and validates that street is present. Cities, regions, postcodes alone, and other area-level results cannot be selected. Default: false. When enabled, this overrides searchTypes() and always uses address.
MapPickerField::make('field_name')
    ->streetAddressesOnly(true);

searchTypes(array|Closure|null $types)

Limit Mapbox Geocoding API results to specific place types. Pass null (default) to search all supported types (addresses, POI, cities, regions, etc.). Use Bjanczak\FilamentFlexFields\Enums\MapboxSearchType or string values: country, region, postcode, district, place, locality, neighborhood, address, poi.
use Bjanczak\FilamentFlexFields\Enums\MapboxSearchType;

// Shops, restaurants, landmarks only
MapPickerField::make('pickup_point')
    ->searchTypes([MapboxSearchType::Poi]);

// Streets and POI
MapPickerField::make('location')
    ->searchTypes([MapboxSearchType::Address, MapboxSearchType::Poi]);

// Cities only
MapPickerField::make('city')
    ->searchTypes([MapboxSearchType::Place]);

readOnly(bool|Closure $condition = true)

Disable map interaction.
MapPickerField::make('field_name')
    ->readOnly(true);

Public helper methods

MethodReturnsDescription
getFields()list<string>Configured field keys
getStoreFormat()stringstructured or string
getStringFormat()stringString template
getRequiredFields()list<string>Required subset
getMapboxToken()string|nullResolved token
getDefaultCenter()array<0: float, 1: float>Map center
getDefaultZoom()intZoom level
isSearchable()boolSearch enabled
isStreetAddressesOnly()boolStreet-address restriction enabled
getSearchTypes()list<string>|nullMapbox types filter (null = all types)
getCountries()list<string>|nullCountry filter
hasStreetAddress(array $state)boolWhether canonical state has a street name
getEmptyCanonicalState()arrayAll keys null
hydrateToCanonical(mixed $state)arrayNormalize incoming state
dehydrateFromCanonical(array $state)mixedOutput for save
normalizeCanonical(array $state)arrayMerge + auto place_name
hasAnyStoredValue(array $state)boolAny configured field filled
formatString(array $state)stringApply string template
getSummaryLabel(array $state)string|nullDisplay label
getValidationMessage(array $state)string|nullFirst validation error
getWrapperClasses()arrayfff-map-picker-field

FlexField schema config

Config keyMaps to
fieldsfields()
store_formatstoreFormat()
string_formatstringFormat()
required_fieldsrequiredFields()
mapbox_tokenmapboxToken()
default_centerdefaultCenter()
default_zoomdefaultZoom()
searchablesearchable()
countriescountries()
street_addresses_onlystreetAddressesOnly()
search_typessearchTypes() — e.g. ['poi'], ['address', 'poi'], or null for all

CSS classes

ClassRole
fff-map-picker-fieldRoot wrapper
fff-map-pickerAlpine root
fff-map-picker__search-wrapSearch input + dropdown container
fff-map-picker__dropdown-panelAutocomplete suggestions list
fff-map-picker__selection-errorInline error when a non-street result is rejected
fff-map-picker__canvasMapbox map container
fff-map-picker__summarySelected address summary below map

Implementation notes

  • Set MAPBOX_ACCESS_TOKEN or filament-flex-fields.mapbox.access_token before use.
  • When lat/lng exist but place_name is empty, a summary is built from street, postcode, city, and country.
  • Shared geocoding helpers live in resources/js/support/mapbox-geocoding.js (also used by AddressAutocompleteField).
  • With streetAddressesOnly(), a map click or pin drag outside a resolvable street address shows an inline error and does not update state (the pin snaps back on drag).
  • Livewire: uses wire:ignore + $entangle for state and wire:key over config props for remounts — see Shared concepts → wire:ignore strategy.