krixer/google-map-form-type-bundle
A Symfony bundle that provides a Google Maps form type for selecting and storing geographic coordinates directly in forms. It adds an interactive map picker with configurable options, making location input easier in admin and user interfaces.
This is a Symfony bundle, not a Laravel package — the day-one decision is whether you're actually in a Symfony app. There is no service provider, no Blade directive, and nothing to php artisan vendor:publish. It exposes exactly one thing you'll use: a form type that renders a draggable Google Map alongside a hidden input carrying the selected coordinates.
Minimal path:
composer require krixer/google-map-form-type-bundle
Register the bundle (config/bundles.php on Symfony 4+, AppKernel::registerBundles() on older):
OhGoogleMapFormTypeBundle\OhGoogleMapFormTypeBundle::class => ['all' => true],
Publish the bundle's JS/Twig assets so the map renders:
php bin/console assets:install --symlink public
Then use the type on a form field:
use OhGoogleMapFormTypeBundle\Form\Type\GoogleMapType;
$builder->add('latlng', GoogleMapType::class, [
'lat' => 48.8566,
'lng' => 2.3522,
'zoom' => 15,
'map_width' => 600,
'map_height' => 400,
]);
Render normally ({{ form_row(form.latlng) }}) and confirm the map appears before wiring up persistence.
Where to look first: Form/Type/GoogleMapType.php (configureOptions is the authoritative option list for whatever version you pinned) and the Twig widget in Resources/views/Form/. The README is thin; the source is small enough to read end-to-end in ten minutes and you will almost certainly need to.
First real use case: an admin "Place" or "Address" edit form where an editor drops a pin, submits, and you persist latitude/longitude — typically as DECIMAL(10,7) columns, with the map re-centering on the saved values when the record is edited.
Two columns, one widget. The bundle gives you one form field, but you usually want two entity properties. Keep the map field unmapped and bridge it in POST_SUBMIT:
$builder->add('latlng', GoogleMapType::class, [
'mapped' => false,
'lat' => $place->getLatitude(),
'lng' => $place->getLongitude(),
'zoom' => 16,
]);
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
$data = (string) $event->getForm()->get('latlng')->getData();
$parts = array_map('trim', explode(',', $data));
if (count($parts) === 2 && is_numeric($parts[0]) && is_numeric($parts[1])) {
$event->getData()
->setLatitude((float) $parts[0])
->setLongitude((float) $parts[1]);
}
});
If you'd rather keep a single latlng string column, skip the listener and just read it back — but you lose queryability ("within bounding box") later.
Reuse via a wrapper type. You'll add the same options to five forms. Make LocationType that sets getParent() => GoogleMapType::class and provides your defaults (zoom, height, map type, search box), then use that everywhere. One place to change when you upgrade.
Admin panels. In EasyAdmin, FormField::addField('latlng')->setFormType(GoogleMapType::class)->setFormTypeOptions([...]) works; in Sonata, wire it as a form field with the same options. Both funnel through the same Symfony form theme, so the widget's assets must be loaded on those pages too — this is the most common "map is blank in admin but fine on the frontend" cause.
Validation. The map can legitimately submit nothing (user never clicked). Add NotBlank plus a custom constraint asserting lat ∈ [-90, 90] and lng ∈ [-180, 180]; otherwise you'll silently persist 0,0 (Null Island) and think geocoding is broken.
Editing existing records. Always pass current lat/lng into the options — the widget does not read them from your entity automatically when the field is unmapped. Default to a map center of your country rather than 0,0 for new records; it makes the marker easier to place.
&key=YOUR_KEY (and &libraries=places if you're using the search box). Do this via form_themes in config rather than editing vendor code.<script> tag in your base layout, not buried in a bundle that loads after the inline init.turbo:load handler and destroy the previous map instance to avoid "Map is already initialized" leaks.AbstractType internals and Twig form block overrides have shifted since. Pin the exact version, run your test suite on your Symfony/PHP combination, and be prepared to fork or vendor-patch — with zero dependents there's no community pressure keeping this current.null) from 0,0. A NOT NULL column with a 0 default will make every unset record look like it's off the coast of Africa.DECIMAL(10,7), not FLOAT. Rounding drift shows up when you re-center edited pins.form.latlng.vars (lat, lng, map_width) in Twig, then check the browser console for the Maps API key rejection — that error message is usually the whole diagnosis.GoogleMapType to change configureOptions defaults. Beyond that the surface is small — if you need reverse geocoding, autocomplete with address parsing, or multiple markers, this package won't carry you and you'll be writing the JS yourself anyway.How can I help you explore Laravel packages today?