eekes/sulu-form-city-select-bundle
Adds a City Select field to Sulu forms, letting frontend users pick a city from a predefined list. Install via Composer and enable the bundle; the new field appears automatically in the form field list.
Installation:
composer require eekes/sulu-form-city-select-bundle
Register the bundle in config/bundles.php:
Eekes\Sulu\FormCitySelectBundle\EekesSuluFormCitySelectBundle::class => ['all' => true],
First Use Case:
config/forms.yml or via the admin UI).Where to Look First:
config/packages/eekes_sulu_form_city_select.yaml.Resources/views/forms/_city_select.html.twig).# config/forms.yml
my_form:
fields:
city:
type: city_select
label: "Select a City"
options:
required: true
placeholder: "Choose a city..."
public function store(Request $request)
{
$city = $request->input('city'); // e.g., "Berlin" or "New York"
// Process city data (e.g., save to database or use in logic)
}
config/packages/eekes_sulu_form_city_select.yaml:
eekes_sulu_form_city_select:
api:
enabled: true
endpoint: "https://api.example.com/cities"
cache_ttl: 3600 # Cache cities for 1 hour
// src/Service/CityProvider.php
class CityProvider implements CityProviderInterface
{
public function getCities(): array
{
return [
['id' => 1, 'name' => 'Paris'],
['id' => 2, 'name' 'London'],
];
}
}
Bind the service in services.yaml:
services:
App\Service\CityProvider: ~
eekes_sulu_form_city_select.city_provider: '@App\Service\CityProvider'
Extend Twig Templates: Override the default template for the city select field:
php artisan vendor:publish --tag=sulu-form-city-select-templates
Customize templates/forms/fields/city_select.html.twig to add classes, icons, or validation messages.
Add JavaScript Behavior: Use Sulu’s form event system to attach custom logic:
// assets/js/app.js
Sulu.Form.on('citySelect:change', function(event) {
const city = event.detail.value;
console.log('Selected city:', city);
// Trigger additional actions (e.g., load city-specific data)
});
$request->validate([
'city' => 'required|string|exists:cities,name', // Assuming a `cities` table
]);
$cityData = City::where('name', $request->city)->first();
$coordinates = $cityData->coordinates; // e.g., ["lat" => 52.5200, "lng" => 13.4050]
# translations/messages.en.yml
city_select:
paris: "Paris (France)"
london: "London (UK)"
Reference translations in your form:
fields:
city:
options:
choices:
paris: "%city_select.paris%"
london: "%city_select.london%"
Missing API Configuration:
curl or Postman before integrating:
curl https://api.example.com/cities
api.enabled: false in config if using a custom provider, or debug API errors in Sulu logs (var/log/dev.log).Caching Issues:
php artisan cache:clear
php artisan sulu:cache:clear
cache_ttl: 0 in config for development to bypass caching.Field Not Appearing in Form Builder:
bundles.php and dependencies (e.g., SuluFormBundle) are installed.php artisan sulu:form:fields:list. If not, verify the bundle’s service tags are registered.Case Sensitivity in City Names:
$request->validate([
'city' => 'required|string|exists:cities,name',
]);
$normalizedCity = mb_strtolower($request->city);
Performance with Large City Lists:
// Use a library like Select2 with AJAX
$('.city-select').select2({
ajax: {
url: '/api/cities',
dataType: 'json',
delay: 250,
data: function(params) {
return { q: params.term };
}
}
});
Log City Data: Add logging to inspect city data flow:
use Psr\Log\LoggerInterface;
class CitySelectHandler
{
public function __construct(private LoggerInterface $logger) {}
public function handleCitySelection(string $city): void
{
$this->logger->info('City selected', ['city' => $city]);
// Process city...
}
}
Check Bundle Events:
The bundle may dispatch events (e.g., city.select). Listen for them in your code:
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
$dispatcher->addListener('city.select', function($event) {
$city = $event->getCity();
// Handle event...
});
Database Mismatches: If cities submitted via the form don’t match database entries, verify:
name column in your cities table matches the submitted values.Custom City Data Source:
Implement Eekes\Sulu\FormCitySelectBundle\Provider\CityProviderInterface to replace the default provider:
class DatabaseCityProvider implements CityProviderInterface
{
public function getCities(): array
{
return City::query()->pluck('name')->toArray();
}
}
Bind the service in services.yaml:
eekes_sulu_form_city_select.city_provider: '@App\Service\DatabaseCityProvider'
Add City Metadata: Extend the city select field to include additional data (e.g., country, population):
fields:
city:
type: city_select
options:
display_properties: ['name', 'country', 'population']
Update the template to render extra properties:
{# templates/forms/fields/city_select.html.twig #}
<div class="city-info">
{{ field.value.name }} ({{ field.value.country }})
</div>
Geocoding Integration: Automatically fetch coordinates for selected cities using a service like Google Maps or OpenStreetMap:
use Geocoder\Geocoder;
use Geocoder\Provider\OpenStreetMap\OpenStreetMap;
$geocoder
How can I help you explore Laravel packages today?