• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Frage jsGrid Beispiel mit postgres

LudwigM

Mitglied
Kann jemand ein einfaches Beispiel einer jsGrid Tabelle mit postgres geben?
Leider ist die Demo sehr knapp gehalten...
Gegeben sei eine Tabelle mit wenigen Spalten
Hier mein Versuch:
Javascript:
<!DOCTYPE html>
<html>
<head>
  <title>CRUD with jsGrid and PostgreSQL</title>
 
 
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.js"></script>
    <link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.css" />
    <link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid-theme.min.css" />   


</head>
<body>
  <div id="jsGrid"></div>
 
  <script>
    $(function() {
      // Define the jsGrid fields
      const fields = [
        { name: "zeitstempel", type: "datetime", width: 150, validate: "required" },
        { name: "raum_id", type: "number", width: 50, validate: "required" },
        { name: "wert", type: "number", width: 50 },
        { name: "created", type: "datetime", width: 150 }
      ];
    
      // Define the jsGrid controller
      const controller = {
        loadData: function(filter) {
          return $.ajax({
            type: "GET",
            url: "data.php",
            data: filter
          });
        },
        insertItem: function(item) {
          return $.ajax({
            type: "POST",
            url: "data.php",
            data: item
          });
        },
        updateItem: function(item) {
          return $.ajax({
            type: "PUT",
            url: "data.php",
            data: item
          });
        },
        deleteItem: function(item) {
          return $.ajax({
            type: "DELETE",
            url: "data.php",
            data: item
          });
        }
      };
    
      // Initialize the jsGrid
      $("#jsGrid").jsGrid({
        height: "90%",
        width: "100%",
        sorting: true,
        paging: true,
        filtering: true,
        editing: true,
        deleting: true,
        inserting: true,
        autoload: true,
        pageSize: 10,
        pageButtonCount: 5,
        controller: controller,
        fields: fields
      });
    });
  </script>
</body>
</html>
PHP:
<?php

// Connect to the PostgreSQL database
$conn = pg_connect("host=localhost dbname=dbname user=user_name password=pw");

// Check if the connection was successful
if (!$conn) {
    die("Connection failed: " . pg_last_error());
}

// Handle the CREATE operation
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $data = json_decode(file_get_contents("php://input"), true);
    $sql = "INSERT INTO test (zeitstempel, raum_id, wert)
            VALUES ('" . $data['zeitstempel'] . "', '" . $data['raum_id'] . "', '" . $data['wert'] . "')";
    $result = pg_query($conn, $sql);
    if ($result) {
        echo json_encode("OK");
    } else {
        echo json_encode(pg_last_error());
    }
}

// Handle the READ operation
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    $sql = "SELECT * FROM test ORDER BY zeitstempel DESC";
    $result = pg_query($conn, $sql);
    $data = pg_fetch_all($result);
    if ($result) {
        echo json_encode($data);
    } else {
        echo json_encode(pg_last_error());
    }
}

// Handle the UPDATE operation
if ($_SERVER['REQUEST_METHOD'] === 'PUT') {
    parse_str(file_get_contents("php://input"), $data);
    $sql = "UPDATE test SET zeitstempel='" . $data['zeitstempel'] . "', raum_id='" . $data['raum_id'] . "', wert='" . $data['wert'] . "'
            WHERE zeitstempel='" . $data['zeitstempel'] . "' AND raum_id='" . $data['raum_id'] . "'";
    $result = pg_query($conn, $sql);
    if ($result) {
        echo json_encode("OK");
    } else {
        echo json_encode(pg_last_error());
    }
}

// Handle the DELETE operation
if ($_SERVER['REQUEST_METHOD'] === 'DELETE') {
    parse_str(file_get_contents("php://input"), $data);
    $sql = "DELETE FROM test WHERE zeitstempel='" . $data['zeitstempel'] . "' AND raum_id='" . $data['raum_id'] . "'";
    $result = pg_query($conn, $sql);
    if ($result) {
        echo json_encode("OK");
    } else {
        echo json_encode(pg_last_error());
    }
}[/SPOILER]

// Close the database connection
pg_close($conn);

?>
Es werden die Spalten erzeugt, aber keine Daten geladen
 
Fehler 1 + Hinweise:
Wenn du etwas an den Client zurückgibst, musst du auch die richtigen Header mitgeben:
PHP:
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    $sql = "SELECT * FROM test ORDER BY zeitstempel DESC";
    $result = pg_query($conn, $sql);
    $data = pg_fetch_all($result);
    if ($result) {
        header('Content-Type: application/json; charset=utf-8'); // !!!!!!!!!!!!!!
        echo json_encode($data);
    } else {
        echo json_encode(pg_last_error());
    }
}
Ansonsten weiß der Browser nicht, ob es sich um JSON, HTML, einen String oder sonstiges handelt (Das war Fehler 1). Selbiges gilt im übrigen auch für alle anderen Responses. Wenn du nur Text zurückgibst, wie es bei dir bei POST, PUT, DELETE der Fall ist, dann musst du auch kein json_encode anwenden, es handelt sich schließlich nicht um JSON.
PHP:
<?php

// Connect to the PostgreSQL database
$conn = pg_connect("host=localhost port=5432 dbname=postgres user=postgres");

// Check if the connection was successful
if (!$conn) {
    die("Connection failed: " . pg_last_error());
}

// Handle the CREATE operation
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $data = json_decode(file_get_contents("php://input"), true);
    $sql = "INSERT INTO test (zeitstempel, raum_id, wert)
            VALUES ('" . $data['zeitstempel'] . "', '" . $data['raum_id'] . "', '" . $data['wert'] . "')";
    $result = pg_query($conn, $sql);
    if ($result) {
        header('Content-Type: text/plain; charset=UTF-8');
        echo "OK";
    } else {
        echo json_encode(pg_last_error());
    }
}

// Handle the READ operation
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    $sql = "SELECT * FROM test ORDER BY zeitstempel DESC";
    $result = pg_query($conn, $sql);
    $data = pg_fetch_all($result);
    if ($result) {
        header('Content-Type: application/json; charset=utf-8');
        echo json_encode($data);
    } else {
        echo json_encode(pg_last_error());
    }
}

// Handle the UPDATE operation
if ($_SERVER['REQUEST_METHOD'] === 'PUT') {
    parse_str(file_get_contents("php://input"), $data);
    $sql = "UPDATE test SET zeitstempel='" . $data['zeitstempel'] . "', raum_id='" . $data['raum_id'] . "', wert='" . $data['wert'] . "'
            WHERE zeitstempel='" . $data['zeitstempel'] . "' AND raum_id='" . $data['raum_id'] . "'";
    $result = pg_query($conn, $sql);
    if ($result) {
        header('Content-Type: text/plain; charset=UTF-8');
        echo "OK";
    } else {
        echo json_encode(pg_last_error());
    }
}

// Handle the DELETE operation
if ($_SERVER['REQUEST_METHOD'] === 'DELETE') {
    parse_str(file_get_contents("php://input"), $data);
    $sql = "DELETE FROM test WHERE zeitstempel='" . $data['zeitstempel'] . "' AND raum_id='" . $data['raum_id'] . "'";
    $result = pg_query($conn, $sql);
    if ($result) {
        header('Content-Type: text/plain; charset=UTF-8');
        echo "OK";
    } else {
        echo json_encode(pg_last_error());
    }
}

// Close the database connection
pg_close($conn);

Fehler (?) 2:
Den zweiten Fehler konnte ich zwar aufspüren, aber irgendwie nicht wirklich lösen. Du wirst merken, dass wenn du paging: true in deiner jsGrid-Konfiguration auskommentierst, dir Daten angezeigt werden. Die mehr als dürftige Dokumentation von jsGrid hat mir leider auch keinen Aufschluss darüber gegeben, was hier genau der Fehler ist.

Was auf jeden Fall fehlt, ist die itemsCount property, welche zusätzlich zu deinen Tabellenzeilen serverseitig zurückgegeben werden muss, sofern du serverseitige pagination haben möchtest. Dein Response sollte die Form
JSON:
{
    data: [], // Deine Tabellenzeilen, limitiert auf die Pagegröße
    itemsCount: ... // Die insgesamte Anzahl an Zeilen in der Datenbank
}
sein.

So oder so habe ich es leider nicht zum laufen bekommen, ohne paging: true auszukommentieren.

Noch ein sehr wichtiger Hinweis:
PHP:
$sql = "UPDATE test SET zeitstempel='" . $data['zeitstempel'] . "', raum_id='" . $data['raum_id'] . "', wert='" . $data['wert'] . "'
            WHERE zeitstempel='" . $data['zeitstempel'] . "' AND raum_id='" . $data['raum_id'] . "'";
$result = pg_query($conn, $sql);
Als ich das gesehen habe, stellten sich bei mir direkt die Nackenhaare auf. Hier ist eine riesengroße Sicherheitslücke durch SQL-Injection sichtbar! Benutze unbedingt Prepared Statements! Und zwar nicht nur bei deinem PUT Request, sondern auch sonst überall.
 
Zuletzt bearbeitet:
Immerhin werden jetzt Daten angezeigt. Aber noch nicht so wie es sein sollte. Zwei leere Zeilen, und eine in der die Daten durch Scrollen zu sehen sind. Insert, Update, Create Funktion ist noch nicht gegeben.
1678391033217.png
Auffällig ist in der Netzwerkanalyse, dass data.php mit den Parametern zeitstempel und created, allerdings ohne Wert aufgerufen wird.
Wie sah es bei dir aus? @Aaron3219
Danke für den Hinweis, kommt noch...
 
Zuletzt bearbeitet:
Immerhin werden jetzt Daten angezeigt. Aber noch nicht so wie es sein sollte. Zwei leere Zeilen, und eine in der die Daten durch Scrollen zu sehen sind. Insert, Update, Create Funktion ist noch nicht gegeben.
Die erste Leerzeile ist zum Filtern da und wenn du mal einen Wert eingibst und Enter drückst, wirst du sehen, dass auch die Werte mitgeschickt werden.

Die zweite Leerzeile ist zum Einfügen dar, auch wenn ich noch nicht ganz kapiert habe, wie man denn eigentlich das Form submitted. Diese Informationen nehme ich aus den CSS Klassennamen.
1678400881600.png

Update kannst du machen, indem du auf eine Zeile doppelklickst.

Ich finde das hier alles aber höchst seltsam. Auch, weil das alles komisch gestylet ist.


Edit:
Bei deinen fields muss noch { type: "control" } eingefügt werden:
Javascript:
const fields = [
    { name: "zeitstempel", type: "datetime", width: 150, validate: "required" },
    { name: "raum_id", type: "number", width: 50, validate: "required" },
    { name: "wert", type: "number", width: 50 },
    { name: "created", type: "datetime", width: 150 },
    { type: "control" }
];
Dann ergibt das ganze schon mehr Sinn.
HTML:
<!DOCTYPE html>
<html>

<head>
    <title>CRUD with jsGrid and PostgreSQL</title>


    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

    <link type="text/css" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.css" />
    <link type="text/css" rel="stylesheet"
        href="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid-theme.min.css" />

    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jsgrid/1.5.3/jsgrid.min.js"></script>

</head>

<body>
    <div id="jsGrid"></div>

    <script>
        // Define the jsGrid fields
        const fields = [
            { name: "zeitstempel", type: "datetime", width: 150, validate: "required" },
            { name: "raum_id", type: "number", width: 50, validate: "required" },
            { name: "wert", type: "number", width: 50 },
            { name: "created", type: "datetime", width: 150 },
            { type: "control" }
        ];

        // Define the jsGrid controller
        const controller = {
            loadData: function (filter) {
                return $.ajax({
                    type: "GET",
                    url: "data.php",
                    data: filter,
                });
            },
            insertItem: function (item) {
                return $.ajax({
                    type: "POST",
                    url: "data.php",
                    data: item
                });
            },
            updateItem: function (item) {
                return $.ajax({
                    type: "PUT",
                    url: "data.php",
                    data: item
                });
            },
            deleteItem: function (item) {
                return $.ajax({
                    type: "DELETE",
                    url: "data.php",
                    data: item
                });
            }
        };

        // Initialize the jsGrid
        $("#jsGrid").jsGrid({
            width: "100%",
            height: "400px",
            sorting: true,
            paging: true,
            pageSize: 1,
            pageIndex: 1,
            filtering: true,
            editing: true,
            deleting: true,
            inserting: true,
            autoload: true,
            pageSize: 10,
            pageButtonCount: 5,
            controller: controller,
            fields: fields
        });
    </script>
</body>

</html>
Aber irgendwie finde ich jsGrid ein wenig komisch...
 
Danke, es wird immer ein bisschen besser ;) Die Anzeige der Daten funktioniert immerhin jetzt.
Beim Bearbeiten und Insert, wird zeitstempel und created nicht editierbar gemacht. created soll letzendlich auch nicht, aber zu Testzwecken schon. Geht das bei dir?
Es scheint am type in fields[] zu liegen. Gibt man da number an, geht es. Aber das nützt hier ja nichts. datetime-local und date geht leider auch nicht

Aber irgendwie finde ich jsGrid ein wenig komisch..
Gibt es bessere Alternativen?
 
Zuletzt bearbeitet:
Es scheint am typein fields[] zu liegen. Gibt man da numberan, geht es. Aber das nützt hier ja nichts. datetime-local und dategeht leider auch nicht
Eventuell unterstützt jsGrid keinen datetime picker (wäre zwar komisch, es könnte aber auch wieder an irgendwelchen undurchsichtigen Konfigurationsfehlern liegen).

Gibt es bessere Alternativen?
Das hängt immer von deinem Vorhaben ab. Ich persönlich habe mit jQuery und Vanilla HTML/JS-Projekten (im Sinne von "kein Framework, kein NodeJS, kein npm") schon lange nichts mehr am Hut gehabt und bin da ein wenig raus. Wenn ich mich recht erinnere, war/ist Datatables ein mächtiges und immer noch viel genutztes Tool. Für kleinere Vorhaben sollte das auf jeden Fall ausreichen.

Falls dein Vorhaben aber größer ist, kannst du zwar immer noch Datatables nutzen, aber ich würde dann doch lieber ein ordentliches Frontend und Backend Framework nutzen. Viele Frontend UI Libraries kommen dann mit ihren eigenen Tabellenimplementationen, die sich je nach Framework und Library unterscheiden.
 
Zurück
Oben