127 lines
4.6 KiB
JavaScript
127 lines
4.6 KiB
JavaScript
(function () {
|
|
'use strict';
|
|
|
|
var label = document.getElementById('weather-label');
|
|
var results = document.getElementById('weather-location-results');
|
|
var latitude = document.getElementById('weather-latitude');
|
|
var longitude = document.getElementById('weather-longitude');
|
|
var latitudeValue = document.getElementById('weather-latitude-value');
|
|
var longitudeValue = document.getElementById('weather-longitude-value');
|
|
var timezone = document.getElementById('weather-timezone');
|
|
var manualCoordinates = document.getElementById('weather-manual-coordinates');
|
|
var timer;
|
|
var requestId = 0;
|
|
|
|
if (!label || !results || !latitude || !longitude || !timezone) {
|
|
return;
|
|
}
|
|
|
|
function clearResults() {
|
|
results.replaceChildren();
|
|
results.classList.add('d-none');
|
|
}
|
|
|
|
function selectResult(result) {
|
|
label.value = result.label;
|
|
latitude.value = result.latitude;
|
|
longitude.value = result.longitude;
|
|
timezone.value = result.timezone;
|
|
latitudeValue.value = result.latitude;
|
|
longitudeValue.value = result.longitude;
|
|
latitude.disabled = true;
|
|
longitude.disabled = true;
|
|
latitude.removeAttribute('name');
|
|
longitude.removeAttribute('name');
|
|
latitudeValue.name = 'latitude';
|
|
longitudeValue.name = 'longitude';
|
|
manualCoordinates.classList.remove('d-none');
|
|
clearResults();
|
|
}
|
|
|
|
function enableManualCoordinates() {
|
|
latitude.disabled = false;
|
|
longitude.disabled = false;
|
|
latitude.name = 'latitude';
|
|
longitude.name = 'longitude';
|
|
latitudeValue.removeAttribute('name');
|
|
longitudeValue.removeAttribute('name');
|
|
manualCoordinates.classList.add('d-none');
|
|
}
|
|
|
|
function renderResults(items) {
|
|
results.replaceChildren();
|
|
if (!items.length) {
|
|
clearResults();
|
|
return;
|
|
}
|
|
items.forEach(function (item) {
|
|
var button = document.createElement('button');
|
|
button.type = 'button';
|
|
button.className = 'list-group-item list-group-item-action';
|
|
button.textContent = item.label;
|
|
button.addEventListener('click', function () { selectResult(item); });
|
|
results.appendChild(button);
|
|
});
|
|
results.classList.remove('d-none');
|
|
}
|
|
|
|
label.addEventListener('input', function () {
|
|
enableManualCoordinates();
|
|
window.clearTimeout(timer);
|
|
var query = label.value.trim();
|
|
if (query.length < 2) {
|
|
clearResults();
|
|
return;
|
|
}
|
|
timer = window.setTimeout(function () {
|
|
var currentRequestId = ++requestId;
|
|
fetch('/data-sources/weather/geocode?q=' + encodeURIComponent(query), { credentials: 'same-origin' })
|
|
.then(function (response) { if (!response.ok) throw new Error('Lookup failed'); return response.json(); })
|
|
.then(function (data) { if (currentRequestId === requestId) renderResults(data.results || []); })
|
|
.catch(function () { if (currentRequestId === requestId) clearResults(); });
|
|
}, 300);
|
|
});
|
|
|
|
manualCoordinates.addEventListener('click', enableManualCoordinates);
|
|
|
|
if (latitude.value && longitude.value) {
|
|
selectResult({ label: label.value, latitude: latitude.value, longitude: longitude.value, timezone: timezone.value });
|
|
}
|
|
|
|
var refreshButton = document.querySelector('[data-weather-refresh-url]');
|
|
if (refreshButton) {
|
|
refreshButton.addEventListener('click', function () {
|
|
refreshButton.disabled = true;
|
|
fetch(refreshButton.getAttribute('data-weather-refresh-url'), { method: 'POST', credentials: 'same-origin', headers: { 'X-Requested-With': 'XMLHttpRequest' } })
|
|
.then(function (response) {
|
|
if (!response.ok) throw new Error('Refresh failed');
|
|
window.location.assign(response.url);
|
|
})
|
|
.catch(function () { refreshButton.disabled = false; });
|
|
});
|
|
}
|
|
|
|
var forecastButtons = document.querySelectorAll('[data-weather-forecast-mode]');
|
|
var dailyForecast = document.getElementById('weather-daily-forecast');
|
|
var hourlyForecast = document.getElementById('weather-hourly-forecast');
|
|
forecastButtons.forEach(function (button) {
|
|
button.addEventListener('click', function () {
|
|
var hourly = button.getAttribute('data-weather-forecast-mode') === 'hourly';
|
|
dailyForecast.classList.toggle('d-none', hourly);
|
|
hourlyForecast.classList.toggle('d-none', !hourly);
|
|
forecastButtons.forEach(function (item) {
|
|
var selected = item === button;
|
|
item.classList.toggle('btn-primary', selected);
|
|
item.classList.toggle('btn-outline-secondary', !selected);
|
|
item.setAttribute('aria-pressed', selected ? 'true' : 'false');
|
|
});
|
|
});
|
|
});
|
|
|
|
document.addEventListener('click', function (event) {
|
|
if (!results.contains(event.target) && event.target !== label) {
|
|
clearResults();
|
|
}
|
|
});
|
|
}());
|