NEWS
[gelöst] Per js generierte Ausgabe mit Button
-
Hi Community,
nach langer Suche schreibe ich Euch hier, in der Hoffnung, die richtigen Antworten zu finden.
Mittlerweile zeige ich sehr viele Angaben per eigenem JS in der VIS Oberfläche an. Dazu habe ich viele einzelne Skripte, welche jeweils eine html/css generierte Ausgabe in einem State ablegen. Diese sammle ich und stelle damit ein Dashboard zusammen. Soweit so gut.
Nun zum Thema. Gerne möchte ich eigene Buttons darin umsetzen und nicht die VIS-Buttons nutzen. Klickbar bekomme ich den hin, allerdings schreibt solch ein eigen kreierter Button in einem State keine Änderung / Wert in einen anderen State.
Meine Vermutung, in der statisch eingebundenen HTML Ausgabe kann ich keinen Button "überwachen" und damit Aktionen auslösen.Freue mich, wenn mir jemand zeigen kann, wie man einen Button per JS erzeugt, die Darstellung per HTML in VIS einbindet und dann vor allen Dingen dieses Event (wenn geklickt) abfängt und weiter verarbeitet.
Beste Grüße!
-
in diesem script https://forum.iobroker.net/topic/28953/sonoff-geräte-als-html-tabelle-vis-iqontrol wird ein eigener button (emoji) erzeugt
an das html file wird am ende ein javascript angehängt - in diesem wird ein datenpunkt des iobroker geschalten (rechte spalte)
such im script nach "button" und "script" - falls du es nicht findest, könnte ich morgen mehr dazu schreiben
funktioniert nur in der vis - da die existierende socket verbindung genutzt wird
in diesem script wird einfach mit einem trigger gearbeitet um auf änderungen zu reagieren
drückt man im script auf den button, wird dieser ausgeführt und schaltet einen datenpunkt - daraufhin wird die tabelle neu aufgebaut und die änderung wird in der vis sichtbar
-
@dkerkow
Am einfachsten wäre es einen vorhandenes Knopf-Widget zu verwenden und dies per css-Anweisungen umzugestalten. -
@liv-in-sky
Danke, das versuche ich gleich morgen! -
@OliverIO
Genau das wollte ich nicht, sonst habe ich in der View wieder eine Kombination aus Buttons und Skripten. Wollte alles aus einer Hand. -
@liv-in-sky
Habe es versucht, aber es ist zu spät, oder ich bin zu blöd, oder beides ...
Wenn jemand einem Blinden helfen mag, dann bitte gerne.function testOneState() { var ausgabeTestOneButton = '<button onclick="changeValueTrue(true)">Button true</button>' + '<script>function changeValueTrue(myvalue) {var objID = myvalue; setState(\'javascript.0.TEST.ONE_STATE\', objID);}</script>'; setState('javascript.0.TEST.ONE_OUTPUT', ausgabeTestOneButton); } schedule("*/3 * * * * *", testOneState);
-
@dkerkow
Der code läuft ja im Browser.
Da gibt es setState nicht.
Dort heißt der Befehlvis.setValue(state, value);
-
diese constante wird am ende des html codes angehängt (hier ist es eine toggle function, hat nix mit doppelclick zu tun - der name blieb durch copy und paste, console.log erscheint im browser log unter entwicklertools - gut für debuggen):
const buttonScript = '<script> function setOnDblClickCustom( myvalue ) { var Self = this; var objID = myvalue; Self.servConn.getStates(objID, (error, states) => { console.log(states); Self.servConn.setState(objID, !states[objID].val); }); } </script>'
in der html tabelle ist der button hier definiert (darin wid function aufgerufen, wichtig ist der valButton wert - das ist der datenpunkt, die button def musst du definieren - hier ist ein emoji (symbolSwitch), val6 ist der eintrag in der tabelle (letzte spalte) :
val6="<button style\=\"border:none\; background-color\:transparent\; color\:white\; font\-size\:1em\; text\-align:left\" value=\"toggle\" onclick=\"setOnDblClickCustom\(\'"+valButton+"\')\">"+symbolSwitch+"</button> <font color=\""+farbeSchalterOFF+"\"> "+"OFF";
aus einem anderen script - kein toggle sondern setze "true"
'function setOnSort( myvalue ) { var Self = this; Self.servConn.setState(\''+dpSort+'\', myvalue); Self.servConn.setState(\''+dpRefresh+'\', true) }'
hier wird eine zahl gesetzt (am ende der function)(auch hier ist der function name schlecht gewählt)(am ende wird dpRefresh gesetzt - auf diesen dp wird auch im script getriggert und die tabelle neu aufgebaut - da die tabelle durch diese function anders sortiert werden soll und daher neu aufgebaut werden muss, hier ist es kein button sondern input-feld):
function setOnDblClickCustom( myvalue ) { var Self = this; var objID = myvalue; Self.servConn.getStates(objID, (error, states) => { console.log(states); Self.servConn.setState(objID, !states[objID].val); }); Self.servConn.setState(\''+dpRefresh+'\', '+sortNumber+'); } '
dein beispiel - du brauchst einen zweiten dp (zeichenkette)
in der vis wird der ONE_TABLE dp als binding im html widget angegeben
sieht dann so aus in der vis-runtime:
let valButton="javascript.0.TEST.ONE_OUTPUT" let symbolSwitch="🔄" let farbeSchalterOFF="lightblue" function testOneState() { let ausgabeTestOneButton = '<script> function setOnDblClickCustom( myvalue ) { var Self = this; var objID = myvalue; Self.servConn.getStates(objID, (error, states) => { console.log(states); Self.servConn.setState(objID, !states[objID].val); }); } </script>'; let val6="<button style\=\"border:none\; background-color\:transparent\; color\:white\; font\-size\:1em\; text\-align:left\" value=\"toggle\" onclick=\"setOnDblClickCustom\(\'"+valButton+"\')\">"+symbolSwitch+"</button> <font color=\""+farbeSchalterOFF+"\"> "+"SCHALTE HIER"; log(val6.concat(ausgabeTestOneButton)) setState('javascript.0.TEST.ONE_TABLE', val6.concat(ausgabeTestOneButton)); } schedule("*/10 * * * * *", testOneState);
-
wegen dem vis.setState....
kann ich diesen befehl z.b in einem binding verwenden ?
hst du ein beispiel dafür
habe mal in der vis getestet:
ein html widget mit diesem inhalt:
<style> /* Style the button */ button { isplay: inline-block; padding: 15px 25px; font-size: 18px; cursor: pointer; text-align: center; text-decoration: none; outline: none; color: #0efbf6; background-color: black; border: none; border-radius: 5px; /*box-shadow: 0 2px #0efbf6;*/ } </style> <button onclick="mytest();">CLICK</button>
und unter dem scripte tab in der vis:
function mytest() {console.log("bin da"); vis.setState("javascript.0.TEST.ONE_OUTPUT",true)}
der output im browser:
-
Weiß, das ist etwas blöd gelöst.
Auf dem Server in der JavaScript Engine = setState
Auf dem. Client I’m Browser = vis.setValueSchön wäre, wenn man auf dem Server und dem. Client die selben Befehle zur Verfügung hat
-
-
@liv-in-sky
You didn’t get it
Du hast da den falschen Befehl.
Tausche vis.setState gegen vis.setValue aus -
@OliverIO sorry - oh mann bin ich ...
ich teste mal
-
danke - alles gut funktioniert - gibt es auch vis.getValue ?
-
@liv-in-sky das kommt darauf an ob der datenpunkt im Browser bereits abonniert ist.
Abonniert heißt, das der datenpunkt in einem anderen Widget schon mal bekannt gemacht worden ist.Wenn ja, dann kann der Wert wie folgt abgerufen werden
vis.states.attr(datenpunkt.val');
Anstatt .val kannst du auch .ts angeben um bspw die letzte Änderung auszulesen. Es gibt noch weitere extensions. Da musst du in die Iobroker Doku mal schauen.
Über die chromed developer tools kannst du mal vis.states in watch Eingeben und schauen, da müsste ein Array mit allen abonnierten datenpunkten sein.
Wenn der datenpunkt noch nicht abonniert wurde wird es etwas komplexer, insbesondere, wenn du per callback informiert werden wills, wenn sich ein Wert ändert.
Dazu kannst du mal in meine Adapter widgets rssfeed oder openligadb schauen. Allerdings ist vis keine einfache Kost. Ich habe viel Zeit im debugger verbracht um ein paar Funktionsweisen nachzuvollziehen.
-
ja hört sich strange an - aber tausend dank für die erläuterung
muss da morgen mal in ruhe noch mal "spielen"
-
@OliverIO sagte in Per js generierte Ausgabe mit funktionsfähigem Button:
vis.setValue(state, value);
Spitze! Genau das war die fehlende Antwort bei mir.
Funktioniert.