New date picker
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
<li>Departure: {{ departure_time }}</li>
|
||||
<li>Purpose: {{ purpose }}</li>
|
||||
</ul>
|
||||
<p>You can <a href="{{ base_url }}/edit?token={{ public_token }}">edit or cancel</a> your PPR using this secure link.</p>
|
||||
<p>You can <a href="{{ base_url }}/edit.html?token={{ public_token }}">edit or cancel</a> your PPR using this secure link.</p>
|
||||
<p>You will receive further updates via email.</p>
|
||||
<p>Best regards,<br>Swansea Airport Team</p>
|
||||
</body>
|
||||
|
||||
154
web/edit.html
154
web/edit.html
@@ -289,7 +289,12 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="eta" class="required">Estimated Time of Arrival (Local Time)</label>
|
||||
<input type="datetime-local" id="eta" name="eta" required>
|
||||
<div style="display: flex; gap: 0.5rem;">
|
||||
<input type="date" id="eta-date" name="eta-date" required style="flex: 1;">
|
||||
<select id="eta-time" name="eta-time" required style="flex: 1;">
|
||||
<option value="">Select Time</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pob_in" class="required">Persons on Board (Arrival)</label>
|
||||
@@ -311,7 +316,12 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="etd">Estimated Time of Departure (Local Time)</label>
|
||||
<input type="datetime-local" id="etd" name="etd">
|
||||
<div style="display: flex; gap: 0.5rem;">
|
||||
<input type="date" id="etd-date" name="etd-date" style="flex: 1;">
|
||||
<select id="etd-time" name="etd-time" style="flex: 1;">
|
||||
<option value="">Select Time</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pob_out">Persons on Board (Departure)</label>
|
||||
@@ -370,6 +380,28 @@
|
||||
window.location.href = '/';
|
||||
}
|
||||
|
||||
// Initialize time dropdowns
|
||||
function initializeTimeDropdowns() {
|
||||
const timeSelects = ['eta-time', 'etd-time'];
|
||||
|
||||
timeSelects.forEach(selectId => {
|
||||
const select = document.getElementById(selectId);
|
||||
// Clear existing options except the first one
|
||||
select.innerHTML = '<option value="">Select Time</option>';
|
||||
|
||||
// Add time options in 15-minute intervals
|
||||
for (let hour = 0; hour < 24; hour++) {
|
||||
for (let minute = 0; minute < 60; minute += 15) {
|
||||
const timeString = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`;
|
||||
const option = document.createElement('option');
|
||||
option.value = timeString;
|
||||
option.textContent = timeString;
|
||||
select.appendChild(option);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Notification system
|
||||
function showNotification(message, isError = false) {
|
||||
const notification = document.getElementById('notification');
|
||||
@@ -398,11 +430,43 @@
|
||||
document.getElementById('ac_call').value = ppr.ac_call || '';
|
||||
document.getElementById('captain').value = ppr.captain || '';
|
||||
document.getElementById('in_from').value = ppr.in_from || '';
|
||||
document.getElementById('eta').value = ppr.eta ? new Date(ppr.eta).toISOString().slice(0, 16) : '';
|
||||
|
||||
// Handle ETA date/time separately
|
||||
if (ppr.eta) {
|
||||
let utcDateStr = ppr.eta;
|
||||
if (!utcDateStr.includes('T')) {
|
||||
utcDateStr = utcDateStr.replace(' ', 'T');
|
||||
}
|
||||
if (!utcDateStr.includes('Z')) {
|
||||
utcDateStr += 'Z';
|
||||
}
|
||||
const etaDate = new Date(utcDateStr);
|
||||
const etaDateStr = etaDate.toISOString().split('T')[0];
|
||||
const etaTimeStr = etaDate.toISOString().slice(11, 16);
|
||||
document.getElementById('eta-date').value = etaDateStr;
|
||||
document.getElementById('eta-time').value = etaTimeStr;
|
||||
}
|
||||
|
||||
document.getElementById('pob_in').value = ppr.pob_in || '';
|
||||
document.getElementById('fuel').value = ppr.fuel || '';
|
||||
document.getElementById('out_to').value = ppr.out_to || '';
|
||||
document.getElementById('etd').value = ppr.etd ? new Date(ppr.etd).toISOString().slice(0, 16) : '';
|
||||
|
||||
// Handle ETD date/time separately
|
||||
if (ppr.etd) {
|
||||
let utcDateStr = ppr.etd;
|
||||
if (!utcDateStr.includes('T')) {
|
||||
utcDateStr = utcDateStr.replace(' ', 'T');
|
||||
}
|
||||
if (!utcDateStr.includes('Z')) {
|
||||
utcDateStr += 'Z';
|
||||
}
|
||||
const etdDate = new Date(utcDateStr);
|
||||
const etdDateStr = etdDate.toISOString().split('T')[0];
|
||||
const etdTimeStr = etdDate.toISOString().slice(11, 16);
|
||||
document.getElementById('etd-date').value = etdDateStr;
|
||||
document.getElementById('etd-time').value = etdTimeStr;
|
||||
}
|
||||
|
||||
document.getElementById('pob_out').value = ppr.pob_out || '';
|
||||
document.getElementById('email').value = ppr.email || '';
|
||||
document.getElementById('phone').value = ppr.phone || '';
|
||||
@@ -492,6 +556,7 @@
|
||||
async function handleArrivalAirportLookup(query) {
|
||||
clearTimeout(arrivalAirportLookupTimeout);
|
||||
const resultsDiv = document.getElementById('arrival-airport-lookup-results');
|
||||
const inputField = document.getElementById('in_from');
|
||||
|
||||
if (!query || query.length < 2) {
|
||||
resultsDiv.innerHTML = '';
|
||||
@@ -506,12 +571,31 @@
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
if (data && data.length > 0) {
|
||||
if (data.length === 1) {
|
||||
// Single match - auto-populate the input field with ICAO code
|
||||
const airport = data[0];
|
||||
inputField.value = airport.icao;
|
||||
resultsDiv.innerHTML = `
|
||||
<div class="lookup-match">
|
||||
${airport.icao}/${airport.iata || ''} - ${airport.name}, ${airport.country}
|
||||
</div>
|
||||
`;
|
||||
} else if (data.length <= 10) {
|
||||
// Multiple matches - show as clickable list
|
||||
resultsDiv.innerHTML = `
|
||||
<div class="aircraft-list">
|
||||
${data.map(airport => `
|
||||
<div class="aircraft-option" onclick="selectAirport('in_from', '${airport.icao}')">
|
||||
<div class="aircraft-code">${airport.icao}/${airport.iata || ''}</div>
|
||||
<div class="aircraft-details">${airport.name}, ${airport.country}</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
// Too many matches
|
||||
resultsDiv.innerHTML = '<span class="lookup-no-match">Too many matches, please be more specific</span>';
|
||||
}
|
||||
} else {
|
||||
resultsDiv.innerHTML = '<span class="lookup-no-match">No airport found</span>';
|
||||
}
|
||||
@@ -529,6 +613,7 @@
|
||||
async function handleDepartureAirportLookup(query) {
|
||||
clearTimeout(departureAirportLookupTimeout);
|
||||
const resultsDiv = document.getElementById('departure-airport-lookup-results');
|
||||
const inputField = document.getElementById('out_to');
|
||||
|
||||
if (!query || query.length < 2) {
|
||||
resultsDiv.innerHTML = '';
|
||||
@@ -543,12 +628,31 @@
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
if (data && data.length > 0) {
|
||||
if (data.length === 1) {
|
||||
// Single match - auto-populate the input field with ICAO code
|
||||
const airport = data[0];
|
||||
inputField.value = airport.icao;
|
||||
resultsDiv.innerHTML = `
|
||||
<div class="lookup-match">
|
||||
${airport.icao}/${airport.iata || ''} - ${airport.name}, ${airport.country}
|
||||
</div>
|
||||
`;
|
||||
} else if (data.length <= 10) {
|
||||
// Multiple matches - show as clickable list
|
||||
resultsDiv.innerHTML = `
|
||||
<div class="aircraft-list">
|
||||
${data.map(airport => `
|
||||
<div class="aircraft-option" onclick="selectAirport('out_to', '${airport.icao}')">
|
||||
<div class="aircraft-code">${airport.icao}/${airport.iata || ''}</div>
|
||||
<div class="aircraft-details">${airport.name}, ${airport.country}</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
// Too many matches
|
||||
resultsDiv.innerHTML = '<span class="lookup-no-match">Too many matches, please be more specific</span>';
|
||||
}
|
||||
} else {
|
||||
resultsDiv.innerHTML = '<span class="lookup-no-match">No airport found</span>';
|
||||
}
|
||||
@@ -562,6 +666,28 @@
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function selectAirport(fieldId, icaoCode) {
|
||||
document.getElementById(fieldId).value = icaoCode;
|
||||
// Clear the results
|
||||
const resultsDivId = fieldId === 'in_from' ? 'arrival-airport-lookup-results' : 'departure-airport-lookup-results';
|
||||
document.getElementById(resultsDivId).innerHTML = '';
|
||||
// Remove focus from the field to hide the dropdown
|
||||
document.getElementById(fieldId).blur();
|
||||
}
|
||||
|
||||
// Clear airport lookup results when input loses focus
|
||||
document.getElementById('in_from').addEventListener('blur', function() {
|
||||
setTimeout(() => {
|
||||
document.getElementById('arrival-airport-lookup-results').innerHTML = '';
|
||||
}, 150);
|
||||
});
|
||||
|
||||
document.getElementById('out_to').addEventListener('blur', function() {
|
||||
setTimeout(() => {
|
||||
document.getElementById('departure-airport-lookup-results').innerHTML = '';
|
||||
}, 150);
|
||||
});
|
||||
|
||||
// Form submission (update)
|
||||
document.getElementById('ppr-form').addEventListener('submit', async function(e) {
|
||||
e.preventDefault();
|
||||
@@ -573,9 +699,18 @@
|
||||
if (value.trim() !== '') {
|
||||
if (key === 'pob_in' || key === 'pob_out') {
|
||||
pprData[key] = parseInt(value);
|
||||
} else if (key === 'eta' || key === 'etd') {
|
||||
pprData[key] = new Date(value).toISOString();
|
||||
} else {
|
||||
} else if (key === 'eta-date' && formData.get('eta-time')) {
|
||||
// Combine date and time for ETA
|
||||
const dateStr = formData.get('eta-date');
|
||||
const timeStr = formData.get('eta-time');
|
||||
pprData.eta = new Date(`${dateStr}T${timeStr}`).toISOString();
|
||||
} else if (key === 'etd-date' && formData.get('etd-time')) {
|
||||
// Combine date and time for ETD
|
||||
const dateStr = formData.get('etd-date');
|
||||
const timeStr = formData.get('etd-time');
|
||||
pprData.etd = new Date(`${dateStr}T${timeStr}`).toISOString();
|
||||
} else if (key !== 'eta-time' && key !== 'etd-time') {
|
||||
// Skip the time fields as they're handled above
|
||||
pprData[key] = value;
|
||||
}
|
||||
}
|
||||
@@ -647,6 +782,11 @@
|
||||
|
||||
// Load data on page load
|
||||
loadPPRData();
|
||||
|
||||
// Initialize the page when DOM is loaded
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
initializeTimeDropdowns();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
119
web/ppr.html
119
web/ppr.html
@@ -289,7 +289,12 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="eta" class="required">Estimated Time of Arrival (Local Time)</label>
|
||||
<input type="datetime-local" id="eta" name="eta" required>
|
||||
<div style="display: flex; gap: 0.5rem;">
|
||||
<input type="date" id="eta-date" name="eta-date" required style="flex: 1;">
|
||||
<select id="eta-time" name="eta-time" required style="flex: 1;">
|
||||
<option value="">Select Time</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pob_in" class="required">Persons on Board (Arrival)</label>
|
||||
@@ -311,7 +316,12 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="etd">Estimated Time of Departure (Local Time)</label>
|
||||
<input type="datetime-local" id="etd" name="etd">
|
||||
<div style="display: flex; gap: 0.5rem;">
|
||||
<input type="date" id="etd-date" name="etd-date" style="flex: 1;">
|
||||
<select id="etd-time" name="etd-time" style="flex: 1;">
|
||||
<option value="">Select Time</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="pob_out">Persons on Board (Departure)</label>
|
||||
@@ -354,6 +364,28 @@
|
||||
<div id="notification" class="notification"></div>
|
||||
|
||||
<script>
|
||||
// Initialize time dropdowns
|
||||
function initializeTimeDropdowns() {
|
||||
const timeSelects = ['eta-time', 'etd-time'];
|
||||
|
||||
timeSelects.forEach(selectId => {
|
||||
const select = document.getElementById(selectId);
|
||||
// Clear existing options except the first one
|
||||
select.innerHTML = '<option value="">Select Time</option>';
|
||||
|
||||
// Add time options in 15-minute intervals
|
||||
for (let hour = 0; hour < 24; hour++) {
|
||||
for (let minute = 0; minute < 60; minute += 15) {
|
||||
const timeString = `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`;
|
||||
const option = document.createElement('option');
|
||||
option.value = timeString;
|
||||
option.textContent = timeString;
|
||||
select.appendChild(option);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Notification system
|
||||
function showNotification(message, isError = false) {
|
||||
const notification = document.getElementById('notification');
|
||||
@@ -455,6 +487,7 @@
|
||||
async function handleArrivalAirportLookup(query) {
|
||||
clearTimeout(arrivalAirportLookupTimeout);
|
||||
const resultsDiv = document.getElementById('arrival-airport-lookup-results');
|
||||
const inputField = document.getElementById('in_from');
|
||||
|
||||
if (!query || query.length < 2) {
|
||||
resultsDiv.innerHTML = '';
|
||||
@@ -469,12 +502,31 @@
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
if (data && data.length > 0) {
|
||||
if (data.length === 1) {
|
||||
// Single match - auto-populate the input field with ICAO code
|
||||
const airport = data[0];
|
||||
inputField.value = airport.icao;
|
||||
resultsDiv.innerHTML = `
|
||||
<div class="lookup-match">
|
||||
${airport.icao}/${airport.iata || ''} - ${airport.name}, ${airport.country}
|
||||
</div>
|
||||
`;
|
||||
} else if (data.length <= 10) {
|
||||
// Multiple matches - show as clickable list
|
||||
resultsDiv.innerHTML = `
|
||||
<div class="aircraft-list">
|
||||
${data.map(airport => `
|
||||
<div class="aircraft-option" onclick="selectAirport('in_from', '${airport.icao}')">
|
||||
<div class="aircraft-code">${airport.icao}/${airport.iata || ''}</div>
|
||||
<div class="aircraft-details">${airport.name}, ${airport.country}</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
// Too many matches
|
||||
resultsDiv.innerHTML = '<span class="lookup-no-match">Too many matches, please be more specific</span>';
|
||||
}
|
||||
} else {
|
||||
resultsDiv.innerHTML = '<span class="lookup-no-match">No airport found</span>';
|
||||
}
|
||||
@@ -492,6 +544,7 @@
|
||||
async function handleDepartureAirportLookup(query) {
|
||||
clearTimeout(departureAirportLookupTimeout);
|
||||
const resultsDiv = document.getElementById('departure-airport-lookup-results');
|
||||
const inputField = document.getElementById('out_to');
|
||||
|
||||
if (!query || query.length < 2) {
|
||||
resultsDiv.innerHTML = '';
|
||||
@@ -506,12 +559,31 @@
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
if (data && data.length > 0) {
|
||||
if (data.length === 1) {
|
||||
// Single match - auto-populate the input field with ICAO code
|
||||
const airport = data[0];
|
||||
inputField.value = airport.icao;
|
||||
resultsDiv.innerHTML = `
|
||||
<div class="lookup-match">
|
||||
${airport.icao}/${airport.iata || ''} - ${airport.name}, ${airport.country}
|
||||
</div>
|
||||
`;
|
||||
} else if (data.length <= 10) {
|
||||
// Multiple matches - show as clickable list
|
||||
resultsDiv.innerHTML = `
|
||||
<div class="aircraft-list">
|
||||
${data.map(airport => `
|
||||
<div class="aircraft-option" onclick="selectAirport('out_to', '${airport.icao}')">
|
||||
<div class="aircraft-code">${airport.icao}/${airport.iata || ''}</div>
|
||||
<div class="aircraft-details">${airport.name}, ${airport.country}</div>
|
||||
</div>
|
||||
`).join('')}
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
// Too many matches
|
||||
resultsDiv.innerHTML = '<span class="lookup-no-match">Too many matches, please be more specific</span>';
|
||||
}
|
||||
} else {
|
||||
resultsDiv.innerHTML = '<span class="lookup-no-match">No airport found</span>';
|
||||
}
|
||||
@@ -525,6 +597,28 @@
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function selectAirport(fieldId, icaoCode) {
|
||||
document.getElementById(fieldId).value = icaoCode;
|
||||
// Clear the results
|
||||
const resultsDivId = fieldId === 'in_from' ? 'arrival-airport-lookup-results' : 'departure-airport-lookup-results';
|
||||
document.getElementById(resultsDivId).innerHTML = '';
|
||||
// Remove focus from the field to hide the dropdown
|
||||
document.getElementById(fieldId).blur();
|
||||
}
|
||||
|
||||
// Clear airport lookup results when input loses focus
|
||||
document.getElementById('in_from').addEventListener('blur', function() {
|
||||
setTimeout(() => {
|
||||
document.getElementById('arrival-airport-lookup-results').innerHTML = '';
|
||||
}, 150);
|
||||
});
|
||||
|
||||
document.getElementById('out_to').addEventListener('blur', function() {
|
||||
setTimeout(() => {
|
||||
document.getElementById('departure-airport-lookup-results').innerHTML = '';
|
||||
}, 150);
|
||||
});
|
||||
|
||||
// Form submission
|
||||
document.getElementById('ppr-form').addEventListener('submit', async function(e) {
|
||||
e.preventDefault();
|
||||
@@ -536,10 +630,18 @@
|
||||
if (value.trim() !== '') {
|
||||
if (key === 'pob_in' || key === 'pob_out') {
|
||||
pprData[key] = parseInt(value);
|
||||
} else if (key === 'eta' || key === 'etd') {
|
||||
// Convert datetime-local to ISO string
|
||||
pprData[key] = new Date(value).toISOString();
|
||||
} else {
|
||||
} else if (key === 'eta-date' && formData.get('eta-time')) {
|
||||
// Combine date and time for ETA
|
||||
const dateStr = formData.get('eta-date');
|
||||
const timeStr = formData.get('eta-time');
|
||||
pprData.eta = new Date(`${dateStr}T${timeStr}`).toISOString();
|
||||
} else if (key === 'etd-date' && formData.get('etd-time')) {
|
||||
// Combine date and time for ETD
|
||||
const dateStr = formData.get('etd-date');
|
||||
const timeStr = formData.get('etd-time');
|
||||
pprData.etd = new Date(`${dateStr}T${timeStr}`).toISOString();
|
||||
} else if (key !== 'eta-time' && key !== 'etd-time') {
|
||||
// Skip the time fields as they're handled above
|
||||
pprData[key] = value;
|
||||
}
|
||||
}
|
||||
@@ -582,6 +684,11 @@
|
||||
document.getElementById('submit-btn').textContent = 'Submit PPR Request';
|
||||
}
|
||||
});
|
||||
|
||||
// Initialize the page when DOM is loaded
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
initializeTimeDropdowns();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user