175 lines
4.9 KiB
HTML
175 lines
4.9 KiB
HTML
{{define "location-geocode-header"}}
|
|
<style>
|
|
.detail-label {
|
|
font-size: 0.8rem;
|
|
text-transform: uppercase;
|
|
color: #6c757d;
|
|
margin-bottom: 2px;
|
|
font-weight: 600;
|
|
}
|
|
.detail-value {
|
|
font-weight: 500;
|
|
}
|
|
.main-address {
|
|
font-weight: 500;
|
|
}
|
|
.place-info {
|
|
font-size: 0.85rem;
|
|
color: #6c757d;
|
|
margin-top: 2px;
|
|
}
|
|
.suggestions-container {
|
|
position: absolute;
|
|
width: 100%;
|
|
max-height: 300px;
|
|
overflow-y: auto;
|
|
z-index: 1000;
|
|
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
|
}
|
|
.suggestion-item {
|
|
cursor: pointer;
|
|
padding: 10px 12px;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
}
|
|
.suggestion-item:hover {
|
|
background-color: #f8f9fa;
|
|
}
|
|
</style>
|
|
<script>
|
|
// Display suggestions in the dropdown
|
|
function displaySuggestions(suggestions) {
|
|
const suggestionsContainer = document.getElementById('suggestions');
|
|
// Clear previous suggestions
|
|
suggestionsContainer.innerHTML = '';
|
|
|
|
if (suggestions.length === 0) {
|
|
suggestionsContainer.classList.add('d-none');
|
|
return;
|
|
}
|
|
|
|
// Create and append suggestion items
|
|
suggestions.forEach(suggestion => {
|
|
const item = document.createElement('div');
|
|
item.className = 'suggestion-item list-group-item';
|
|
|
|
// Create structure for the main address and place info
|
|
const mainAddressDiv = document.createElement('div');
|
|
mainAddressDiv.className = 'main-address';
|
|
mainAddressDiv.textContent = suggestion.properties.name || suggestion.properties.full_address;
|
|
|
|
item.appendChild(mainAddressDiv);
|
|
if (suggestion.properties.place_formatted) {
|
|
const placeInfoDiv = document.createElement('div');
|
|
placeInfoDiv.className = 'place-info';
|
|
placeInfoDiv.textContent = suggestion.properties.place_formatted || '';
|
|
item.appendChild(placeInfoDiv);
|
|
}
|
|
// Handle click on a suggestion
|
|
item.addEventListener('click', function() {
|
|
addressInput.value = suggestion.properties.name || suggestion.properties.full_address;
|
|
suggestionsContainer.classList.add('d-none');
|
|
|
|
// Display the selected location details
|
|
displaySelectedLocation(suggestion);
|
|
setMapMarker(suggestion.geometry.coordinates);
|
|
});
|
|
|
|
suggestionsContainer.appendChild(item);
|
|
});
|
|
|
|
// Show the suggestions container
|
|
suggestionsContainer.classList.remove('d-none');
|
|
}
|
|
|
|
// Fetch suggestions from Mapbox API
|
|
async function fetchGeocodingSuggestions(query) {
|
|
// Replace with your actual Mapbox access token
|
|
const MAPBOX_ACCESS_TOKEN = '{{.MapboxToken}}';
|
|
|
|
try {
|
|
const url = `https://api.mapbox.com/search/geocode/v6/forward?q=${encodeURIComponent(query)}&access_token=${MAPBOX_ACCESS_TOKEN}`;
|
|
|
|
const response = await fetch(url);
|
|
const data = await response.json();
|
|
|
|
displaySuggestions(data.features || []);
|
|
} catch (error) {
|
|
console.error('Error fetching geocoding suggestions:', error);
|
|
}
|
|
}
|
|
|
|
function displaySelectedLocation(suggestion) {
|
|
const locationDisplayContainer = document.getElementById('locationDisplayContainer');
|
|
|
|
// Show location display container
|
|
locationDisplayContainer.classList.remove('d-none');
|
|
|
|
// Extract context data from properties
|
|
const props = suggestion.properties;
|
|
const context = props.context || {};
|
|
|
|
// Populate structured fields
|
|
// Street Address - combine address, street, housenumber if available
|
|
let addressStr = '';
|
|
if (context.address) addressStr += context.address.address_number;
|
|
if (context.street) {
|
|
if (addressStr) addressStr += ' ';
|
|
addressStr += context.street.name;
|
|
}
|
|
if (addressStr === '') {
|
|
addressStr = props.name || props.full_address || '-';
|
|
}
|
|
streetAddress.textContent = addressStr;
|
|
|
|
// Post Code
|
|
postCode.textContent = context.postcode.name || '-';
|
|
|
|
// District (could be district, locality, or place)
|
|
district.textContent = context.district.name || context.place.name || context.locality.name || '-';
|
|
|
|
// Region (state, province, etc.)
|
|
region.textContent = context.region.name || '-';
|
|
|
|
// Country
|
|
country.textContent = context.country.name || '-';
|
|
}
|
|
function onAddressInput() {
|
|
const suggestionsContainer = document.getElementById('suggestions');
|
|
|
|
let debounceTimer;
|
|
const query = this.value.trim();
|
|
|
|
// Clear previous timer
|
|
clearTimeout(debounceTimer);
|
|
|
|
// Clear suggestions if input is less than 3 characters
|
|
if (query.length < 3) {
|
|
suggestionsContainer.classList.add('d-none');
|
|
suggestionsContainer.innerHTML = '';
|
|
return;
|
|
}
|
|
|
|
// Debounce API calls (wait 300ms after typing stops)
|
|
debounceTimer = setTimeout(() => {
|
|
fetchGeocodingSuggestions(query);
|
|
}, 300);
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const addressInput = document.getElementById('addressInput');
|
|
const suggestionsContainer = document.getElementById('suggestions');
|
|
const locationDetails = document.getElementById('locationDetails');
|
|
|
|
|
|
// Listen for input changes
|
|
addressInput.addEventListener('input', onAddressInput);
|
|
|
|
// Close suggestions when clicking outside
|
|
document.addEventListener('click', function(event) {
|
|
if (!addressInput.contains(event.target) && !suggestionsContainer.contains(event.target)) {
|
|
suggestionsContainer.classList.add('d-none');
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
{{end}}
|