only render Elements in renderData
This commit is contained in:
parent
dc84436346
commit
7673265167
1 changed files with 167 additions and 141 deletions
308
elevators.js
308
elevators.js
|
@ -1,3 +1,11 @@
|
||||||
|
const internalData = {
|
||||||
|
lastUpdate: 0,
|
||||||
|
stations: [],
|
||||||
|
};
|
||||||
|
let geolocationPermission = false;
|
||||||
|
let geolocation = [null, null];
|
||||||
|
|
||||||
|
|
||||||
Object.defineProperty(String.prototype, 'capitalize', {
|
Object.defineProperty(String.prototype, 'capitalize', {
|
||||||
value: function () {
|
value: function () {
|
||||||
return this.charAt(0).toUpperCase() + this.toLowerCase().slice(1);
|
return this.charAt(0).toUpperCase() + this.toLowerCase().slice(1);
|
||||||
|
@ -9,7 +17,90 @@ async function loadElevators() {
|
||||||
const res = await fetch('https://www.hvv.de/elevators', {referrer: ""});
|
const res = await fetch('https://www.hvv.de/elevators', {referrer: ""});
|
||||||
|
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
localStorage.setItem("elevator_data", JSON.stringify(data));
|
|
||||||
|
const stations = data['stations'];
|
||||||
|
stations.sort(sortStations)
|
||||||
|
internalData.lastUpdate = new Date(data['lastUpdate']);
|
||||||
|
|
||||||
|
let stationIndex = 0;
|
||||||
|
|
||||||
|
for (const station of stations) {
|
||||||
|
const stationName = station['mainSubStation']['stationName'];
|
||||||
|
const lines = new Set();
|
||||||
|
const elevators = [];
|
||||||
|
for (const elevatorKey of Object.keys(station.elevators)) {
|
||||||
|
const elevatorApi = station.elevators[elevatorKey];
|
||||||
|
const elevatorLines = [];
|
||||||
|
for (let line of elevatorApi.lines) {
|
||||||
|
line = line.replace(/[()]/g, "");
|
||||||
|
lines.add(line);
|
||||||
|
elevatorLines.push({
|
||||||
|
line: line,
|
||||||
|
type: getType(line),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to detect levels from description
|
||||||
|
let levels = [];
|
||||||
|
if (elevatorApi.description.search('<->') >= 0) {
|
||||||
|
levels = elevatorApi.description.split('<->').map(level => level.trim());
|
||||||
|
} else if (elevatorApi.description.search('<>') >= 0) {
|
||||||
|
levels = elevatorApi.description.split('<>').map(level => level.trim());
|
||||||
|
} else if (elevatorApi.description.search('/ ') >= 0) {
|
||||||
|
levels = elevatorApi.description.split('/ ').map(level => level.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
const elevator = {
|
||||||
|
working: elevatorApi['state'] === 1,
|
||||||
|
stateUnavailable: elevatorApi['state'] === -1,
|
||||||
|
dimensions: {
|
||||||
|
width: elevatorApi['cabinWidth'],
|
||||||
|
length: elevatorApi['cabinLength'],
|
||||||
|
door: elevatorApi['doorWidth'],
|
||||||
|
},
|
||||||
|
description: elevatorApi['description'],
|
||||||
|
label: elevatorApi['label'],
|
||||||
|
type: elevatorApi['type'].replace('_', ' ').capitalize(),
|
||||||
|
braille: elevatorApi['tasterType'] === 'UNBEKANNT' ? -1 : elevatorApi['tasterType'] === 'KOMBI' || elevatorApi['tasterType'] === 'BRAILLE',
|
||||||
|
speaker: elevatorApi['tasterType'] === 'UNBEKANNT' ? -1 : elevatorApi['tasterType'] === 'KOMBI',
|
||||||
|
lines: elevatorLines,
|
||||||
|
levels: levels,
|
||||||
|
instCause: elevatorApi['instCause'],
|
||||||
|
osmNodeId: elevatorApi['osmId'],
|
||||||
|
}
|
||||||
|
|
||||||
|
elevators.push(elevator);
|
||||||
|
}
|
||||||
|
|
||||||
|
let stationState = {
|
||||||
|
unavailable: 0,
|
||||||
|
working: 0,
|
||||||
|
outOfOrder: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const elevator of elevators) {
|
||||||
|
if (elevator.stateUnavailable) {
|
||||||
|
stationState.unavailable++;
|
||||||
|
} else if (elevator.working) {
|
||||||
|
stationState.working++;
|
||||||
|
} else {
|
||||||
|
stationState.outOfOrder++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const stationLines = Array.from(lines);
|
||||||
|
const stationTypes = Array.from(getTypes(stationLines));
|
||||||
|
|
||||||
|
internalData.stations[stationIndex++] = {
|
||||||
|
name: stationName,
|
||||||
|
state: stationState,
|
||||||
|
lines: stationLines,
|
||||||
|
types: stationTypes,
|
||||||
|
elevators: elevators,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem("internal_data", JSON.stringify(internalData));
|
||||||
}
|
}
|
||||||
|
|
||||||
const dateTimeStyle = new Intl.DateTimeFormat('de-DE', {
|
const dateTimeStyle = new Intl.DateTimeFormat('de-DE', {
|
||||||
|
@ -18,19 +109,11 @@ const dateTimeStyle = new Intl.DateTimeFormat('de-DE', {
|
||||||
timeZone: 'Europe/Berlin',
|
timeZone: 'Europe/Berlin',
|
||||||
})
|
})
|
||||||
|
|
||||||
const internalData = []
|
|
||||||
let geolocationPermission = false;
|
|
||||||
let geolocation = [null, null];
|
|
||||||
|
|
||||||
async function loadOsmData() {
|
async function loadOsmData() {
|
||||||
const elevatorNodes = document.querySelectorAll('.elevator');
|
|
||||||
const nodeIdList = [];
|
const nodeIdList = [];
|
||||||
for (const elevator of elevatorNodes) {
|
for (const station of internalData.stations) {
|
||||||
const osmContainer = elevator.querySelector('.osm');
|
for (const elevator of station.elevators) {
|
||||||
const nodeId = osmContainer.dataset.nodeid;
|
nodeIdList.push(elevator.osmNodeId)
|
||||||
if (nodeId > 0) {
|
|
||||||
elevator.querySelector('.osm').insertAdjacentHTML("beforeend", '<dl class="osmTags">loading...</dl>');
|
|
||||||
nodeIdList.push(nodeId)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,44 +122,7 @@ async function loadOsmData() {
|
||||||
|
|
||||||
if (!osmJson.hasOwnProperty('elements')) return;
|
if (!osmJson.hasOwnProperty('elements')) return;
|
||||||
|
|
||||||
for (const elevator of elevatorNodes) {
|
localStorage.setItem("osm_data", JSON.stringify(osmJson));
|
||||||
const tagContainer = elevator.querySelector('.osmTags');
|
|
||||||
const nodeId = elevator.querySelector('.osm').dataset.nodeid;
|
|
||||||
|
|
||||||
const nodes = osmJson.elements.filter(node => node.id === parseInt(nodeId))
|
|
||||||
if (!nodes.length) {
|
|
||||||
tagContainer.innerHTML = 'keine Daten';
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const nodeInfo = nodes[0];
|
|
||||||
|
|
||||||
if (!nodeInfo.hasOwnProperty('tags')) {
|
|
||||||
tagContainer.innerHTML = 'keine Daten';
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const tags = nodeInfo['tags'];
|
|
||||||
|
|
||||||
if (tags['highway'] === 'elevator') {
|
|
||||||
let osmTemplate = '';
|
|
||||||
osmTemplate += `<div><dt><span data-icon="location" class="size-l"></span>Link zur Karte</dt><dd><a href="https://www.openstreetmap.org/node/${nodeId}" target="_blank">
|
|
||||||
Auf Karte anzeigen
|
|
||||||
</a></dd></div>`;
|
|
||||||
if (tags.hasOwnProperty('description')) {
|
|
||||||
osmTemplate += `<div><dt><span data-icon="info" class="size-l"></span>Beschreibung</dt><dd>${tags['description']}</dd></div>`;
|
|
||||||
}
|
|
||||||
if (tags.hasOwnProperty('level')) {
|
|
||||||
osmTemplate += `<div><dt><span data-icon="up-down" class="size-l"></span>Ebenen</dt><dd>${tags['level'].split(';').sort().join(', ')}</dd></div>`;
|
|
||||||
}
|
|
||||||
if (tags.hasOwnProperty('wheelchair')) {
|
|
||||||
osmTemplate += `<div><dt><span data-icon="wheelchair" class="size-l"></span>Rollstühle</dt><dd>${tags['wheelchair'] === 'yes' ? 'Ja' : 'Nein'}</dd></div>`;
|
|
||||||
}
|
|
||||||
if (tags.hasOwnProperty('bicycle')) {
|
|
||||||
osmTemplate += `<div><dt><span data-icon="bicycle" class="size-l"></span>Fahrräder</dt><dd>${tags['bicycle'] === 'yes' ? 'Ja' : 'Nein'}</dd></div>`;
|
|
||||||
}
|
|
||||||
tagContainer.innerHTML = ''; // clear loading state
|
|
||||||
tagContainer.insertAdjacentHTML('beforeend', osmTemplate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function distance([lat1, lon1], [lat2, lon2]) {
|
function distance([lat1, lon1], [lat2, lon2]) {
|
||||||
|
@ -171,85 +217,34 @@ function getTypes(lines) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderData() {
|
function renderData() {
|
||||||
const data = JSON.parse(localStorage.getItem("elevator_data"));
|
const ls = JSON.parse(localStorage.getItem("internal_data"));
|
||||||
|
if (!ls) return;
|
||||||
|
internalData.lastUpdate = ls['lastUpdate'];
|
||||||
|
internalData.stations = ls['stations'];
|
||||||
|
const osmData = JSON.parse(localStorage.getItem("osm_data"));
|
||||||
|
|
||||||
if (!data) {
|
if (!internalData || !internalData.stations.length) {
|
||||||
console.error('No Data available!')
|
console.error('No Data available!')
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let stations = data.stations;
|
|
||||||
stations.sort(sortStations)
|
|
||||||
const date = new Date(data.lastUpdate);
|
|
||||||
|
|
||||||
document.querySelector('#loadElevators').innerHTML = 'Daten aktualisieren';
|
document.querySelector('#loadElevators').innerHTML = 'Daten aktualisieren';
|
||||||
const listContainer = document.querySelector('#stationList');
|
|
||||||
const dateContainer = document.querySelector('#lastUpdated');
|
const dateContainer = document.querySelector('#lastUpdated');
|
||||||
|
dateContainer.innerHTML = dateTimeStyle.format(new Date(internalData.lastUpdate));
|
||||||
|
|
||||||
dateContainer.innerHTML = dateTimeStyle.format(date);
|
const listContainer = document.querySelector('#stationList');
|
||||||
|
|
||||||
let stationIndex = 0;
|
|
||||||
|
|
||||||
//clear list before update
|
//clear list before update
|
||||||
listContainer.innerHTML = '';
|
listContainer.innerHTML = '';
|
||||||
for (const station of stations) {
|
|
||||||
const stationName = station.mainSubStation.stationName;
|
|
||||||
const lines = new Set();
|
|
||||||
const elevators = [];
|
|
||||||
for (const elevatorKey of Object.keys(station.elevators)) {
|
|
||||||
const elevatorApi = station.elevators[elevatorKey];
|
|
||||||
const elevatorLines = [];
|
|
||||||
for (let line of elevatorApi.lines) {
|
|
||||||
line = line.replace(/[\(\)]/g, "");
|
|
||||||
lines.add(line);
|
|
||||||
elevatorLines.push({
|
|
||||||
line: line,
|
|
||||||
type: getType(line),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to detect levels from description
|
const stations = internalData['stations'];
|
||||||
let levels = [];
|
|
||||||
if (elevatorApi.description.search('<->') >= 0) {
|
|
||||||
levels = elevatorApi.description.split('<->').map(level => level.trim());
|
|
||||||
} else if (elevatorApi.description.search('<>') >= 0) {
|
|
||||||
levels = elevatorApi.description.split('<>').map(level => level.trim());
|
|
||||||
} else if (elevatorApi.description.search('/ ') >= 0) {
|
|
||||||
levels = elevatorApi.description.split('/ ').map(level => level.trim());
|
|
||||||
}
|
|
||||||
|
|
||||||
const elevator = {
|
for (const stationIndex in stations) {
|
||||||
working: elevatorApi['state'] === 1,
|
const station = stations[stationIndex];
|
||||||
stateUnavailable: elevatorApi['state'] === -1,
|
|
||||||
dimensions: {
|
|
||||||
width: elevatorApi['cabinWidth'],
|
|
||||||
length: elevatorApi['cabinLength'],
|
|
||||||
door: elevatorApi['doorWidth'],
|
|
||||||
},
|
|
||||||
description: elevatorApi['description'],
|
|
||||||
label: elevatorApi['label'],
|
|
||||||
type: elevatorApi['type'].replace('_', ' ').capitalize(),
|
|
||||||
braille: elevatorApi['tasterType'] === 'UNBEKANNT' ? -1 : elevatorApi['tasterType'] === 'KOMBI' || elevatorApi['tasterType'] === 'BRAILLE',
|
|
||||||
speaker: elevatorApi['tasterType'] === 'UNBEKANNT' ? -1 : elevatorApi['tasterType'] === 'KOMBI',
|
|
||||||
lines: elevatorLines,
|
|
||||||
levels: levels,
|
|
||||||
instCause: elevatorApi['instCause'],
|
|
||||||
osmNodeId: elevatorApi['osmId'],
|
|
||||||
}
|
|
||||||
|
|
||||||
elevators.push(elevator);
|
|
||||||
}
|
|
||||||
|
|
||||||
const stationTypes = getTypes(Array.from(lines));
|
|
||||||
|
|
||||||
let elevatorsTemplate = '';
|
let elevatorsTemplate = '';
|
||||||
let previewTemplate = '';
|
let previewTemplate = '';
|
||||||
let stationState = {
|
|
||||||
unavailable: 0,
|
for (const elevator of station.elevators) {
|
||||||
working: 0,
|
|
||||||
outOfOrder: 0,
|
|
||||||
}
|
|
||||||
for (const elevator of elevators) {
|
|
||||||
let linesTemplate = '<div class="lineList">Linien: ';
|
let linesTemplate = '<div class="lineList">Linien: ';
|
||||||
for (const line of elevator.lines) {
|
for (const line of elevator.lines) {
|
||||||
linesTemplate += `<span data-type="${line.type}" data-line="${line.line}" class="lineChip">${line.line}</span>`;
|
linesTemplate += `<span data-type="${line.type}" data-line="${line.line}" class="lineChip">${line.line}</span>`;
|
||||||
|
@ -262,16 +257,45 @@ function renderData() {
|
||||||
}
|
}
|
||||||
levelsTemplate += '</ol>';
|
levelsTemplate += '</ol>';
|
||||||
|
|
||||||
|
let osmTemplate = '';
|
||||||
|
if (osmData) {
|
||||||
|
const nodes = osmData.elements.filter(node => node.id === elevator.osmNodeId)
|
||||||
|
if (nodes.length) {
|
||||||
|
const nodeInfo = nodes[0];
|
||||||
|
if (nodeInfo.hasOwnProperty('tags')) {
|
||||||
|
const tags = nodeInfo['tags'];
|
||||||
|
if (tags['highway'] === 'elevator') {
|
||||||
|
osmTemplate = '<dl>';
|
||||||
|
osmTemplate += `<div><dt><span data-icon="location" class="size-l"></span>Link zur Karte</dt><dd><a href="https://www.openstreetmap.org/node/${elevator.osmNodeId}" target="_blank">
|
||||||
|
Auf Karte anzeigen
|
||||||
|
</a></dd></div>`;
|
||||||
|
if (tags.hasOwnProperty('description')) {
|
||||||
|
osmTemplate += `<div><dt><span data-icon="info" class="size-l"></span>Beschreibung</dt><dd>${tags['description']}</dd></div>`;
|
||||||
|
}
|
||||||
|
if (tags.hasOwnProperty('level')) {
|
||||||
|
osmTemplate += `<div><dt><span data-icon="up-down" class="size-l"></span>Ebenen</dt><dd>${tags['level'].split(';').sort().join(', ')}</dd></div>`;
|
||||||
|
}
|
||||||
|
if (tags.hasOwnProperty('wheelchair')) {
|
||||||
|
osmTemplate += `<div><dt><span data-icon="wheelchair" class="size-l"></span>Rollstühle</dt><dd>${tags['wheelchair'] === 'yes' ? 'Ja' : 'Nein'}</dd></div>`;
|
||||||
|
}
|
||||||
|
if (tags.hasOwnProperty('bicycle')) {
|
||||||
|
osmTemplate += `<div><dt><span data-icon="bicycle" class="size-l"></span>Fahrräder</dt><dd>${tags['bicycle'] === 'yes' ? 'Ja' : 'Nein'}</dd></div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
osmTemplate += '<dl>';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
osmTemplate = 'keine Daten';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
osmTemplate = 'keine Daten';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
previewTemplate += `<span data-icon="${elevator.working || elevator.stateUnavailable ? 'elevator' : 'elevator-slash'}"
|
previewTemplate += `<span data-icon="${elevator.working || elevator.stateUnavailable ? 'elevator' : 'elevator-slash'}"
|
||||||
class="size-l ${elevator.working ? 'text-green' : elevator.stateUnavailable ? 'text-orange' : 'text-red'}"></span>`
|
class="size-l ${elevator.working ? 'text-green' : elevator.stateUnavailable ? 'text-orange' : 'text-red'}"></span>`
|
||||||
|
|
||||||
if (elevator.stateUnavailable) {
|
|
||||||
stationState.unavailable++;
|
|
||||||
} else if (elevator.working) {
|
|
||||||
stationState.working++;
|
|
||||||
} else {
|
|
||||||
stationState.outOfOrder++;
|
|
||||||
}
|
|
||||||
|
|
||||||
elevatorsTemplate += `<li class="elevator">
|
elevatorsTemplate += `<li class="elevator">
|
||||||
<span data-icon="${elevator.working || elevator.stateUnavailable ? 'elevator' : 'elevator-slash'}"
|
<span data-icon="${elevator.working || elevator.stateUnavailable ? 'elevator' : 'elevator-slash'}"
|
||||||
|
@ -311,6 +335,7 @@ function renderData() {
|
||||||
${elevator.lines.length ? `${linesTemplate}` : ''}
|
${elevator.lines.length ? `${linesTemplate}` : ''}
|
||||||
<div class="osm" data-nodeid="${elevator.osmNodeId}">
|
<div class="osm" data-nodeid="${elevator.osmNodeId}">
|
||||||
<h4>Daten von OpenStreetMap</h4>
|
<h4>Daten von OpenStreetMap</h4>
|
||||||
|
${osmTemplate}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>`;
|
</li>`;
|
||||||
|
@ -319,14 +344,14 @@ function renderData() {
|
||||||
const template = `<li class="station" id="station_${stationIndex}">
|
const template = `<li class="station" id="station_${stationIndex}">
|
||||||
<div class="stationSummary">
|
<div class="stationSummary">
|
||||||
<div class="typeList">
|
<div class="typeList">
|
||||||
${Array.from(stationTypes).sort().map(t => `<span class="typeChip" data-type="${t}">${t}</span>`).join('')}
|
${station.types.sort().map(t => `<span class="typeChip" data-type="${t}">${t}</span>`).join('')}
|
||||||
</div>
|
</div>
|
||||||
<div class="stationTitle">
|
<div class="stationTitle">
|
||||||
<h3>${stationName}</h3>
|
<h3>${station.name}</h3>
|
||||||
<div class="elevator-preview" role="img"
|
<div class="elevator-preview" role="img"
|
||||||
aria-label="${stationState.working ? `${stationState.working} ${stationState.working > 1 ? 'Aufzüge sind' : 'Aufzug ist'} funktionstüchtig.` : ''}
|
aria-label="${station.state.working ? `${station.state.working} ${station.state.working > 1 ? 'Aufzüge sind' : 'Aufzug ist'} funktionstüchtig.` : ''}
|
||||||
${stationState.outOfOrder ? `${stationState.outOfOrder} ${stationState.outOfOrder > 1 ? 'Aufzüge sind' : 'Aufzug ist'} außer Betrieb.` : ''}
|
${station.state.outOfOrder ? `${station.state.outOfOrder} ${station.state.outOfOrder > 1 ? 'Aufzüge sind' : 'Aufzug ist'} außer Betrieb.` : ''}
|
||||||
${stationState.unavailable ? `Bei ${stationState.unavailable} ${stationState.unavailable > 1 ? 'Aufzügen' : 'Aufzug'} ist der Funktionsstatus unbekannt.` : ''}">
|
${station.state.unavailable ? `Bei ${station.state.unavailable} ${station.state.unavailable > 1 ? 'Aufzügen' : 'Aufzug'} ist der Funktionsstatus unbekannt.` : ''}">
|
||||||
${previewTemplate}
|
${previewTemplate}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -349,38 +374,39 @@ ${stationState.unavailable ? `Bei ${stationState.unavailable} ${stationState.una
|
||||||
// .addEventListener('click', () => toggleElevatorList(stationId))
|
// .addEventListener('click', () => toggleElevatorList(stationId))
|
||||||
// }());
|
// }());
|
||||||
|
|
||||||
|
|
||||||
internalData[stationIndex++] = {
|
|
||||||
name: stationName,
|
|
||||||
state: stationState,
|
|
||||||
elevators: elevators,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelector('#loadElevators')
|
document.querySelector('#loadElevators')
|
||||||
.addEventListener('click', (e) => {
|
.addEventListener('click', (e) => {
|
||||||
loadElevators().then(() => renderData());
|
loadElevators().then(() => {
|
||||||
|
renderData();
|
||||||
|
filterData();
|
||||||
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
document.querySelector('#loadOSM')
|
document.querySelector('#loadOSM')
|
||||||
.addEventListener('click', (e) => {
|
.addEventListener('click', (e) => {
|
||||||
loadOsmData();
|
loadOsmData().then(() => {
|
||||||
|
renderData();
|
||||||
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
renderData();
|
renderData();
|
||||||
|
|
||||||
|
|
||||||
function filterData(searchString) {
|
function filterData() {
|
||||||
for (const stationIndex in internalData) {
|
const searchString = document.querySelector('#searchStation').value;
|
||||||
const matches = internalData[stationIndex].name.toLowerCase().search(searchString.toLowerCase()) >= 0;
|
if (internalData) {
|
||||||
document.querySelector(`#station_${stationIndex}`).classList.toggle('hidden', !matches);
|
for (const stationIndex in internalData.stations) {
|
||||||
|
const matches = internalData.stations[stationIndex].name.toLowerCase().search(searchString.toLowerCase()) >= 0;
|
||||||
|
document.querySelector(`#station_${stationIndex}`).classList.toggle('hidden', !matches);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.querySelector('#searchStation').addEventListener('input', (e) => {
|
document.querySelector('#searchStation').addEventListener('input', (e) => {
|
||||||
filterData(e.target.value);
|
filterData();
|
||||||
})
|
})
|
||||||
|
|
||||||
filterData(document.querySelector('#searchStation').value)
|
filterData()
|
Loading…
Add table
Add a link
Reference in a new issue