Add all routes as selection

This commit is contained in:
Florian Zumpe
2026-06-16 15:14:46 +02:00
parent b6f1a0f825
commit 278813fba6
4 changed files with 180 additions and 16 deletions
+87 -14
View File
@@ -30,14 +30,30 @@
else if (previous !== pageSelector) history.pushState(historyState, '', pageSelector);
}
function renderRoutes() {
const list = $('#route-list').empty();
if (!state.routes.length) {
list.append('<li class="empty-list">Keine Route in der Nähe gefunden.</li>');
function normalizeSearch(value) {
return String(value ?? '')
.normalize('NFKD')
.replace(/[\u0300-\u036f]/g, '')
.toLocaleLowerCase('de');
}
function routeMatchesSearch(route, searchTerm) {
if (!searchTerm) return true;
return normalizeSearch([
route.name,
route.schoolName,
route.description
].filter(Boolean).join(' ')).includes(searchTerm);
}
function renderRouteItems(listSelector, routes, emptyText) {
const list = $(listSelector).empty();
if (!routes.length) {
list.append(`<li class="empty-list">${escapeHtml(emptyText)}</li>`);
return;
}
state.routes.forEach(route => {
routes.forEach(route => {
const proximity = route.proximityM == null
? ''
: `<span class="route-distance">${escapeHtml(ns.Distance.format(route.proximityM))} entfernt</span>`;
@@ -53,6 +69,54 @@
});
}
function renderRoutes() {
const radiusM = ns.Config.routeRadiusKm * 1000;
const nearbyRoutes = state.position
? state.routes
.filter(route => route.proximityM != null && route.proximityM <= radiusM)
.sort((a, b) => a.proximityM - b.proximityM)
: [];
const searchTerm = normalizeSearch($('#route-search').val());
const allRoutes = state.routes
.filter(route => routeMatchesSearch(route, searchTerm))
.slice()
.sort((a, b) => a.name.localeCompare(b.name, 'de'));
const nearbyEmptyText = state.position
? `Keine Route im Umkreis von ${ns.Config.routeRadiusKm} km gefunden. Wähle unten eine beliebige Route aus.`
: 'Für Empfehlungen in der Nähe ist ein Standort erforderlich. Alle Routen bleiben unten auswählbar.';
renderRouteItems('#nearby-route-list', nearbyRoutes, nearbyEmptyText);
renderRouteItems('#all-route-list', allRoutes,
searchTerm ? 'Keine Route entspricht dem Suchbegriff.' : 'Es sind noch keine Routen vorhanden.');
$('#all-routes-summary').text(
searchTerm
? `${allRoutes.length} von ${state.routes.length} Routen gefunden.`
: `${state.routes.length} Routen verfügbar.`
);
}
function initializeRouteSearch() {
const input = $('#route-search');
input.autocomplete({
minLength: 0,
source(request, response) {
const term = normalizeSearch(request.term);
response(state.routes
.filter(route => routeMatchesSearch(route, term))
.slice(0, 12)
.map(route => ({ label: route.name, value: route.name })));
},
select(event, ui) {
input.val(ui.item.value);
renderRoutes();
return false;
}
});
}
function renderRoute(route) {
state.route = route;
state.triggered.clear();
@@ -121,6 +185,12 @@
}
function bindEvents() {
$(document).on('input', '#route-search', renderRoutes);
$(document).on('click', '#clear-route-search', function () {
$('#route-search').val('').trigger('input').trigger('focus');
});
$(document).on('click', '[data-route-id]', async function () {
const button = $(this);
button.prop('disabled', true);
@@ -178,19 +248,22 @@
try {
const position = await ns.Geo.current();
state.position = position;
$('#location-hint').text(`Standort ermittelt (Genauigkeit ${Math.round(position.accuracy)} m).`);
state.routes = state.routes
.map(route => ({
...route,
proximityM: route.start ? ns.Distance.meters(position, route.start) : null
}))
.filter(route => route.proximityM == null || route.proximityM <= ns.Config.routeRadiusKm * 1000)
.sort((a, b) => (a.proximityM ?? Number.MAX_VALUE) - (b.proximityM ?? Number.MAX_VALUE));
$('#location-hint').text(
`Standort ermittelt (Genauigkeit ${Math.round(position.accuracy)} m). ` +
`Nahe Routen werden bis ${ns.Config.routeRadiusKm} km empfohlen.`
);
state.routes = state.routes.map(route => ({
...route,
proximityM: route.start ? ns.Distance.meters(position, route.start) : null
}));
} catch (error) {
$('#location-hint').text(`Standort nicht verfügbar: ${error.message}. Es werden alle Routen angezeigt.`);
$('#location-hint').text(
`Standort nicht verfügbar: ${error.message}. Alle Routen können weiterhin ausgewählt werden.`
);
}
context.markStep('location', 'done');
initializeRouteSearch();
renderRoutes();
updateTrackingButton();
}
+1
View File
@@ -45,6 +45,7 @@
$('#bootstrap-retry').button({ icon: 'ui-icon-refresh' });
$('.back-button').button({ icon: 'ui-icon-caret-1-w' });
$('#start-tracking').button({ icon: 'ui-icon-pin-s' });
$('#clear-route-search').button({ icon: 'ui-icon-close', showLabel: false });
$('#slide-prev').button({ icon: 'ui-icon-caret-1-w', showLabel: false });
$('#slide-next').button({ icon: 'ui-icon-caret-1-e', showLabel: false });
$('#slide-controls').controlgroup();