Files
ludikevent_crm/assets/flow_reservation.js

99 lines
4.1 KiB
JavaScript
Raw Normal View History

class ZipCodeCityUpdater {
constructor(zipCodeInputSelector, citySelectSelector, apiUrl) {
this.zipCodeInput = document.querySelector(zipCodeInputSelector);
this.citySelect = document.querySelector(citySelectSelector); // Changed to citySelect
this.apiUrl = apiUrl;
this.timer = null;
this.debounceTime = 500; // ms
// Store initial value from the select element (if any was pre-selected by Twig)
this.initialCityValue = this.citySelect ? this.citySelect.value : '';
if (this.zipCodeInput && this.citySelect) {
this.zipCodeInput.addEventListener('input', this.debounce(this.handleZipCodeChange.bind(this)));
// Trigger on page load if a zip code is already present
if (this.zipCodeInput.value) {
this.handleZipCodeChange();
}
}
}
debounce(func) {
return function(...args) {
const context = this;
clearTimeout(context.timer);
context.timer = setTimeout(() => func.apply(context, args), context.debounceTime);
};
}
async handleZipCodeChange() {
const zipCode = this.zipCodeInput.value.trim();
// Save current city selection if any, before clearing
const currentlySelectedCity = this.citySelect.value;
// Clear existing options, but keep the default placeholder if any
this.citySelect.innerHTML = '<option value="">Sélectionnez une ville</option>';
this.citySelect.value = '';
this.citySelect.disabled = true; // Disable until cities are loaded or cleared
if (zipCode.length !== 5 || !/^\d+$/.test(zipCode)) {
// If zip code is invalid or empty, disable and reset select
this.citySelect.disabled = false; // Re-enable for placeholder
return;
}
try {
const response = await fetch(this.apiUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ zipCode: zipCode }),
});
if (!response.ok) {
console.error(`HTTP error! status: ${response.status}`);
this.citySelect.disabled = false; // Re-enable for placeholder
return;
}
const data = await response.json();
if (data.cities && data.cities.length > 0) {
data.cities.forEach(city => {
const option = document.createElement('option');
option.value = city;
option.textContent = city;
this.citySelect.appendChild(option);
});
// Attempt to re-select the city that was previously selected, or the initial one
if (data.cities.includes(currentlySelectedCity)) {
this.citySelect.value = currentlySelectedCity;
} else if (data.cities.includes(this.initialCityValue)) {
this.citySelect.value = this.initialCityValue;
} else if (data.cities.length === 1) {
// Automatically select if only one city is returned and no previous match
this.citySelect.value = data.cities[0];
}
this.citySelect.disabled = false; // Enable once options are loaded
} else {
// If no cities found, ensure select is enabled but shows only placeholder
this.citySelect.disabled = false;
}
} catch (error) {
console.error('Error fetching city:', error);
this.citySelect.disabled = false; // Re-enable on error
}
}
}
// Global initialization - run when the DOM is fully loaded or Turbo loads a new page
document.addEventListener('turbo:load', () => {
// Note: Use CSS selectors for querySelector
new ZipCodeCityUpdater('input[name="billingZipCode"]', '#billingTownSelect', '/cities/lookup');
new ZipCodeCityUpdater('input[name="zipCodeEvent"]', '#townEventSelect', '/cities/lookup');
});