Hauptmenü

Framework7 + FTUI

Begonnen von Standarduser, 02 Juli 2017, 16:31:08

Vorheriges Thema - Nächstes Thema

Standarduser

Hallo zusammen,
hallo setstate,

es gab ja hier im Forum schon an der einen oder anderen Stelle Ansätze, wie FTUI mit Framework7 kombiniert werden kann. Aber so richtig viel verwertbares konnte ich nicht finden.
Ich habe mich jetzt auch mal an der Umsetzung versucht und eine kleine Inkompatibilität gefunden.

Eine in fhem-tablet-ui.js verwendete Funktion verursacht einen schwarzen Bildschirm, nachdem alles gerendert wurde.
// -------- Framework7---------
// https://framework7.io/docs/

if (typeof Framework7 === 'function') {
    var f7 = {
        ftui: new Framework7({
            animateNavBackIcon: true
        }),
        options: {
            dynamicNavbar: true,
            domCache: true
        },
        views: []
    };
    Dom7('.view').each(function (index) {
        var view = f7.ftui.addView('#' + Dom7(this)[0].id, {
            dynamicNavbar: true

        });
        f7.ftui.views.push(view);
    });
    f7.ftui.onPageInit('*', function (page) {
        ftui.log(1,page.name + ' initialized');
        ftui.initWidgets('[data-page="' + page.name + '"]');
    });
}


Für den moment hat es geholfen, folgenden Teil auszukommentieren:
/*
    Dom7('.view').each(function (index) {
        var view = f7.ftui.addView('#' + Dom7(this)[0].id, {
            dynamicNavbar: true
        });
        f7.ftui.views.push(view);

    });
*/


Gibt es eine bessere Möglichkeit, beides gemeinsam laufen zu lassen, als diesen Code auszukommentieren?

setstate

So sieht mein Header für eine F7 Seite aus


<head>
    <!-- FTUI with Framework7 Demo (draft) 2016 by Mario Stephan
        ftui:  https://github.com/knowthelist/fhem-tablet-ui
        f7:    https://github.com/nolimits4web/Framework7
        docs:  http://idangero.us/framework7/docs/

        this demo page is still under construction

    -->

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">

    <meta name="longpoll" content="1">
    <!-- 1=longpoll;0=shortpoll every 30sec -->
    <meta name="debug" content="1">
    <!-- verbose level 1-6 = output to console;0 = not output -->

    <title>FTUI-F7</title>

    <link rel="stylesheet" href="lib/framework7/framework7.ios.min.css">
    <link rel="stylesheet" href="lib/framework7/framework7.ios.colors.min.css">
    <link rel="stylesheet" href="css/fhem-tablet-ui-f7.css" />

    <script src="lib/framework7/framework7.min.js" defer></script>
    <script src="js/fhem-tablet-ui.js" defer></script>
    <!--script src="js/my-app.js" defer></script-->
   

</head>

Standarduser

Hast Du eigentlich etwas spezielles in der fhem-tablet-ui-f7.css stehen?
Und würdest Du die mit uns teilen?

setstate

#3
Klar mach ich.
Ich bin aber noch nicht weit damit :-(
Hier der Stand

Standarduser

Sehr cool.
Ich hänge auch mal einen ersten Screenshot an.
Gibt noch viel zu tun...

Standarduser

#5
Ich kämpfe gerade damit, dass die Widgets Slider und Medialist überhaupt nicht funktionieren.

Beim Slider-Widget hab ich den Grund schon gefunden:
Es liegt an der Klasse "tab", die vom Slider genau wie von f7 verwendet wird. Nur dass f7 sie auf "display:none" setzt.
Im Moment kann ich gut darauf verzichten, aber wäre es möglich, da noch eine zweite Klasse mit gleicher Funktion aber anderem Namen einzubauen?

//Edit: Scheint so, als hätte Medialist ein Problem damit, wenn man es auf einer Unterseite einbindet. Wenn es in der index.html definiert wird, funktioniert alles, auf beliebigen anderen Seiten scheint das Widget den nötigen Code nicht zu generieren. Das hier kommt dabei heraus:


<div class="page-content">
<!-- Medialist -->
<div data-type="medialist" data-device="DG.ku.MM.Squeezebox" data-set="track" data-get="ftuiMedialist" data-pos="playlistCurrentTrack" data-height="85%" data-width="95%" class="autoscroll index1 centered">
</div>
</div>

Standarduser

Ich bin wieder ein Stück weiter gekommen.

Die neuesten Erkenntnisse:
Auf der Hauptseite funktionieren alle Widgets, auf Unterseiten nicht. Das liegt daran, dass Unterseiten per Ajax geparst werden und so standardmäßig keine Scripte ausgeführt werden.
Also hab ich die Funktion für das Initialisieren der Seiten in der my-app.js wie folgt angepasst:

$$(document).on('pageInit', function(e) {
var page = e.detail.page;

$$(page.container).find("script").each(function(el) {
if ($(this).attr('src')) {
jQuery.getScript($(this).attr('src'));
}
else {
eval($(this).text());
}
});
});


Damit werden auf Unterseiten eingebundene Scripte beim Aufruf der Seite ausgeführt.
Zusätzlich habe ich meine Unterseite, die die Medialist enthält, um einen erneuten Aufruf von fhem-tablet-ui.js erweitert, sodass sie im Moment wie folgt aussieht:


<!-- Navigationsleiste oben -->
<div class="navbar">
<div class="navbar-inner">
<div class="left"><a href="#" class="back link"><i class="icon icon-back"></i><span>Zurück</span></a></div>
<div class="center sliding">aktuelle Wiedergabeliste</div>
<div class="right"><a href="#" class="link icon-only"><i class="icon demo-icon"></i></a></div>
</div>
</div>

<div data-page="mplayer_ku_playlist" class="page navbar-fixed">
<div class="page-content">
<!-- Medialist -->
<div data-type="medialist"
data-device="DG.ku.MM.Squeezebox"
data-set="track"
data-get="ftuiMedialist"
data-pos="playlistCurrentTrack"
data-height="85%"
data-width="95%"
class="autoscroll index1 centered media-list">
</div>
</div>
<script type="text/javascript" src="js/fhem-tablet-ui.js" defer></script>
</div>


Beim Aufruf der Unterseite wird nun die Medialist erzeugt.
Der erneute Aufruf hat nun jedoch auch Auswirkungen auf die ursprüngliche Seite. Da bewirkt der Aufruf nun, dass das Cover doppelt generiert und ausgeblendet wird.

Der ursprünglich generierte Code für das Coverbild nach dem Laden der Seite sieht so aus:

<div data-type="image" data-device="DG.ku.MM.Squeezebox" data-get="coverarturl" data-size="100%" data-opacity="1" class="middle nocache"><img alt="img" src="http://www.mysqueezebox.com/public/imageproxy?u=https%3A%2F%2Fi.scdn.co%2Fimage%2F65ddbfe0908400f797bb2c90d619ebf3594e42fd&amp;h=700&amp;w=700" style="opacity: 1; height: auto; width: 100%; max-width: 100%;"></div>

In dem Moment, wo ich die Unterseite aufrufe und fhem-tablet-ui.js erneut geladen wird, wird daraus das hier:

<div data-type="image" data-device="DG.ku.MM.Squeezebox" data-get="coverarturl" data-size="100%" data-opacity="1" class="middle nocache" style="display: none;"><img alt="img" src="http://www.mysqueezebox.com/public/imageproxy?u=https%3A%2F%2Fi.scdn.co%2Fimage%2F65ddbfe0908400f797bb2c90d619ebf3594e42fd&amp;h=700&amp;w=700" style="opacity: 1; height: auto; width: 100%; max-width: 100%;"><img alt="img" src="http://www.mysqueezebox.com/public/imageproxy?u=https%3A%2F%2Fi.scdn.co%2Fimage%2F65ddbfe0908400f797bb2c90d619ebf3594e42fd&amp;h=700&amp;w=700" style="opacity: 1; height: auto; width: 100%; max-width: 100%;"></div>

Gehe ich nun auf die vorherige Seite zurück, ist das Cover (und einige andere Steuerelemente) weg.
Siehe angehängte Bilder.

Das Problem ist mir jetzt klar. Aber wie ich das lösen soll ... keine Ahnung

setstate

Die ganze fhem-tablet-ui.js muss nicht neu geladen werden. Es reicht, wenn man ftui.initWidgets(<selector>) ruft.
Das habe ich aber schon in der  fhem-tablet-ui.js so eingebaut

    f7.ftui.onPageInit('*', function (page) {
        ftui.log(1,page.name + ' initialized');
        ftui.initWidgets('[data-page="' + page.name + '"]');
    });


Dafür muss die Unterseite ein data-page Attribute haben


<div data-page="abouty" class="page">
...


Dieser Teil wird dann Widget-technisch initialisiert.

Standarduser

Könntest Du bitte nochmal etwas ins Detail gehen?

Ich hab jetzt den Script-Aufruf von der Unterseite entfernt und in my-app.js folgendes eingebaut:

myApp.onPageInit('mplayer_ku_playlist', function (page) {
ftui.initWidgets('[data-page="mplayer_ku_playlist"]');
});


Jetzt kommt die Playlist auf der Unterseite, aber nach 1x hin und her sieht die Ursprungsseite wieder komisch aus.

Standarduser

#9
Ich hab jetzt nochmal alle möglichen Kombinationen ausprobiert, die mir in den Sinn gekommen sind. Aber im Ergebnis ändert sich nichts.
Ich fasse mal zusammen:

Ich verwende folgenden Header:
<head>
<meta charset="utf-8">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />

<link rel="stylesheet" href="css/framework7.ios.min.css" />
<link rel="stylesheet" href="css/framework7.ios.colors.min.css" />
<link rel="stylesheet" href="css/my-app.css" />

<link rel="stylesheet" href="css/fhem-tablet-ui-f7.css" />
<link rel="stylesheet" href="styles_colors-ui.css" />

<script src="js/framework7.min.js" defer></script>
<script src="js/fhem-tablet-ui.js" defer></script>
<script src="js/my-app.js" defer></script>

<title>Home</title>
</head>


Wenn ich, wie im ersten Post erwähnt, den Code in fhem-tablet-ui.js nicht auskommentiere, kommt der Fehler
[Error] TypeError: undefined is not an object (evaluating 'l[0].f7View=o')
o (framework7.min.js:16:8345)
addView (framework7.min.js:16:19457)
(anonyme Funktion) (fhem-tablet-ui.js:33)
each (framework7.min.js:15:22542)
Globaler Code (fhem-tablet-ui.js:32)


Im Ergebnis funktioniert kein einziges FTUI-Widget.
Also sieht meine fhem-tablet-ui.js im Moment so aus:

...
// global Framework7:true, jQuery:true

"use strict";


// -------- Framework7---------
// https://framework7.io/docs/

if (typeof Framework7 === 'function') {
    var f7 = {
        ftui: new Framework7({
            animateNavBackIcon: true
        }),
        options: {
            dynamicNavbar: true,
            domCache: true
        },
        views: []
    };

/*
    Dom7('.view').each(function (index) {
        var view = f7.ftui.addView('#' + Dom7(this)[0].id, {
            dynamicNavbar: true
        });
        f7.ftui.views.push(view);

    });
*/

    f7.ftui.onPageInit('*', function (page) {
        ftui.log(1,page.name + ' initialized');
        ftui.initWidgets('[data-page="' + page.name + '"]');
    });
}
...

Ich hatte auch mal zum Spaß // global Framework7:true, jQuery:true wieder einkommentiert. Aber da kommt nur ein anderer Fehler

In der my-app.js steht folgender Code:

// Initialize app and store it to myApp variable for futher access to its methods
// See https://framework7.io/docs/init-app.html
var myApp = new Framework7({
sortable: 'false', // If you don't use sortable lists you can disable it for potentially better performance.
//panelLeftBreakpoint: '1000', // Minimal app width when left panel becomes always visible
swipePanel: 'left', // If you want to enable ability to open side panels with swipe you can pass here "left" (for left panel) or "right" (for right panel) or "both" (for both panels).
scrollTopOnStatusbarClick: 'true', // Set to true and each click on Status bar ("status-bar-overlay") will scroll currently active page to top
hideNavbarOnPageScroll: 'true', // Set to true and Navbar will be hidden automatically on page scroll down, and become visible on scroll up
hideToolbarOnPageScroll: 'true', // Set to true and Toolbar will be hidden automatically on page scroll down, and become visible on scroll up
hideTabbarOnPageScroll: 'true', // Set to true and Tab bar will be hidden automatically on page scroll down, and become visible on scroll up. Note that this is only for Tab Bar app layout, otherwise use hideToolbarOnPageScroll
showBarsOnPageScrollEnd: 'false', // Set to true to show hidden Navbar and Toolbar when scrolling reaches end of the page
showBarsOnPageScrollTop: 'false', // Set to false and bars will not become visible when you scroll page to top everytime. They will become visible only on the most top scroll position, in the beginning of the page
scrollTopOnNavbarClick: 'false', // Set to true and each click on Navbar's "center" element will scroll currently active page to top
});

// We need to use custom DOM library, let's save it to $$ variable:
var $$ = Dom7;

// Add view
var mainView = myApp.addView('.view-main', {
// Because we want to use dynamic navbar, we need to enable it for this view:
dynamicNavbar: true
});

$$(document).on('pageInit', function(e) {
var page = e.detail.page;

ftui.initWidgets('[data-page="' + page.name + '"]');
});


Du hattest geschrieben, dass ftui.initWidgets... bereits in FTUI eingebaut ist. Hab ich auch gesehen, aber ohne eine weiteren expliziten Aufruf funktioniert es bei mir nicht. Die Widgets auf den Unterseiten werden dann nicht initialisiert.
Die Subpage besitzt die Seitendefinition <div data-page="..." class="page ...">, nun jedoch keinen eigenen Script-Aufruf mehr.

So, wie es jetzt ist, funktionieren alle Widgets auf der Hauptseite. Beim Aufruf von Unterseiten funktionieren diese auch, allerdings gibt es nach dem Aufruf der Unterseite Probleme mit den Widgets auf der Hauptseite.

Was ich auch probiert habe:
my-app.js komplett weglassen, fhem-tablet-ui.js wieder in Ursprungszustand versetzt. Funktioniert trotzdem nicht.

Framework7 ist bei mir Version 1.6.4, FTUI letzter Stand.

Standarduser

Hi setstate,

ich hänge immer noch an der gleichen Stelle.
Könntest Du mir mal Dein komplettes Projekt anhängen, damit ich mal vergleichen kann, wo die unterschiede sind und warum es bei Dir scheinbar läuft, bei mir jedoch nicht?

setstate

Wie gesagt: ich habe da noch nicht viel gemacht. Nur diese eine Seite mit einer einfachen Sub-Page für View-1. Alle anderen Views sind direkt in der Main-Page dabei.

fhem-tablet-ui-f7.css: wie oben
fhem-tablet-ui.js: Standard (wie in Github)
f7_main.html und f7_sub_mates.html: anbei

Standarduser

#12
Interessant ist, dass es bei Deinen Dateien scheinbar problemlos und auf Anhieb funktioniert. Ich werde mal den Aufbau der Dateien analysieren.

Nach weiteren Versuchen stelle ich fest, dass es wohl ein grundsätzliches Problem zu geben scheint, denn es treten die gleiche Effekte auf.

Ich habe Dein Layout genommen und direkt über <div class="content-block-title">Übersicht</div> im view-1 folgenden Block eingebaut:

<div class="center top-space-10px">
<div data-type="push"   class="inline" data-device="DG.ku.MM.Squeezebox" data-icon="fa-step-backward" data-on-color="mplayer-on" data-off-color="mplayer-off" data-set-on="prev" data-background-icon="-"></div>
<div data-type="switch" class="inline" data-device="DG.ku.MM.Squeezebox" data-get-off="!on" data-set-off="" data-get="playStatus" data-get-on="playing" data-set-on="play"  data-icon="fa-play"  data-background-icon="-" data-on-color="mplayer-on" data-off-color="mplayer-off"></div>
<div data-type="switch" class="inline" data-device="DG.ku.MM.Squeezebox" data-get-off="!on" data-set-off="" data-get="playStatus" data-get-on="paused"  data-set-on="pause" data-icon="fa-pause" data-background-icon="-" data-on-color="mplayer-on" data-off-color="mplayer-off"></div>
<div data-type="push"   class="inline" data-device="DG.ku.MM.Squeezebox" data-icon="fa-step-forward"  data-on-color="mplayer-on" data-off-color="mplayer-off" data-set-on="next" data-background-icon="-"></div>
</div>


Wenn ich dann die Seite für Anwesenheit (f7_sub_mates.html) aufrufe und zurückkehre, sind meine Buttons wieder weg. So sieht dann der Code aus:

<div class="center top-space-10px">
<div data-type="push" class="inline" data-device="DG.ku.MM.Squeezebox" data-icon="fa-step-backward" data-on-color="mplayer-on" data-off-color="mplayer-off" data-set-on="prev" data-background-icon="-" style="display: none;"><div class="famultibutton fa-stack fa-2x"><i id="bg" class="fa fa-stack-2x -" style="color: rgb(80, 80, 80);"></i><i id="fg" class="fa fa-stack-1x fa-step-backward"></i><div class="famultibutton fa-stack fa-2x fa-stack-1x" id="fg"><i id="bg" class="fa fa-stack-2x -" style="color: rgb(80, 80, 80);"></i><i id="fg" class="fa fa-stack-1x fa-step-backward"></i><div id="fg" class="fa-stack-1x"></div></div></div></div>
<div data-type="switch" class="inline" data-device="DG.ku.MM.Squeezebox" data-get-off="!on" data-set-off="" data-get="playStatus" data-get-on="playing" data-set-on="play" data-icon="fa-play" data-background-icon="-" data-on-color="mplayer-on" data-off-color="mplayer-off" style="display: none;"><div class="famultibutton fa-stack fa-2x"><i id="bg" class="fa fa-stack-2x -" style="color: rgb(80, 80, 80);"></i><i id="fg" class="fa fa-stack-1x fa-play"></i><div class="famultibutton fa-stack fa-2x fa-stack-1x" id="fg"><i id="bg" class="fa fa-stack-2x -" style="color: rgb(80, 80, 80);"></i><i id="fg" class="fa fa-stack-1x fa-play"></i><div id="fg" class="fa-stack-1x"></div></div></div></div>
<div data-type="switch" class="inline" data-device="DG.ku.MM.Squeezebox" data-get-off="!on" data-set-off="" data-get="playStatus" data-get-on="paused" data-set-on="pause" data-icon="fa-pause" data-background-icon="-" data-on-color="mplayer-on" data-off-color="mplayer-off" style="display: none;"><div class="famultibutton fa-stack fa-2x"><i id="bg" class="fa fa-stack-2x -" style="color: rgb(80, 80, 80);"></i><i id="fg" class="fa fa-stack-1x fa-pause"></i><div class="famultibutton fa-stack fa-2x fa-stack-1x" id="fg"><i id="bg" class="fa fa-stack-2x -" style="color: rgb(80, 80, 80);"></i><i id="fg" class="fa fa-stack-1x fa-pause"></i><div id="fg" class="fa-stack-1x"></div></div></div></div>
<div data-type="push" class="inline" data-device="DG.ku.MM.Squeezebox" data-icon="fa-step-forward" data-on-color="mplayer-on" data-off-color="mplayer-off" data-set-on="next" data-background-icon="-" style="display: none;"><div class="famultibutton fa-stack fa-2x"><i id="bg" class="fa fa-stack-2x -" style="color: rgb(80, 80, 80);"></i><i id="fg" class="fa fa-stack-1x fa-step-forward"></i><div class="famultibutton fa-stack fa-2x fa-stack-1x" id="fg"><i id="bg" class="fa fa-stack-2x -" style="color: rgb(80, 80, 80);"></i><i id="fg" class="fa fa-stack-1x fa-step-forward"></i><div id="fg" class="fa-stack-1x"></div></div></div></div>
</div>


Man beachte, dass hier scheinbar die Push- und Switch-Widgets ein zweites mal erzeugt und jedes Widget per display: none; ausgeblendet wird.

---

Der Code in der fhem-tablet-ui.js, den ich bei meiner Variante auskommentieren musste, scheint damit garnichts zu tun zu haben. Ich vermute dass es daher kommt, dass ich meinen Seitenaufbau ganz anders gestaltet habe. Du hast für jeden Tab-Link in in der Tab-Bar ein view/page erzeugt, während ich nur ein view/page habe und stattdessen mit dem Tab-Wrapper gearbeitet habe.

Also zwei getrennte Dinge.

takaze

Ich hab mich in letzter Zeit auch mal verstärkt mit der Thematik F7 + FTUI beschäftigt.
Die kleine Starthilfe weiter oben von setstate hat mir dabei wirklich sehr geholfen, Danke schonmal dafür :)

Allerdings bin ich auch recht schnell auf ein Problem gestoßen, welches ich aufgrund mangelnder coding Skills offenbar nicht lösen kann  ::)

Ausgehend von den Dateien, die setstate bereitgestellt, habe ich einfach ein symbol-widget auf die erste seite hinzugefügt. Wird jetzt die Subpage aufgerufen und anschließend wieder verlassen, wird offenbar das Widget erneut erstellt (?). Das würde sich mit dem Fehlerbild von Standarduser decken, allerdings denke ich, dass hier die Widgets "verschwinden", da einfach nicht genug platz ist und diese somit von der Seite rutschen. Da in meinem Fall genug Platz ist, wird das neue einfach darüber erstellt. Ist so aber glaube ich auch nicht im Sinne des Erfinders :P

Gibt es den mittlerweile jemanden der sich schon näher mit der Sache beschäftigt hat?

Grüße,
Florian
RPi 3B, Add-On Board mit 1.8" TFT LCD, FHEM V5.8, CULFW v1.65 RPIAddOn_CSM, Jeelink v3, Selbstbau CUL433 MHz (signalduino), z-Wave (Fibaro), 8'' WIN10 Wand-Infoboard mit FTUI

setstate

Sowas habe ich noch garnicht ausprobiert, Symbol Widget einzusetzen. Mein Ziel war es, nur die F7 Controls zu benutzen und mit dem data-type="html" zu beeinflussen.

Im jetzigen Stand wird nicht nur die Subpage initiiert, sondern durch einen falschen Filter die ganze Seite neu. Dadurch zerhaut es die Symbol-Widgets so.

Abhilfe schafft die Korrektur des Context-Selectors beim initWidgets

them-tablet-ui.js Zeile 40 muss so geändert werden:

ftui.initWidgets('.page[data-page="' + page.name + '"]');