Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Deutsch
    3. Skripten / Logik
    4. Frage an die HTML und Javascript Experten

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    UNSOLVED Frage an die HTML und Javascript Experten

    This topic has been deleted. Only users with topic management privileges can see it.
    • O
      Oli last edited by

      Hallo zusammen,
      ich versuche mich zur Zeit an der VIS-2. Da dort aber einige meiner bevorzugten Widgets nicht funktionieren (z.B. das IconList Widget), wollte ich versuchen dieses über eine HTML Struktur nachzubauen.

      Die Optik sieht meiner Meinung nach auch schon ganz gut aus, bei den Funktionen scheitere ich aber, da ich bei HTML erst ganz am Anfang stehe.

      VIS 1 mit dem IconList Widget aus dem alten MaterialDesign Adapter
      0bb74681-116f-4f91-aeb9-e17998bfc744-image.png

      VIS 2 mit einem HTML Widget
      7ea8d002-7fc4-40cf-bdc7-7dcb43f82a51-image.png

      Skript

      /************************************************************************************************************************************************************************
      Version: 1.0.0
      created by Scrounger letzte Aktualierung: 04.03.2020
      Dieses Skript erzeugt einen json string um Javascript Informationen im VIS mit den Material Design Widgets darzustellen
      =========================================================================================================================================================================
      !!! Voraussetzungen !!!
      * Material Design Widgets               >= 0.3.6
      * Javascript Adapter                    >= 4.6.1
      * Javascript Adapter NPM Module:        moment
      =========================================================================================================================================================================
      --- Links ---
      * Support:          https://forum.iobroker.net/topic/30662/material-design-widgets-skript-status
      =========================================================================================================================================================================
      --- Changelog ---
      * 1.0.0:            Initial release
      ************************************************************************************************************************************************************************/
      // imports NPM Module -> müssen im Javascript Adapter unter 'Zusätzliche NPM-Module' eingetragen sein
      const moment = require("moment-timezone");
      // **********************************************************************************************************************************************************************
      
      // Skript Einstellungen *************************************************************************************************************************************************
      
      let dpList = '0_userdata.0.SkriptStatus.HtmlList';                            // Datenpunkt für IconList Widget (Typ: Zeichenkette (String))
      let dpskriptRestart = '0_userdata.0.SkriptStatus.RestartTrigger';             // Datenpunkt für Skript restart (Typ: Zeichenkette (String))
      
      let dpSortMode = '0_userdata.0.SkriptStatus.SortMode';                        // Datenpunkt für Sortieren (Typ: Zeichenkette (String))
      let dpFilterMode = '0_userdata.0.SkriptStatus.FilterMode';                    // Datenpunkt für Filter (Typ: Zeichenkette (String))
      
      let sprache = 'de';                                                           // Sprache für formatierung letzte Änderung
      let formatierungLastChange = "ddd DD.MM.YYYY - HH:mm";                        // Formatierung letzte Änderung -> siehe momentjs library
      
      let neustarten = true;                                                        // true: Skript wird neugestartet, false: Skript wird gestoppt oder gestartet
      
      let farbeSkriptAktiv = 'green';                                               // Status Bar Farbe wenn Skript aktiv ist
      let farbeSkriptDeaktiviert = 'darkgrey';                                      // Status Bar Farbe wenn Skript deaktiviert ist
      let farbeSkriptProblem = 'FireBrick';                                         // Status Bar Farbe wenn Skript Problem hat
      
      let sortResetAfter = 120;                                                     // Sortierung nach X Sekunden auf sortReset zurücksetzen (0=deaktiviert)
      let sortReset = 'name'                                                        // Sortierung auf die zurückgesetzt werden soll
      
      let filterResetAfter = 120;                                                   // Filter nach X Sekunden zurücksetzen (0=deaktiviert) 
      const checkInterval = 60;                                                     // Interval wie oft Status der Skripte überprüft werden soll (in Sekunden)
      
      const imagePath = '/vis-2.0/GlasVersion/Bilder/Logos/';             // Pfad für Bilder
      // **********************************************************************************************************************************************************************
      
      // Fomate für moment Lib
      moment.locale(sprache);
      
      // auf Änderungen der Sortieung hören
      on({ id: dpSortMode, change: 'ne' }, skriptStatus);
      on({ id: dpSortMode, change: 'ne' }, resetSort);
      
      // // auf Änderungen der Filter hören
      on({ id: dpFilterMode, change: 'ne' }, skriptStatus);
      on({ id: dpFilterMode, change: 'ne' }, resetFilter); 
      
      // Funktion selektorStatus alle x Sekunden ausführen
      schedule('*/' + checkInterval + ' * * * * *', skriptStatus);
      
      // Beim Staren des Skriptes Adapter Status abrufen
      datenpunkte();
      
      //Datenpunkte anlegen
      function datenpunkte() {
         if (existsState(dpskriptRestart)) {
             skriptStatus()
         } else {
             mySetState(dpList, '', 'string', 'SkriptStatus');        
             mySetState(dpSortMode, 'name', 'string', 'SkriptStatus Sortierung');
             mySetState(dpFilterMode, '', 'string', 'SkriptStatus Filter');        
             mySetState(dpskriptRestart, '', 'string', `SkriptStatus Schalter`);
      
             setTimeout(function() {
                 skriptStatus()
             }, 3000);
         }
      }
      
      function skriptStatus() {
         //if (getState(dpNavi).val == navSeite) {
             let skriptList = [], htmlText = '';
             let enableSelector = `[id=javascript.*.scriptEnabled.*]`;
             let skriptEnableList = $(enableSelector);
      
             let htmlKopf = `
                 <html>
                 <style>
                 *,
                 ::before,
                 ::after {
                     box-sizing: border-box;
                 }
      
                 main {
                     display: grid;
                     gap: 1rem;
                     grid-template-columns: repeat(auto-fill, minmax(min(30em, 100%), 1fr));
                     color: #8f8f8f;
                     font-size: 14px;
                 }
      
                 main > section {
                     padding: 1em;
                     background: hsl(220 80% 90%);
                     border-radius: 5px;
                     box-shadow: 2px 2px 3px rgba(20, 20, 20, 50);
                     text-align: left;
                     background-color: rgba(38,45,61,1);
                 }
      
                 h2 {
                     margin: 0 0 1.3rem;
                     line-height: 1em;
                     color: #d7cec1; 
                     font-size: 16px; 
                     text-shadow: rgba(0, 0, 0, 0.9) 3px 3px 4px;
                 }
                 </style>
      
                 <main>
             `
             let htmlEnde = `
                 </main>
                 <hr style="border-color: transparent;">
                 </html>
             `
      
             try {
                 for (var i = 0; i <= skriptEnableList.length - 1; i++) {
                     let id = skriptEnableList[i];
      
                     if (existsObject(id)) {   
                         let obj = getObject(id);
                         let scriptObj = undefined;
                         let scriptName = '';
                         let engineType = '';
                         let lastChangeText = '';
                         let lastChange = 0;
                         let image = 'image-off-outline';
                         let imageColor = '';
                         let statusBarColor = farbeSkriptDeaktiviert;
                         let status = 1;
      
                         if (obj && obj !== null && obj.native && obj.native.script) {
                             scriptObj = getObject(obj.native.script);
      
                             if (scriptObj && scriptObj.common) {
                                 if (scriptObj.common.name) {
                                     scriptName = scriptObj.common.name;
                                     scriptName = scriptName.replace(/_/g, ' ')
                                 }
      
                                 if (scriptObj.common.engineType) {
                                     engineType = scriptObj.common.engineType.replace('/js', '').replace('/ts', '');
      
                                     if (engineType.toLowerCase() === 'Javascript'.toLowerCase()) {
                                         image = `${imagePath}JavaScript-Logo.png`;
                                         //imageColor = '#ffca28';
                                     } else if (engineType.toLowerCase() === 'TypeScript'.toLowerCase()) {
                                         image = `${imagePath}TypeScript-Logo.png`;
                                         //imageColor = '#007acc';
                                     } else if (engineType.toLowerCase() === 'Blockly'.toLowerCase()) {
                                         image = `${imagePath}Blocky-Logo.png`;
                                         //imageColor = '#5a80a6';
                                     }
                                 }
      
                                 if (scriptObj.ts) {
                                     lastChange = scriptObj.ts;
                                     lastChangeText = moment(scriptObj.ts).format(formatierungLastChange);
                                 }
      
                                 if (scriptObj.common.enabled) {
                                     statusBarColor = farbeSkriptAktiv;
                                     status = 0;
                                 }
                             }
                         }
      
                         if (myHelper().getStateValueIfExist(id) === 'true') {
                             statusBarColor = farbeSkriptAktiv;
                             status = 0;
                         }
      
                         if (myHelper().getStateValueIfExist(id.replace('.scriptEnabled.', '.scriptProblem.'), false) === 'true') {
                             statusBarColor = farbeSkriptProblem;
                             status = 2;
                         }
      
                         let folder = '-';
                         let folderList = id.replace('javascript.0.scriptEnabled.').split(".");
                         if (folderList.length > 1) {
                             folder = id.replace('javascript.0.scriptEnabled.', '').replace('.' + folderList[folderList.length - 1], '');
                         }
      
                         let text = scriptName;
                         if (status === 2) {
                             text = `<span class="mdi mdi-alert-box-outline" style="color: #d7cec1;"></span> ${scriptName}`
                         }
      
                         let subText = `
                             <div style="display: flex; flex-direction: row; line-height: 1.3; padding-left: 10px; padding-right: 8px; align-items: center;">
                             <div style="flex: 1; font-size: 12px;">Sprache</div>
                             <div style="color: #8f8f8f; font-size: 12px; font-family: Arial, Helvetica, sans-serif-LightItalic; text-align: right;">${engineType}</div>
                             </div>
      
                             <div style="display: flex; flex-direction: row; line-height: 1.3; padding-left: 10px; padding-right: 8px; align-items: center;">
                             <div style="flex: 1; font-size: 12px;">letzte Änderung</div>
                             <div style="color: #8f8f8f; font-size: 12px; font-family: Arial, Helvetica, sans-serif-LightItalic; text-align: right;">${lastChangeText}</div>
                             </div>
      
                             <div style="display: flex; flex-direction: row; line-height: 1.3; padding-left: 10px; padding-right: 8px;">
                             <div style="flex: 1; font-size: 12px;">Ordner</div>
                             <div style="color: #8f8f8f; font-size: 12px; font-family: Arial, Helvetica, sans-serif-LightItalic; text-overflow: ellipsis; white-space: normal; text-align: right;">${folder}</div>
                             </div>
                         `
      
                         htmlText = htmlText + `
                             <section style= "border-color: ${statusBarColor}; border-style: solid; border-width: 0px 0px 5px 0px">
                             <h2>${text}</h2>
                             <img style="float: left; margin-right: 10px;" src="${image}" width="50" height="50" /><p>${subText}</p>
                             </section>
                         `  
                     }    
                 }
      
                 let sortMode = myHelper().getStateValueIfExist(dpSortMode, 'name');
      
                 if (sortMode === 'name') {
                     skriptList.sort(function (a, b) {
                         return a[sortMode].toLowerCase() == b[sortMode].toLowerCase() ? 0 : +(a[sortMode].toLowerCase() > b[sortMode].toLowerCase()) || -1;
                     });
                 } else if (sortMode === 'lastChange' || sortMode === 'status' || sortMode === 'folder') {
                     skriptList.sort(function (a, b) {
                         return a[sortMode] == b[sortMode] ? 0 : +(a[sortMode] < b[sortMode]) || -1;
                     });
                 } else {
                     // default: nach name sortieren
                     sortMode = 'name'
                     skriptList.sort(function (a, b) {
                         return a[sortMode].toLowerCase() == b[sortMode].toLowerCase() ? 0 : +(a[sortMode].toLowerCase() > b[sortMode].toLowerCase()) || -1;
                     });
                 }
      
                 let filterMode = myHelper().getStateValueIfExist(dpFilterMode, null);
      
                 if (filterMode && filterMode !== null && filterMode !== '') {
                     if (filterMode === 'error') {
                         skriptList = skriptList.filter(function (item) {
                             return item.status === 2;
                         });
                     } else if (filterMode === 'deactivated') {
                         skriptList = skriptList.filter(function (item) {
                             return item.status === 1;
                         });
                     } else if (filterMode === 'activated') {
                         skriptList = skriptList.filter(function (item) {
                             return item.status === 0;
                         });
                     }
                 }
      
                           
                 mySetState(dpList, htmlKopf + htmlText + htmlEnde, 'string', 'SkriptStatus');
      
             } catch (err) {
                 console.error(`[skriptStatus] error: ${err.message}, stack: ${err.stack}`);
             }
         //}    
      }
      
      // Funktion um Skript starten / Stoppen
      on({ id: dpskriptRestart }, function (obj) {
         if (existsState(dpskriptRestart) && getState(dpskriptRestart).val != null && getState(dpskriptRestart).val != '') { 
             var scriptObj = getObject(obj.state.val.toString());
      
             if (neustarten) {
                 scriptObj.common.enabled = true;
                 setObject(obj.state.val.toString(), scriptObj);
             } else {
                 if (scriptObj && scriptObj.common) {
      
                     if (scriptObj.common.enabled) {
                         scriptObj.common.enabled = false;
                     } else {
                         scriptObj.common.enabled = true;
                     }
      
                     setObject(obj.state.val.toString(), scriptObj);
                 }
             }
         }    
      });
      
      function resetSort() {
         let sortMode = myHelper().getStateValueIfExist(dpSortMode, null);
      
         if (sortResetAfter > 0) {
             setTimeout(function () {
                 if (sortMode !== null && sortMode === myHelper().getStateValueIfExist(dpSortMode, null)) {                
                     mySetState(dpSortMode, sortReset, 'string', 'SkriptStatus Sortierung');        
                 }
             }, sortResetAfter * 1000);
         }
      }
      
      function resetFilter() {
         let filterMode = myHelper().getStateValueIfExist(dpFilterMode, null);
      
         if (filterResetAfter > 0) {
             setTimeout(function () {
                 if (filterMode !== null && filterMode === myHelper().getStateValueIfExist(dpFilterMode, null)) {                                
                     mySetState(dpFilterMode, '', 'string', 'SkriptStatus Filter');       
                 }
             }, filterResetAfter * 1000);
         }
      }
      
      function myHelper() {
         return {
             getStateValueIfExist: function (id, nullValue = undefined, prepand = '', append = '') {
                 if (existsState(id)) {
                     return prepand + getState(id).val + append;
                 } else {
                     return nullValue;
                 }
             },
             getCommonPropertyIfExist: function (object, prop, nullValue = undefined, prepand = '', append = '') {
                 if (myHelper().checkCommonPropertyExist(object, prop)) {
                     return prepand + object.common[prop] + append;
                 } else {
                     return nullValue;
                 }
             },
             checkCommonPropertyExist: function (object, prop) {
                 if (object && object.common && object.common[prop]) {
                     return true;
                 } else {
                     return false;
                 }
             }
         }
      }
      
      function mySetState(id, val, type, name, write = true) {
         if (existsState(id)) {
             setState(id, val, true);
         } else {
             createState(id, {
                 'name': name,
                 'desc': 'Created by Javascript',
                 'type': type,
                 'read': true,
                 'write': write
             }, function () {
                 setState(id, val, true);
             });
         }
      } 
      
      

      Jetzt meine Fragen:

      1. Geht das erstellen der Cards irgendwie besser (habe mir diese Lösung aus dem Internet kopiert)?
      2. Kann ich eine Filter- und Sortierfunktion einbauen?
      3. bekomme ich einen Button in jede Card, mit dem ich einen Datenpunkt beschreiben kann (ausgewähltes Script stoppen und starten)?

      Vielen Dank schon mal im Voraus!!!

      OliverIO 1 Reply Last reply Reply Quote 0
      • OliverIO
        OliverIO @Oli last edited by OliverIO

        @oli sagte in Frage an die HTML und Javascript Experten:

        1. Geht das erstellen der Cards irgendwie besser (habe mir diese Lösung aus dem Internet kopiert)?

        zunächst bitte kein <html> tag schreiben. das existiert bereits in vis und es darf nur einmal geben
        ansonsten, wenn du zurecht kommst alles ok
        ich würde das html besser formatieren, also mit einrückungen, aber wenn es für dich ok ist alles gut.

        1. Kann ich eine Filter- und Sortierfunktion einbauen?

        ja, du könntest ein textfeld platzieren, welches dann einen datenpunkt beschreibt. auf den triggerst du in deinem skript und erzeugst das html erneut aber mit den gefilterten elementen

        1. bekomme ich einen Button in jede Card, mit dem ich einen Datenpunkt beschreiben kann (ausgewähltes Script stoppen und starten)?

        um per javascript einen datenpunkt zu beschreiben kannst du den befehl vis.setValue("datenpunkt","wert") verwenden. mit den anführungsstriche muss man ein wenig aufpassen, sonst kommt der browser durcheinander. aber du kannst das ja mit den developer tools im chrome dann überprüfen und auch debuggen.

        <button onclick="vis.setValue('datenpunkt','wert')">Start</button>
        
        O 1 Reply Last reply Reply Quote 1
        • O
          Oli @OliverIO last edited by

          @oliverio
          Danke für dein Feedback, deine Tipps werde ich umsetzten und das mit dem Button funktioniert super.

          Wie mache ich das am besten, wenn ich mehrere Button nebeneinander haben möchte?

          OliverIO 1 Reply Last reply Reply Quote 0
          • OliverIO
            OliverIO @Oli last edited by

            @oli

            wo ist da das problem. hier mal 3 knöpfe im html widget?

            32e4fcb9-6d6b-4969-968f-8176f937a2ce-image.png

            <button>test1</button><button>test1</button><button>test1</button>
            

            im zweifel mit css

            1 Reply Last reply Reply Quote 0
            • First post
              Last post

            Support us

            ioBroker
            Community Adapters
            Donate

            508
            Online

            31.9k
            Users

            80.2k
            Topics

            1.3m
            Posts

            javascript
            2
            4
            255
            Loading More Posts
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes
            Reply
            • Reply as topic
            Log in to reply
            Community
            Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
            The ioBroker Community 2014-2023
            logo