FW_pH für XHR?

Begonnen von Talkabout, 11 Juni 2015, 20:17:13

Vorheriges Thema - Nächstes Thema

Talkabout

Hallo zusammen,

ich habe gesehen, dass es in 01_FHEMWEB.pm eine Funktion gibt, um Links zusammen zu bauen: "FW_pH". Diese wird häufig verwendet, um Links für das Frontend zu generieren. Leider wird sie ebenfalls für Device-Commands aufgerufen, was sehr unschön ist, da damit die komplette Seite neu geladen wird, wenn das Kommando abgeschickt wird. Der Link hat dann die folgende Form:

<a onClick="location.href='/fhem/?cmd.XXX=set XXX XXX&...'>XXX</a>

Dabei besitzt FHEM ja bereits JavaScript-Funktionen um solche Commandos auch per AJAX (asynchron) abzuschicken: FW_cmd

Ich habe in der 01_FHEMWEB.pm aber keine Funktion gefunden, die mir einen solchen asynchronen Aufruf zusammen baut, der so aussehen muss:

<a onClick="FW_cmd('/fhem/?cmd.XXX=set XXX XXX&..&XHR=1.')">XXX</a>

Ich habe mir im Dashboard-Modul diesen Link "per Hand" zusammen gebaut und erreiche damit eine wesentlich flüssigere Navigation. Meine Frage wäre nun, ob es anderweitig die Möglichkeit gibt, sich einen solchen Link zusammen bauen zu lassen. Wenn nicht, spricht etwas dagegen, etwas in der Art in 01_FHEMWEB.pm aufzunehmen:

sub
FW_pHXHR(@)
{
  my ($link, $txt, $td, $class, $doRet,$nonl) = @_;
  my $ret;

  $link = ($link =~ m,^/,) ? "$link$FW_CSRF" : "$FW_ME$FW_subdir?$link$FW_CSRF";
 
  $ret = "<a onClick=\"FW_cmd('$link');\">$txt</a>";

  #actually 'div' should be removed if no class is defined
  #  as I can't check all code for consistancy I add nonl instead
  $class = ($class)?" class=\"$class\"":"";
  $ret = "<div$class>$ret</div>" if (!$nonl);

  $ret = "<td>$ret</td>" if($td);
  return $ret if($doRet);
  FW_pO $ret;
}


äquivalent zu der "FW_pH"?

Ich denke in der heutigen Zeit sollte man auf ein Neu-Laden von Webseiten verzichten wo immer es geht. Und wenn FHEM solche Möglichkeiten bietet, sollte man diese auch zur Verfügung stellen.

Danke!

Gruss

justme1968

#1
all diese links werden nach dem seitenaufbau durch FW_replaceLink in fhemweb.js zu XHR links umgebaut.

kann es sein das das aus irgendeinem grund beim dashboard nicht (oder nicht richtig) passiert ?

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Talkabout

Zitat von: justme1968 am 11 Juni 2015, 20:23:47
all diese links werden nach dem seitenaufbau durch FW_replaceLink in fhemweb.js zu XHR links umgebaut.

kann es sein das das aus irgendeinem grund beim dashboard nicht (oder nicht richtig) passiert ?

gruss
  andre
Der Hinweis ist super, werde das prüfen.

Danke!

Talkabout

Hallo justme1968

das Problem ist diese Stelle in der 01_FHEMWEB.pm (FW_pH)

if($FW_ss || $FW_tp) {
    $ret = "<a onClick=\"location.href='$link'\">$txt</a>";
  } else {
    $ret = "<a href=\"$link\">$txt</a>";
  }

sobald er hier in den Block mit dem "onClick" rein läuft (was bei mir passiert), kann er es Client-seitig nicht mehr ersetzen, da das Kommando nicht mehr im "href"-Attribut steht. Die Ersetzung im "onclick"-Attribut würde ich nicht machen wollen, da sich Browser dabei zu unterschiedlich verhalten. Ich finde diese Ersetzung auf Client-Seite auch nicht ganz so optimal, da dies natürlich die Arbeit am Client doch erheblich steigert, vor allem bei grossen Seiten.

Ich würde daher gerne meinen Vorschlag aus dem ersten Post aufgreifen, und diese Funktion integrieren. Damit wäre es einerseits nicht mehr nötig, so viel auf Client-Seite zu ersetzen, andererseits würde man sich Probleme, wie ich sie aktuell habe, damit ersparen.

Was haltet Ihr davon?

Gruss

Talkabout

Hallo zusammen,

es gäbe vielleicht noch eine Alternative. Da die Funktionalität zum Ersetzen ja eh global ist, könnte man diese auch direkt in die "FW_pH" einbauen. Im Falle, dass als Link ein Kommando übergeben wurde, würde man direkt dort die Ersetzung durch "FW_cmd" machen.

Im 1. Vorschlag wäre die Rückwärtskompatibilität der Methode gegeben, im 2. Fall wäre diese zwar weg, aber vielleicht braucht es die auch nicht.

Gruss

justme1968

einer der gründe warum rudi es auf der js seite eingebaut hat war das nicht alle module FW_pH verwenden und mit der implementierung auf client seite auch diese module mit recht kleinem aufwand umgestellt werden konnten.

da es immer noch scheinbar recht viele fhem installationen gibt bei denen der client sehr viel performanter ist als der server war es kein problem das im client zu machen.

ein anderer grund war das es das argument gab das alles auch ohne javascript und longpoll laufen sollte. dafür sollte dann ohne konfiguration automatisch auf das alte verhalten mit reload zurückgefallen werden.

das erste argument ist immer noch wichtig und erlaubt es eigentlich nicht auf die ersetzung per js zu verzichten. das man aber zumindest alles was durch FW_pH läuft schon auf server seite direkt mit einem XHR link ausliefert kann ich mir gut vorstellen.

ich weiss nicht wie weit das zweite argument noch gilt.

zu beidem muss aber rudi etwas sagen.

gruss
  andre
hue, tradfri, alexa-fhem, homebridge-fhem, LightScene, readingsGroup, ...

https://github.com/sponsors/justme-1968

Talkabout

Hallo zusammen,

aus meiner Erfahrung (und davon habe ich recht viel) im Bereich der Webentwicklung, ist es heute eigentlich nicht mehr state-of-the-art in einer Web-Applikation auf href zu setzen. Trotzdem kenne ich die verschiedenen Anwendungsgebiete von FHEM nicht und weiss daher nicht, ob eine komplette Ersetzung ohne Rückwärtskompatibilität sinnvoll ist.

Wenn es nicht global geht kann ich mir Gedanken machen, wie wir die Ersetzung für die "onClick"-Attribute hinkriegen.

Gruss

Talkabout

Hallo zusammen,

hier nun ein Vorschlag aus der Praxis. Diese Funktion würde so für das Dashboard und andere Module funktionieren:

#################
# async command link
sub
FW_pC(@)
{
  my ($link, $txt, $td, $class, $doRet,$nonl) = @_;
  my $ret;

  $link = ($link =~ m,^/,) ? "$link$FW_CSRF" : "$FW_ME$FW_subdir?$link$FW_CSRF";

  $ret = "<a onclick=\"FW_cmd('$link&XHR=1');\">$txt</a>";

  #actually 'div' should be removed if no class is defined
  #  as I can't check all code for consistancy I add nonl instead
  $class = ($class)?" class=\"$class\"":"";
  $ret = "<div$class>$ret</div>" if (!$nonl);

  $ret = "<td>$ret</td>" if($td);
  return $ret if($doRet);
  FW_pO $ret;
}


Beim Namen bin ich mir noch unschlüssig, da ich noch nicht ganz hinter das Muster gestiegen bin. Ich vermute bei "FW_pH" steht das "H" für Hyperlink, daher würde bei meinem Vorschlag das "C" für Command stehen. Bin aber für Vorschläge offen.

Gruss

rudolfkoenig

Die Umwandlung der html-Links zu FW_cmd Aufrufen war fuer die Tablet/smallscreen Version nicht implementiert, das ist ein Bug, was ich gerade gefixt habe. Falls das hier gezeigte FW_pC trotzdem noetig sein sollte, dann bitte Bescheid geben.

Die von andre erwaehnten Argumente teile ich auch.

Talkabout

Zitat von: rudolfkoenig am 12 Juni 2015, 19:10:48
Die Umwandlung der html-Links zu FW_cmd Aufrufen war fuer die Tablet/smallscreen Version nicht implementiert, das ist ein Bug, was ich gerade gefixt habe. Falls das hier gezeigte FW_pC trotzdem noetig sein sollte, dann bitte Bescheid geben.

Die von andre erwaehnten Argumente teile ich auch.
Hallo Rudi,

der Fix funktioniert, danke Dir!

Gruss