Ankündigung

Einklappen
Keine Ankündigung bisher.

Item mit (nested) Liste darstellen

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Item mit (nested) Liste darstellen

    Hallo,

    ich suche ein Möglichkeit / Lösung, um den Inhalt einer (nested) Liste darzustellen.

    Es geht um die Schaltzeiten meiner Heizung. Jeder Tag hat 4 Schaltzeitpaare, also 4 Möglichkeiten An und Aus zu festzulegen. Die Schaltzeitpaare sind als Liste verfügbar. Diese hat folgendes Format:
    Code:
    [{'An': '04:40', 'Aus': '21:00'}, {'An': '00:00', 'Aus': '00:00'}, {'An': '00:00', 'Aus': '00:00'}, {'An': '00:00', 'Aus': '00:00'}]
    Das Item heißt "heizung.heizkreis_m2.schaltzeiten.wochentag", also "heizung.heizkreis_m2.schaltzeiten.sonntag", "heizung.heizkreis_m2.schaltzeiten.montag" usw.

    Nun möchte ich diese Listen in einer Tabelle darstellen, in der jeder Schaltzeit ein Feld ist.
    So in etwa:
    Anmerkung 2020-04-28 212727.png

    Mein Widget sieht so aus:

    Code:
    {% macro timer_display(id, txt, gad_timer) %}
        {% import "basic.html" as basic %}
        {% set uid = uid(page, id) %}
        {% if txt %}<b>{{ txt|e }}</b><br/>{% endif %}
        <div id="{{ uid }}">        
            {% set days = ['montag','dienstag','mittwoch','donnerstag','freitag','samstag','sonntag'] %}
            {% set times = ['an1','aus1','an2','aus2','an3','aus3','an4','aus4'] %}
            <table>
                <th width=12%>
                {% for t in times %}
                    <th>{{ t }}</th>
                {% endfor %}
                </th>
    
                {% for day in days %}
                    <tr>
                    <th ALIGN="LEFT">{{ day }}</th>
                    {% for t in times %}
                        {% set item = gad_timer~'.'~day %}
                        <td>{{ basic.print( '', item, '') }}</td>
                    {% endfor %}
                    </tr>
                {% endfor %}
            </table>
        </div>
    {% endmacro %}
    Wie kann ich die Elemente der Liste aus dem Item ansprechen? In Python geht es mit item[0]['An']
    Aber wie geht es hier?

    Bin für jeden sachdienlichen Hinweis dankbar.

    #2
    Ich behaupte, da kommst du nicht um den Javascript Part rum, wenn du den Inhalt der Items abgreifen willst. Da dürfte es dann recht ähnlich zu Python ablaufen. Im device.uzsuicon wird auch mit einem dict in der Response hantiert.

    Kommentar


      #3
      Wenn ich mich recht entsinne, sind tables in Kombination mit jQM nicht immer problemlos. Ich würde die Tabellenzeile durch 9 spans ersetzen, die jeweils eine id haben (Wochentag, An1, Aus1 ...) und per css formatiert werden (ähnlich wie device.smallshut). Im js kannst Du dann die id von jedem <span> mit "find" ansprechen und die Zeiten direkt dort hinein schreiben. Im html wird die Tabelle dann zeilenweise aus den einzelnen items aufgebaut.
      Da die items sehr regelmäßig formatiert sind, kannst Du die Zeiten im js mit substrings sauber herausoperieren und direkt in die spans schreiben. Dann brauchst Du Dich nicht nochmal mit einem Array rumzuschlagen.
      Interessant wäre mal alternativ, ob JSON.parse() nicht schon ein Array liefert, dass man direkt verwenden kann. Ein Versuch wäre es wert. Notfalls muss man die Apostrophe vorher durch doppelte Anführungszeichen ersetzen (replace-Funktion).

      Gruß
      Wolfram

      Kommentar


        #4
        Bin mal meinem Spieltrieb nachgegangen: in der Tat liefert JSON.parse() ein brauchbares Ergebnis, wenn die Anführungszeichen ersetzt sind - siehe hier.
        Ohne Tausch der Anführungszeichen geht es nicht.
        Zuletzt geändert von wvhn; 29.04.2020, 10:05.

        Kommentar


          #5
          Und noch ein bisschen weiter gespielt: Beispiel
          So bekommst Du ein Array, das Du mit obj[0].An ... auslesen kannst, wie Dein Python Array.

          Grober Entwurf (nicht ausprobiert): Nach der Zeile
          Code:
          {% set item = gad_timer~'.'~day %}
          anstelle der Zeile mit dem Aufruf von basic.print
          Code:
          <span data-widget="mywidget.timer_display" data-item="{{ item }}" ></span>;
          Und dann in der mywidget.js ein Makro
          Code:
          $.widget("sv.mywidget_timerdisplay", $.sv.widget, {
          
              initSelector: '[data-widget="mywidget.timer_display"]',
          
              _update: function(response) {
                  txt = response[0].replace(/\'/g, '"');
                  var obj = JSON.parse(txt);
                  // ab hier die Ausgabe der Werte obj[i].An und obj[i].Aus ins html Gerüst
                  ...
              }
          }
          Die Formatierung ist dann sicherlich einge Bastelarbeit.

          Gruß
          Wolfram

          Kommentar


            #6
            Hallo Wolfram,

            danke für Deine Input.
            Damit betrete ich wieder Neuland. Bin grad mit Python etwas war geworden....

            Hab das nun mal soweit nachgebaut bzw. Deine Anmerkungen übertragen.
            Zitat von wvhn Beitrag anzeigen
            // ab hier die Ausgabe der Werte obj[i].An und obj[i].Aus ins html Gerüst
            Mit dem Hinweis komme ich mit meinem Wissen noch nicht weiter. Ich weiß, wich die Werte ansprechen kann, aber wie übergebe ich diese an html?
            Code:
            this.element.val(obj[1].An);
            So?
            Danke für Deine Hilfe

            Aktueller Stand:
            mywidget.js
            Code:
            $.widget("sv.mywidget_timerdisplay", $.sv.widget, {
            
                initSelector: '[data-widget="mywidget.timer_display"]',
            
                _update: function(response) {
                    txt = response[0].replace(/\'/g, '"');
                    var obj = JSON.parse(txt);
                    // ab hier die Ausgabe der Werte obj[i].An und obj[i].Aus ins html Gerüst
                    this.element.val(obj[1].An);
                }
            }
            mywidget.html
            Code:
            /**
             * Viessmann Schaltzeiten Widget als Tabelle zum Anzeigen (Input Liste)
             *
             * @param       unique id for this widget
             * @param       Headline
             * @param       the gad/item for timer (parent item)
             *
             */
            {% macro timer_display(id, txt, gad_timer) %}
                {% import "basic.html" as basic %}
                {% set uid = uid(page, id) %}
                {% if txt %}<b>{{ txt|e }}</b><br/>{% endif %}
                <div id="{{ uid }}">        
                    {% set times = ['an1','aus1','an2','aus2','an3','aus3','an4','aus4'] %}
                    <table>
                        <th width=12%>
                        {% for t in times %}
                            <th>{{ t }}</th>
                        {% endfor %}
                        </th>
            
            
                            {% for t in times %}
                                {% set item = gad_timer~'.'~day %}
                                <span data-widget="mywidget.timer_display" data-item="{{ item }}" ></span>;
                            {% endfor %}
                            </tr>
            
                    </table>
                </div>
            {% endmacro %}
            und der Aufruf auf der Seite:
            Code:
            {{ mywidget.timer_display ('', '', 'heizung.warmwasser.schaltzeiten.sonntag') }}
            Damit sollte erstmal nur ein Array mit den 4 Schaltzeiten für Sonntag kommen.
            Zuletzt geändert von Sisamiwe; 29.04.2020, 14:44.

            Kommentar


              #7
              Hallo Wolfram,

              ich habe die Sache nochmal vereinfacht, um mich dem Thema zu nähern.

              Ein Thema ist das replace im Javascript.
              Wenn die Funktion wie in Deinem Vorschlag
              Code:
              txt = response[0].replace(/\'/g, '"');
              angewendet ist, kommt die Fehlermeldung
              Code:
              mywidget.js:6 Uncaught TypeError: Cannot read property 'replace' of undefined
              .

              Laut Recherche könnte es sein, dass repsonse kein String ist.

              Ändere ich das das replace in
              Code:
              txt = response.toString().replace(/\'/g, '"');
              , kommt ein Fehler beim nächsten Befehl mit
              Code:
               Uncaught SyntaxError: Unexpected end of JSON input
              Mhhh....

              Nachtrag:

              In der BrowserKonsole habe ich nachgeschaut, wie die Iteminhalte übergeben werden. Da habe ich das gefunden:
              Code:
              ["heizung.warmwasser.schaltzeiten.sonntag",[{"An":"04:00","Aus":"04:40"},{"An":"16:30","Aus":"17:10"},{"An":"00:00","Aus":"00:00"},{"An":"00:00","Aus":"00:00"}]]
              im Item "heizung.warmwasser.schaltzeiten.sonntag" selbst steht:
              Code:
              [{'An': '04:00', 'Aus': '04:40'}, {'An': '16:30', 'Aus': '17:10'}, {'An': '00:00', 'Aus': '00:00'}, {'An': '00:00', 'Aus': '00:00'}]
              Wird dann das Replace automatisch gemacht?
              Zuletzt geändert von Sisamiwe; 29.04.2020, 15:41. Grund: Nachtrag

              Kommentar


                #8
                Schade. Ich hatte nur die Trockenübung mit dem item-Inhalt gemacht, den Du gepostet hattest. Deinem Nachtrag zu urteilen kommt das item schon mit den richtigen Anführungszeichen in der Visu an. Um ganz sicher zu gehen, kannst Du in mywidget.js statt der JSON.parse()-Zeile eine Meldung ausgeben:
                Code:
                alert ('Übergabe: '+ response[0] +' wird zu: '+ txt );
                Nächster Schritt: Ich frage mich auch, ob es nicht heißen müsste
                Code:
                txt = response[0].toString().replace(/\'/g, '"');
                Das alert()-Statement hilft Dir, herauszufinden, was passiert, wenn Du das änderst.

                Dritter Schritt: Du kannst die Übergabe als String erzwingen, wenn Du im html-Teil das Item mit "implode" übergibst:
                Code:
                ... data-item=" {{ implode(item) }}" ...
                Ich muss gestehen, dass ich hier auch erst am Lernen bin. Aber wenn wir erstmal wissen, in welcher Form das Item im Widget ankommt, dann bekommen wir den Rest sicher hin.

                Kommentar


                  #9
                  wvhn
                  Ich mach mich ran und geben Updates. ;o)

                  Kommentar


                    #10
                    wvhn

                    So habe mal etwas rumprobiert. Dazu habe ich versucht, über
                    Zitat von wvhn Beitrag anzeigen
                    alert ('Übergabe: '+ response[0] +' wird zu: '+ txt );
                    oder auch
                    Code:
                    console.log ("mywidget JS response: " + response);
                    oder auch
                    Code:
                    {{ basic.print ('', 'heizung.warmwasser.schaltzeiten.sonntag', '') }}
                    den übergebenen Inhalt des Items zu analysieren.

                    Das Ergebnis ist immer:
                    Code:
                    mywidget JS response: [object Object],[object Object],[object Object],[object Object]
                    (hier aus der Console.

                    Da stimmt doch was nicht. Der Item Inhalt kommt schon nicht an.

                    Kommentar


                      #11
                      https://stackoverflow.com/questions/...ascript-object

                      Kommentar


                        #12
                        Zitat von Onkelandy Beitrag anzeigen
                        https://stackoverflow.com/questions/...ascript-object
                        Danke.

                        D.h., dass ich mit
                        Code:
                        _update: function(response) {
                                str = JSON.stringify(response);
                                console.log ("mywidget JS response: " + str);
                        in der Browserkonsole den genauen Inhalt von response sehen kann, also auch den Syntax?

                        Kommentar


                          #13
                          Die Ausgabe
                          Code:
                          [object Object],[object Object],[object Object],[object Object]
                          zeigt doch, dass das item im js-widget schon als Array von Objekten vorliegt. Hast Du schon mal versucht, dies entsprechend anzusprechen?
                          Code:
                          var obj = response[0];
                          alert ('erste Einschaltzeit: ' + obj[0].An + ' erste Ausschaltzeit: '+ obj[0].Aus);
                          Es ist etwas schwer und langwierig, die Lösung per Ferndiagnose zu finden. Kannst Du mir das Plugin evtl. in reduzierter Form schicken? Ich brauche nur einen originalgetreuen Datensatz eines Items, den ich dann von shNG an die Visu schicken kann.

                          Kommentar


                            #14
                            Hallo,

                            ich habe sowas in der Art für den Indego-Rasenmäher gemacht.
                            Das Plugin ist noch nicht public da Bosch über den Winter die API geändert hat und ich einiges ändern muss.
                            Die Quellen dazu kann man auf meinem Git finden. Das ganze gibt es auch anders herum
                            (Ein / Aus - Zeiten in grün) funktioniert aber aus oben genannten Gründen gerade nicht
                            In der "widget_indego.html" wäre das passende Makro "mow_calendar"
                            In der indgo.js wäre es dann der Eintrag "Widget for active Calendar". Die Struktur der Daten ist ähnlich.

                            Code:
                            {'Params': {'CalCount': [1]}, '1-00:00-23:59': {'Key': '1-00:00-23:59', 'Start': '00:00', 'End': '23:59', 'Days': '6'}, '1-00:00-08:00': {'Key': '1-00:00-08:00', 'Start': '00:00', 'End': '08:00', 'Days': '0,1,2,3,4,5'}, '1-22:00-23:59': {'Key': '1-22:00-23:59', 'Start': '22:00', 'End': '23:59', 'Days': '0,1,2,3,4,5'}}
                            Die Zeiten sind über ein Popup editierbar und werden an shNG übertragen.
                            Vielleicht hilft es hier weiterzukommen. In den Dateien kann man vielleicht auch die Zusammenhänge von js/html
                            rauslesen.
                            Ich bin immer noch mit dem neuen Setup meiner Dev-Umgebung beschäftigt.
                            Wenn das dann alles wieder läuft kann ich hier vielleicht noch was beitragen.

                            Gruss Andre

                            Sieht dann so aus( thanks to schuma for help to the optic):
                            Indego_Kalender.jpg

                            Kommentar


                              #15
                              Cool. Vielleicht kann ich daraus ein allgemein verwendbares Widget für die Erstellung von Tabellen machen. Das ist sogar noch ein älteres Issue auf github.

                              Leider gibt es keinerlei Entwicklerdoku. Deshalb muss man sich all diese Fragen neu erarbeiten. Ich habe über die letzten Wochen alles, was ich an grundsätzlichen Erklärungen im Forum und auf github gefunden habe, mangels besserer Alternative erstmal ins Wiki auf github gepackt. Das sind aber bisher nur Infoschnipsel. Wer sein Wissen teilen möchte, kann das dort sehr gerne in loser Form ergänzen.

                              Gruß
                              Wolfram

                              Kommentar

                              Lädt...
                              X