Hallo liebe Community,
ich möchte mit einem HTML Widget ein interaktives Dropdown Menü erstellen, wo der Nutzer einzelne Messwerte auswählen kann und die Auswahl in einem Datenpunkt gespeichert wird. Anschließend soll er auf "Auswerten" klicken können, dann werden die gewählten Messdaten aus der InfluxDB im gewählten Zeitraum gefischt und in einer CSV zum Download bereitgestellt.
Die verfügbaren Messwerte liegen auch in einem Datenpunkt, die zuvor ein Crawler Skript erstellt hat.
Mein Problem ist jetzt, dass der Javascript Code, der das Dropdown-Menü befüllen soll, nur im Editor der VIS-2 funktioniert im Runtime Modus, aber nicht im Browser (Firefox und Chrome geht beides nicht, sowie die IOBroker App auf iOS auch nicht).
Woran kann das liegen?
HTML-Widget:
<div id="dropdown-container" style="position: relative; display: inline-block; width: 200px;">
<!-- Button für das Dropdown -->
<div id="dropdown-toggle" class="btn_grafana_style" style="position: relative; display: flex; align-items: center; justify-content: space-between; padding: 10px; cursor: pointer;">
<span>Messwerte auswählen</span>
<!-- Pfeil-Symbol -->
<span id="dropdown-arrow" style="margin-left: 10px; font-size: 12px;">▼</span>
</div>
<!-- Dropdown-Menü -->
<div id="dropdown-menu" style="position: absolute; top: 100%; left: 0; width: 100%; background-color: white; border: 1px solid #ccc; padding: 10px; z-index: 1000; max-height: 300px; overflow-y: auto; display: none;">
<!-- Hier werden die Checkboxen dynamisch hinzugefügt -->
</div>
</div>
Javascript Code im Bereich "Skripte" im VIS Editor:
// IDs der Datenpunkte
const sourceDataPoint = "0_userdata.0.Export.Verfügbare_Messwerte"; // JSON mit Messwerten
const targetDataPoint = "0_userdata.0.Export.Ausgewählte_Messwerte"; // Array für ausgewählte Messwerte
// Dropdown-Elemente
const dropdownToggle = document.getElementById("dropdown-toggle");
const dropdownMenu = document.getElementById("dropdown-menu");
// Funktion: Dropdown anzeigen/verstecken
dropdownToggle.addEventListener("click", (event) => {
event.stopPropagation(); // Verhindert, dass der Klick das Schließen triggert
dropdownMenu.style.display = dropdownMenu.style.display === "none" ? "block" : "none";
});
// Funktion: Schließt das Dropdown, wenn man außerhalb klickt
document.addEventListener("click", (event) => {
if (!dropdownMenu.contains(event.target) && event.target !== dropdownToggle) {
dropdownMenu.style.display = "none";
}
});
// Funktion: Verfügbare Messwerte laden und Checkboxen generieren
function loadMeasurements() {
vis.conn.getStates(sourceDataPoint, (err, state) => {
if (err || !state[sourceDataPoint] || !state[sourceDataPoint].val) {
console.error("Fehler beim Laden der Messwerte:", err || "Keine Daten gefunden");
return;
}
// JSON-Daten parsen
const data = JSON.parse(state[sourceDataPoint].val);
// Dropdown leeren
dropdownMenu.innerHTML = "";
// Checkboxen für alle Messwerte generieren
data.forEach((item) => {
const bucket = item.bucket;
item.measurements.forEach((measurement) => {
const checkboxId = `checkbox-${bucket}-${measurement}`;
const checkboxContainer = document.createElement("div");
checkboxContainer.style.marginBottom = "5px";
const checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.id = checkboxId;
checkbox.dataset.bucket = bucket;
checkbox.dataset.measurement = measurement;
const label = document.createElement("label");
label.htmlFor = checkboxId;
label.textContent = `${bucket}: ${measurement}`;
checkboxContainer.appendChild(checkbox);
checkboxContainer.appendChild(label);
dropdownMenu.appendChild(checkboxContainer);
});
});
// Event-Listener für Änderungen an den Checkboxen hinzufügen
Array.from(dropdownMenu.querySelectorAll("input[type='checkbox']")).forEach((checkbox) => {
checkbox.addEventListener("change", saveSelection);
});
});
}
// Funktion: Auswahl speichern
function saveSelection() {
const selectedMeasurements = [];
// Alle ausgewählten Checkboxen sammeln
Array.from(dropdownMenu.querySelectorAll("input[type='checkbox']:checked")).forEach((checkbox) => {
selectedMeasurements.push({
bucket: checkbox.dataset.bucket,
measurement: checkbox.dataset.measurement
});
});
// Auswahl als JSON-String in den Ziel-Datenpunkt speichern
vis.setValue(targetDataPoint, JSON.stringify(selectedMeasurements));
}
// Messwerte beim Start laden
loadMeasurements();
// Falls sich die verfügbaren Messwerte ändern, neu laden
vis.conn.subscribe(sourceDataPoint, (id, state) => {
if (id === sourceDataPoint && state) {
loadMeasurements();
}
});
Screenshot Dropdown Menü:
Wie gesagt im Runtime Modus innerhalb des VIS-Editors funktioniert es einwandfrei, inkl. Speichern der ausgewählten Messwerte.
Ich nutze VIS-2 2.9.64