improved WebUI
This commit is contained in:
@@ -84,7 +84,6 @@ function onMessage(event) {
|
||||
|
||||
processDTCNotifications(dtcArray);
|
||||
fillDTCTable(dtcArray);
|
||||
|
||||
} else if (data.startsWith("MAPPING_STATUS:")) {
|
||||
const data_sliced = data.slice(15);
|
||||
statusMapping = createMapping(data_sliced);
|
||||
@@ -100,19 +99,15 @@ function onMessage(event) {
|
||||
const data_sliced = data.slice(7);
|
||||
const result = processDataString(data_sliced, staticMapping);
|
||||
fillValuesToHTML(result);
|
||||
console.log(result);
|
||||
overlay.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
function createMapping(mappingString) {
|
||||
const mappingArray = mappingString.split(";");
|
||||
const mapping = [];
|
||||
|
||||
mappingArray.forEach((variable) => {
|
||||
if (variable !== null) mapping.push(variable.trim());
|
||||
});
|
||||
return mapping;
|
||||
return mappingString
|
||||
.split(";")
|
||||
.map((s) => s.trim())
|
||||
.filter((s) => s !== "");
|
||||
}
|
||||
|
||||
function processDataString(dataString, mapping) {
|
||||
@@ -157,43 +152,136 @@ function do_resize(textbox) {
|
||||
else textbox.rows = rows;
|
||||
}
|
||||
|
||||
function fillValuesToHTML(dataset) {
|
||||
for (var key in dataset) {
|
||||
var key_prefixed = "data-" + key;
|
||||
var elements = document.getElementsByClassName(key_prefixed);
|
||||
// --- Globale Puffer für Select-Handling ---
|
||||
const selectDesiredValue = Object.create(null); // keyBase -> desired value ("speedsource" -> "GPS")
|
||||
const selectOptionsReady = Object.create(null); // keyBase -> true/false
|
||||
|
||||
if (elements.length > 0) {
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
var element = elements[i];
|
||||
function splitCsv(s) {
|
||||
return (s || "")
|
||||
.split(",")
|
||||
.map((x) => x.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
if (element.type === "checkbox") {
|
||||
// Wenn das Element ein Kontrollkästchen ist
|
||||
element.checked = dataset[key] == 1 ? true : false;
|
||||
} else if (element.tagName === "SELECT") {
|
||||
// Wenn das Element ein Dropdown ist
|
||||
setDropdownValue(element, dataset[key]);
|
||||
} else if (element.classList.contains("progress-bar")) {
|
||||
// Wenn das Element eine Fortschrittsleiste ist
|
||||
updateProgressBar(element, dataset[key]);
|
||||
} else if (element.classList.contains("hideable")) {
|
||||
// Wenn das Element ein Settingsabschnitt-div ist
|
||||
if (dataset[key] == 0) element.style.display = "none";
|
||||
else element.style.display = "";
|
||||
} else {
|
||||
// Standardmäßig für Textfelder und andere Elemente
|
||||
element.value = dataset[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
function hasOption(selectEl, value) {
|
||||
for (let i = 0; i < selectEl.options.length; i++) {
|
||||
if (selectEl.options[i].value === value) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function addOption(selectEl, value, selectIt = false) {
|
||||
const o = document.createElement("option");
|
||||
o.value = value;
|
||||
o.textContent = value;
|
||||
selectEl.appendChild(o);
|
||||
if (selectIt) {
|
||||
selectEl.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
// Funktion zum Setzen des ausgewählten Werts für Dropdowns
|
||||
function populateSelect(selectId, options, currentValue) {
|
||||
const sel = document.getElementById(selectId);
|
||||
if (!sel) return;
|
||||
|
||||
// 1) komplett ersetzen
|
||||
sel.innerHTML = "";
|
||||
options.forEach((opt) => addOption(sel, opt, false));
|
||||
|
||||
// 2) Zielwert bestimmen (currentValue > bereits gepuffert > vorhandener Wert > erste Option)
|
||||
const wanted =
|
||||
(currentValue && currentValue.length ? currentValue : null) ??
|
||||
selectDesiredValue[selectId] ??
|
||||
sel.value ??
|
||||
(options[0] || "");
|
||||
|
||||
// 3) Falls gewünschte Option fehlt, hinzufügen
|
||||
if (wanted && !hasOption(sel, wanted)) addOption(sel, wanted, false);
|
||||
|
||||
// 4) Setzen
|
||||
sel.value = wanted;
|
||||
|
||||
// 5) Markieren: Optionen sind ready
|
||||
selectOptionsReady[selectId] = true;
|
||||
// Verbrauchte Wunschwerte löschen
|
||||
delete selectDesiredValue[selectId];
|
||||
}
|
||||
|
||||
// Robust: setzt den Wert; wenn Option fehlt, füge sie hinzu
|
||||
function setDropdownValue(selectElement, value) {
|
||||
for (var i = 0; i < selectElement.options.length; i++) {
|
||||
if (selectElement.options[i].value === value) {
|
||||
selectElement.selectedIndex = i;
|
||||
break;
|
||||
if (!value) return;
|
||||
if (!hasOption(selectElement, value)) {
|
||||
addOption(selectElement, value, false);
|
||||
}
|
||||
selectElement.value = value;
|
||||
}
|
||||
|
||||
// Core: schreibt Werte in DOM, erkennt *-options und füllt Selects
|
||||
function fillValuesToHTML(dataset) {
|
||||
for (const key in dataset) {
|
||||
const val = dataset[key];
|
||||
|
||||
// A) Optionen-Feld? (z.B. "speedsource-options")
|
||||
if (key.endsWith("-options")) {
|
||||
const base = key.slice(0, -"-options".length); // "speedsource"
|
||||
const selectId = base; // ID = keyBase
|
||||
populateSelect(
|
||||
selectId,
|
||||
splitCsv(val),
|
||||
selectDesiredValue[selectId] || undefined
|
||||
);
|
||||
continue; // fertig mit diesem key
|
||||
}
|
||||
|
||||
// B) Normales Feld
|
||||
const key_prefixed = "data-" + key;
|
||||
const elements = document.getElementsByClassName(key_prefixed);
|
||||
if (elements.length === 0) continue;
|
||||
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
const el = elements[i];
|
||||
|
||||
// Checkbox?
|
||||
if (el.type === "checkbox") {
|
||||
el.checked = val == 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Select?
|
||||
if (el.tagName === "SELECT") {
|
||||
const selectId = el.id || key; // ID hat Vorrang, sonst key
|
||||
// Wenn die Optionen für dieses Select noch NICHT bereit sind, Wunschwert puffern
|
||||
if (!selectOptionsReady[selectId]) {
|
||||
selectDesiredValue[selectId] = val;
|
||||
// Sicherheitsnetz: falls doch schon Optionen existieren, sofort setzen
|
||||
setDropdownValue(el, val);
|
||||
} else {
|
||||
// Optionen sind ready -> ganz normal setzen (ggf. Option ergänzen)
|
||||
setDropdownValue(el, val);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Progress-Bar?
|
||||
if (el.classList.contains("progress-bar")) {
|
||||
updateProgressBar(el, val);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Hideable-Section?
|
||||
if (el.classList.contains("hideable")) {
|
||||
el.style.display = val == 0 ? "none" : "";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Input/Textarea?
|
||||
if ("value" in el) {
|
||||
el.value = val;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Fallback: content nodes (td, span, div)
|
||||
el.textContent = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -212,15 +300,15 @@ function showNotification(message, type) {
|
||||
// Erstellen Sie ein Bootstrap-Alert-Element
|
||||
var alertElement = $(
|
||||
'<div class="alert alert-' +
|
||||
type +
|
||||
' alert-dismissible fade show notification" role="alert">' +
|
||||
"<strong>" +
|
||||
message +
|
||||
"</strong>" +
|
||||
'<button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
|
||||
'<span aria-hidden="true">×</span>' +
|
||||
"</button>" +
|
||||
"</div>"
|
||||
type +
|
||||
' alert-dismissible fade show notification" role="alert">' +
|
||||
"<strong>" +
|
||||
message +
|
||||
"</strong>" +
|
||||
'<button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
|
||||
'<span aria-hidden="true">×</span>' +
|
||||
"</button>" +
|
||||
"</div>"
|
||||
);
|
||||
|
||||
// Fügen Sie das Alert-Element dem Container hinzu
|
||||
|
Reference in New Issue
Block a user