Créer un champ personnalisé Filament pour rechercher des adresses avec OpenStreetMap
Découvrez comment créer un champ personnalisé Filament qui permet à vos utilisateurs de rechercher une adresse via l’API OpenStreetMap
Dans ce tutoriel, nous allons créer un champ personnalisé Filament v3 qui permet à l’utilisateur de rechercher une adresse à l’aide de l’API OpenStreetMap (Nominatim). Lorsqu’une adresse est sélectionnée, le champ mettra à jour automatiquement le champ address.
🛠️ Étape 1 – Générer le champ personnalisé
Filament fournit une commande artisan pour créer un champ :
php artisan make:filament-custom-field AddressSearch
Cela crée deux fichiers :
app/Forms/Components/AddressSearch.phpresources/views/forms/components/address-search.blade.php
🎨 Étape 2 – Créer l’interface avec Alpine.js
Dans resources/views/forms/components/address-search.blade.php, utilisez le composant dynamique de Filament :
<x-dynamic-component
:component="$getFieldWrapperView()"
:field="$field"
>
<div
x-data="{
search: '',
results: [],
state: $wire.$entangle('{{ $getStatePath() }}').defer,
async searchAddress() {
if (this.search.length < 3) {
this.results = []
return
}
const response = await fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(this.search)}`)
const data = await response.json()
this.results = data.map(item => ({
label: item.display_name,
value: {
address: item.display_name,
latitude: item.lat,
longitude: item.lon,
}
})).slice(0, 5)
},
selectResult(result) {
this.state = result.value
this.search = result.label
this.results = []
}
}"
class="space-y-2"
>
<input
type="text"
class="w-full border rounded px-3 py-2"
placeholder="Rechercher une adresse..."
x-model="search"
x-on:input.debounce.500ms="searchAddress"
/>
<ul
class="border rounded bg-white max-h-60 overflow-y-auto shadow"
x-show="results.length > 0"
>
<template x-for="result in results" :key="result.label">
<li
x-text="result.label"
@click="selectResult(result)"
class="px-4 py-2 hover:bg-gray-100 cursor-pointer"
></li>
</template>
</ul>
</div>
</x-dynamic-component>
Ce champ :
- Utilise Alpine.js pour interagir avec l'utilisateur.
- Fait une requête vers OpenStreetMap après 500ms de frappe.
- Affiche une liste déroulante avec les résultats.
- Met à jour automatiquement la valeur du champ (et les autres champs via le backend).
📆 Étape 4 – Utiliser le champ dans un formulaire Filament
Dans votre PlaceResource::form() :
use App\Forms\Components\AddressSearch;
use Filament\Forms\Components\TextInput;
public static function form(Form $form): Form
{
return $form
->schema([
AddressSearch::make('location'), // champ principal contenant l’objet sélectionné
]);
}
✅ Résultat
- Champ avec recherche en temps réel sur OpenStreetMap.
- Intégration native dans Filament.
- Synchronisation automatique avec le modèle Laravel.
- Peut être réutilisé facilement dans d'autres formulaires.
🛍️ Aller plus loin
- Ajouter une carte (Leaflet.js) pour visualiser l’adresse sélectionnée.
- Limiter les résultats à un pays ou une ville spécifique.
- Ajouter un fallback ou gestion des erreurs API.
Et voilà ! Vous avez maintenant un champ personnalisable, moderne et réactif, directement connecté à une source ouverte de données d’adresses 🎉