Meowsalot: Tabelle aktualisieren sobald ein neuer Eintrag vorhanden ist?

Guten Morgen,

ich möchte gerne erreichen wenn ein User ein neuer Eintrag hinterlassen dass ich dieses automatisch angezeigt bekomme auch wenn ich die Seite nicht aktualisiere. Ist dieses möglich?

Mein Aufbau

<table class="table table-hover">
  <thead>
    <tr>
      <th scope="col">Erstellt am</th>
      <th scope="col">Thema</th>
      <th scope="col">B. Sender</th>
      <th scope="col">Sender</th>
      <th scope="col">B. Empf.</th>
      <th scope="col">Empf.</th>
      <th scope="col">Job</th>
      <th scope="col">Art</th>
      <th scope="col">Prio</th>
      <th scope="col">Status</th>
    </tr>
  </thead>
  <tbody>
     <?php $ToDoUebersicht = ToDo($mysqli);
     foreach($ToDoUebersicht as $array){ 

        $Z1 = getAmounttodoNachricht($mysqli, $array['code']);

        $array1 = explode("-",$array['erstellungsdatum']);
        $tag    = $array1[2];
        $monat  = $array1[1];
        $jahr   = $array1[0];

        $Erstellt = $tag.".".$monat.".".$jahr;
     ?>
    <tr>
      <td><?php echo htmlspecialchars($Erstellt) ?></td>
      <td>
      <?php if ($Z1 != 0): ?><span class="fa fa-comments"></span><?php endif ?>
      <a style="color: black" href="todo.php?code=<?php echo htmlspecialchars($array['code']) ?>"><?php echo htmlspecialchars($array['kurzbeschreibung']) ?></a></td>
      <td><?php echo htmlspecialchars($array['Sender']) ?></td>
      <td><?php echo htmlspecialchars($array['apSender']) ?></td>
      <td><?php echo htmlspecialchars($array['Empfaenger']) ?></td>
      <td><?php echo htmlspecialchars($array['apEmpfaenger']) ?></td>
      <td><?php echo htmlspecialchars($array['job']) ?></td>
      <td><?php echo htmlspecialchars($array['ta_titel']) ?></td>
      <td><?php echo htmlspecialchars($array['tp_titel']) ?></td>
      <td><?php echo htmlspecialchars($array['ts_titel']) ?></td>
    </tr>
    <?php } ?>
  </tbody>
</table>

Vielleicht könnte der neue Eintrag dann auch noch farblich gekennzeichnet werden? Wie würdet ihr dieses umsetzten?

PS: Ich habe mich hier im Forum angemeldet, deshalb jetzt auch ein Benutzername.

Bis bald! Meowsalot (Bernd)

akzeptierte Antworten

  1. Guten Morgen,

    ich möchte gerne erreichen wenn ein User ein neuer Eintrag hinterlassen dass ich dieses automatisch angezeigt bekomme auch wenn ich die Seite nicht aktualisiere. Ist dieses möglich?

    Klar. Bilde aus den Eingegebenen Daten eine Checksumme und mach bei jeder Änderung eine Gegenprüfung. Differenz entsprechend auszeichnen und ggf. auch vor dem Schließen des Tab eine Confirmation ob die Änderungen gespeichert werden sollen. Demo auf meiner Haupt~Domäne.

    MfG

    1. Hallo pl,

      Klar. Bilde aus den Eingegebenen Daten eine Checksumme und mach bei jeder Änderung eine Gegenprüfung.

      Wenn ich ehrlich bin verstehe ich dieses nicht

      Demo auf meiner Haupt~Domäne.

      Auf welcher Haupt~Domäne

      Bis bald!
      Meowsalot (Bernd)

      1. Hier ist die Demo. Sobald in einem Feld die Daten geändert und der Fokus auf ein anderes Feld geht, wird dies auf der Daten Speichern Schaltfläche ausgewiesen. Praktisch genauso wie das jede andere Desktopanwendung auch macht MfG

        1. Hallo pl,

          ich habe Bernd anders verstanden. Er möchte - um bei deinem Form-Beispiel zu bleiben - dass die Sternchen bei MIR erscheinen wenn DU was in deinem Browser einträgst.

          Oder wenn's ein Gästebuch wäre - ich schreibe 'rein, dass in Köln die Sonne scheint und drücke Speichern. Bei dir flackert dann ungefragt der Bildschirm und kannst das mit deinem (möglichen) Regen vergleichen.

          Rolf

          --
          sumpsi - posui - clusi
          1. Hallo Rolf,

            ich habe Bernd anders verstanden. Er möchte - um bei deinem Form-Beispiel zu bleiben - dass die Sternchen bei MIR erscheinen wenn DU was in deinem Browser einträgst.

            genau, ich habe eine Übersichtsseite wo alle Einträge aus der Datenbank aufgelistet werden. Wenn irgendwer ein neuen Einträge tätigt soll meine Seite, die ich gerade aufhabe automatisch aktualisiert werden. Allerdings nur die Tabelle, nicht direkt die ganze Seite.

            Oder wenn's ein Gästebuch wäre - ich schreibe 'rein, dass in Köln die Sonne scheint

            leider scheint derzeit in Köln keine Sonne, aber milde Temperaturen

            Bis bald! Meowsalot (Bernd)

          2. hi,

            ich habe Bernd anders verstanden. Er möchte - um bei deinem Form-Beispiel zu bleiben - dass die Sternchen bei MIR erscheinen wenn DU was in deinem Browser einträgst.

            Das ist ja im Prinzip dasselbe, nur daß die Anwendung auf mehrere Clients erweitert wird und die Datenspeicherung ein sog. Master übernimmt. Dazwischen liegt der Transport~Layer und der ist für den Anwender unsichtbar (transparent). Aber Du hast das ja auch schon so beschrieben.

            MfG

            1. Hallo pl,

              ja schon, aber Bernd ist nicht der Anwender, sondern der Programmierer, und deshalb ist das das Zentrum seines Interesses. Und statt einer Kommunikation mit einem zentralen Service findet er in deinem Beispiel Javascript-interne Events.

              Es sei denn, ich war zu flüchtig beim Inspizieren Deiner Seite.

              Rolf

              --
              sumpsi - posui - clusi
  2. Hallo Meowsalot,

    es gibt mehrere Mechanismen, wie man das erreichen kann. Alle setzen voraus, dass Du am Client JavaScript einsetzt und damit einen Update-Mechanismus baust, der unabhängig vom normalen Seitenupdate die neuen Einträge findet und darstellt. Einige setzen auch voraus, dass Du deinen Server anders baust als gewohnt und sind nicht bei jedem Hoster möglich.

    1. Polling.

    Wenn Du die Seite regulär sendest, schickst Du eine JavaScript-Zeile mit, die einen "letzter Stand" Marker setzt. Zum Beispiel der Timestamp des neuesten Eintrags, oder die ID (sofern Du aufsteigende IDs vergibst). Per JavaScript erzeugst Du einen Intervalltimer, der per Ajax den Server fragt, ob es was neues gibt. Dabei wird der eben genannte Marker als Parameter übergeben, das per Ajax aufgerufene PHP Script bestimmt das Delta zwischen Marker-Stand und aktuellem Stand und liefert die seitdem entstandenden Einträge und den dafür geltenden neuesten Marker mit. Wenn deine Seite das empfängt, baut es die Einträge ins DOM ein und speichert den gelieferten Marker als aktuellen Marker.

    2. Server Sent Events (SSE)

    Das ist ein Verfahren, bei dem der Server aktiv Updates sendet, wenn sich eine Änderung ergibt. Mit PHP sind echte SSE schwierig umzusetzen; die diversen Samples, die ich im Netz gefunden habe, sind Fake. Das gleiche gilt für

    3. Web Sockets (WS)

    Das ist ein neueres Verfahren als SSE und ist in PHP ebenfalls nicht so einfach umzusetzen. Hier können Browser und Server über eine offengehaltene Verbindung ständig Daten austauschen.

    Problem bei SSE und WS ist, dass diese Verfahren das klassische Request-Response Prinzip des Web verändern. HTTP ist normalerweise verbindungslos, d.h. sobald ein Request geschickt wurde und die Response vom Server verschickt wurde, weiß der Server nichts mehr davon (außer Session-State). Der Server hält aber keine ständige Information über aktive Clients. Das ist im klassischen Web gut und ressourcensparend. Für interaktive Verfahren wie SSE oder WS ist das anders, da muss sich der Server jeden Client merken. Das kostet deutlich mehr Server-Ressourcen. Und vor allem bedeutet es, dass es auf dem Server einen ständig laufenden Prozess geben muss, der die Client-Verbindungen kennt; das ist KEIN klassisches PHP Script. Es gibt z.B. Ratchet, eine PHP Library für Websockets, aber da startest Du einen PHP-Prozess neben dem Webserver, das geht nicht bei jedem Hoster.

    Andersrum kostet auch Polling Ressourcen, weil dann jeder Client ständig Requests an den Server schickt (z.B. im 5- oder 10-Sekunden Takt). Bei 10.000 Clients ist das ein übler Hagel an Anfragen, der den Server oder die DB schnell in die Knie zwingen kann.

    Rolf

    --
    sumpsi - posui - clusi
    1. Hallo Rolf,

      1. Polling.

      Wenn Du die Seite regulär sendest, schickst Du eine JavaScript-Zeile mit, die einen "letzter Stand" Marker setzt. Zum Beispiel der Timestamp des neuesten Eintrags, oder die ID (sofern Du aufsteigende IDs vergibst). Per JavaScript erzeugst Du einen Intervalltimer, der per Ajax den Server fragt, ob es was neues gibt. Dabei wird der eben genannte Marker als Parameter übergeben, das per Ajax aufgerufene PHP Script bestimmt das Delta zwischen Marker-Stand und aktuellem Stand und liefert die seitdem entstandenden Einträge und den dafür geltenden neuesten Marker mit. Wenn deine Seite das empfängt, baut es die Einträge ins DOM ein und speichert den gelieferten Marker als aktuellen Marker.

      ich habe mich erst einmal für die erste Variante entschieden. Danke für deine sehr ausführliche Beschreibung. Folgendes habe ich bis jetzt erledigt

      function getMaxIdToDos($mysqli){
      
        $sql = "SELECT MAX(ID) AS `maxid` FROM todo_grunddaten";
        $res = $mysqli->prepare($sql);
              
        $res->execute();
        $res->bind_result($maxid);
        $res->fetch();
        $res->close();  
      
        return $maxid; 
      }
      

      Auf der Seite erzeuge ich dann eine JavaScript Variable

      $(document).ready(function(){
       var maxIdToDos = <?php echo getMaxIdToDos($mysqli); ?>
      }); 
      

      Bin ich auf dem richtigen Weg?

      Bis bald! Meowsalot (Bernd)

      1. Hallo Meowsalot,

        hättest Du das Handy etwas mehr nach rechts geschwenkt, hätte ich mich vielleicht im Bild wiedergefunden 😂. In Mülheim bist Du also.

        Ein Semikolon am Zeilenende ist noch gut.

        Und - wenn Du das so machst, entsteht das kleine Problem der Variablenlebensdauer. Du setzt das in eine Readyhandler-Funktion, und maxIdToDos lebt damit genau so lange wie der Scope dieser Funktion.

        Das muss nicht falsch sein. Du musst aber dann INNERHALB dieses Readyhandlers auch den Intervalltimer aufsetzen, damit der auf maxIdToDos Zugriff hat. Ein bisschen was zu Variablen und Scopes findest Du hier, wenn Du Dir unsicher bist, was ich meine.

        $(document).ready(function(){
           var maxIdToDos = <?php echo getMaxIdToDos($mysqli); ?>;
           var refreshing = false;
           setInterval(refreshPostings, 5000);
        
           function requestPostingUpdate() {
               if (refreshing) return;
        
               ajaxGetListUpdate(maxIdToDos)
               .then(acceptPostingUpdate, failedPostingUpdate)
           }
        
           function acceptPostingUpdate(result) {
              // ergebnis in table einarbeiten
              maxIdToDos = result.maxIdToDos;
              refreshing = false;
           }
           function failedPostingUpdate() {
              refreshing = false;
           }
        });
        

        ajaxGetListUpdate ist eine Funktion, die anderswo stehen kann und die den eigentlichen Ajax-Call durchführt. Das kannst Du zum Beispiel mit $.getJSON machen. Ab jQuery 1.5 bekommst Du davon ein Promise zurück, auf dessen Ergebnis Du mit .then warten kannst. D.h. du gibst aus ajaxGetListUpdate einfach das Ergebnis von $.getJSON zurück und übergibst keinen dritten Parameter an getJSON.

        Alternativ kannst Du auch das Fetch-API von Javascript verwenden. Aber wenn du jQuery eh schon drin hast, kannst Du es auch benutzen :)

        Viel mehr sollte das als Hauptsteuerung nicht werden. Da, wo // Ergebnis in Table einarbeiten steht, rufst Du eine weitere Funktion auf die sich um das Anhängen der neuen Rows an die Table kümmert. Ich hinterfrage jetzt nicht, ob eine Table das richtige HTML Konstrukt für den Zweck ist oder nicht...

        Im PHP erzeugst Du eine Rückgabestruktur, die sich passend als JSON Objekt aufbereiten lässt. Mein Beispielcode geht davon aus, dass das Rückgabeobjekt eine Eigenschaft maxIdToDos besitzt. Für die neuen Zeilen baust Du eine weitere Eigenschaft ein, die die Zeilen als Array enthält. Du solltest dabei schon in PHP die htmlspecialchars-Aufbereitung vornehmen.

        Du solltest den PHP-Code, den Du eingangs gezeigt hast, auch noch etwas modularisieren. Denn das Aufbereiten einer DB-Zeile als Table-Row brauchst Du für die Erstanzeige und auch für den Ajax-Call.

        Mehr kau ich nun nicht vor, ich denke, du hast jetzt erstmal einiges zu recherchieren :)

        Rolf

        --
        sumpsi - posui - clusi
        1. Hallo Rolf,

          vielen lieben Dank für deine sehr ausführliche Erklärung. Leider kenne ich mich mit jQuery und oder JavaScript kaum aus. Deshalb fällt es mir auch sehr schwer alles zu verstehen oder dann dieses auch umzusetzen.

          Ich weiß ja nicht, nimmst du kleine Aufträge an? Wenn ja, was würde mich die Umsetzung kosten?

          Bis bald!
          Meowsalot (Bernd)

          1. Hallo Meowsalot,

            Programmieraufträge kann ich nicht übernehmen. Das Forum heißt SelfHTML, d.h. wir versuchen, Hilfe zur Selbsthilfe zu geben. Daher habe ich Dir nur ein Konzept vorgestellt, mit dem Du weiterkommen könntest. Ob jemand anderes das für Dich programmieren möchte - keine Ahnung.

            Unser Wiki enthält Texte zum Thema JavaScript. Da kannst Du viel lesen, du kannst Dir auch Bücher darüber kaufen. Es ist natürlich viel, was man da lernen muss. Wenn Du das nicht möchtest, wird es natürlich schwierig. Einen blitzschnellen Erfolg wirst Du nicht haben, das liegt in der Natur der Sache: es ist eine lange Lernkurve. Wenn Du beim Lernen Fragen hast, kannst Du die hier gern stellen und wirst auch Hilfe bekommen, es sollten dann aber spezifische Fragen sein und nicht "ich will da und da hin, kau mir das mal vor".

            Und übrigens: jQuery kann man nehmen, muss man aber nicht; alles was jQuery kann, können die heutigen Browser auch nativ. Vielleicht etwas umständlicher, aber die Existenzberechtigung für jQuery ist heute nicht mehr so ganz gegeben. Ich hatte nur bei Dir den ready-Handler gesehen und bin deshalb davon ausgegangen, dass jQuery ganz normal zu deinem Toolstack gehört.

            Rolf

            --
            sumpsi - posui - clusi
  3. hallo

    Guten Morgen,

    ich möchte gerne erreichen wenn ein User ein neuer Eintrag hinterlassen dass ich dieses automatisch angezeigt bekomme auch wenn ich die Seite nicht aktualisiere. Ist dieses möglich?

    Also jemand anders erzeugt auf seinem Client Daten, und die werden dann über einen Serverprozess an deinen Client gesendet, der die Daten an deine Tabelle anhängt?

    Das geht über eine Art Chat-Client. In dem Falle würde ich aber JSON ausgeben und dieses via Javascript an die Tabelle anhängen.

    Gut, wahrscheinlich hast du aber etwas anderes gemeint. Aber auch hier gilt: Verwende XHR, gebe JSON zurück und lasse den Requesthandler die Daten an die existierende Tabelle anhängen. JSON deshalb, weil du damit flexibler gegenüber dem Ausgabeformat bleibst.

    Neue Daten markieren:

    table.is-updated tr:last-of-type td {...}
    

    oder

    table tr.added-since-last-session td {...}
    

    Den Weg über den Server würde ich allein schon wegen der Datenvalidierung immer voraussetzen.