Tricks

Geocoding field using Select component

May 30, 2022
Dennis Koch
Form builder, Integration

Filament's Select component is quite powerful as it gives you a full autocomplete. You can use this for a simple geocoding search.

Requirements

  • Install Geocoder Laravel: https://geocoder-php.org/docs/
  • Publish config php artisan vendor:publish (Look for Geocoder)
  • Setup your Google Geocoding API-Key in config/geocoder.php. Alternatively you can install and configure any of the other address providers (https://geocoder-php.org/docs/#providers)

Code

<?php
 
Forms\Components\Select::make('geocoding')
->label('Search')
->searchable()
->reactive()
->dehydrated(false)
->getSearchResultsUsing(function ($query) {
return app('geocoder')->geocode($query)->get()
->mapWithKeys(fn ($result) => [
$result->getFormattedAddress() => $result->getFormattedAddress()
])
->toArray();
})
->afterStateUpdated(function ($state, $set) {
/** @var \Geocoder\Provider\GoogleMaps\Model\GoogleAddress $result */
$result = app('geocoder')->geocode($state)->get()->first();
$coords = $result->getCoordinates();
 
$set('street', $result->getStreetName());
$set('street_number', $result->getStreetNumber());
$set('city', $result->getLocality());
$set('zipcode', $result->getPostalCode());
$set('latitude', $coords->getLatitude());
$set('longitude', $coords->getLongitude());
}),
avatar
ABISHEK R SRIKAANTH

Is there a way to limit the search results to a specific country? Right now it searches for all the countries around the world. Just trying to figure out if there is a way to just set it to US or Canada.

avatar
Fagner dos Santos Gonçalves

Hello, i'm try using this component and return one error when i clear search input to search again. the laravel return this error message: Geocoder\Laravel\ProviderAndDumperAggregator::geocode(): Argument #1 ($value) must be of type string, null given, called in file

avatar

you need to change to : ->getSearchResultsUsing(function ($query) { if ($query) { return app('geocoder')->geocode($query)->get() ->mapWithKeys(fn ($result) => [ $result->getDisplayName() => $result->getDisplayName(), ]) ->toArray(); } return null; }) and

->afterStateUpdated(function ($state, $set) { if($state) { .... } }