Ankündigung

Einklappen
Keine Ankündigung bisher.

PHP mit Javascript Datenbank Update

Einklappen

Neue Werbung 2019

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

  • PHP mit Javascript Datenbank Update

    Moin,

    Hoffe mir kann hier jemand helfen:

    Ich gebe eine Namenliste in einer Tabelle aus:

    PHP-Code:
    Id  -- Checkbox -- Status -- Vorname -- Nachname
    1   
    -- [ ]           --    1      -- Max        -- Meier
    2   
    -- [ ]           --    0      -- Franz      -- Merkel
    3   
    -- [ ]           --    1      -- Heidi       -- Muster 
    Mein Ziel:
    Wird in der ausgegebenen Tabelle eine oder mehrere Checkboxen ausgewählt (siehe oben Id 1 + 3), soll beim auswählen der entsprechenden Select-option die Spalte "Status" bei diesem Benutzer überschrieben werden mit der Nummer 0, 1 oder 2
    je nach dem was ausgewählt wurde (siehe oben hier wurde 1 ausgewählt)

    Über der Tabelle hat es ein Select-Menü:
    PHP-Code:
    <form action="database.php" name="choice_aktion" id="choice_aktion" method="GET">
          <
    select class="form-control" name="CA" id="choice_aktion" onchange="submitform();">
            <
    option>---</option>
            <
    option value="0">Überprüfen</option>
            <
    option value="1">Veröffentlichen</option>
            <
    option value="2">Sperren</option>
          </
    select>
        </
    form
    Wird hier etwas geändert kommt Javascript und führt diese Form aus, was zu dem GET-Array führt:
    Code:
    <script type="text/javascript">
    function submitform(){
        document.choice_aktion.submit(); //get CA
    }
    </script>
    Jede Zeile der Tabelle hat eine solche Checkbox:
    PHP-Code:
    <td>
    <input type="checkbox" name="Sel[]" id="check" value="<?php print($row["id"]) ?>">
    </td>
    Von allen ausgewählten Checkboxen hätte ich gerne einen Array (=alle Id's der betreffenden users) um danach zusammen mit $_GET["CA"] die Datenbankeinträge mit UPDATE in einer Schleife zu überschreiben.

    Bin nun fast 3Stunden dabei und weiss hier nicht genau wie ich das hinkriegen kann. Einen Array in Javascript zu machen bringt ja nichts, weil ich diesen in PHP brauche... Eine Form um die Checkboxen zu tun wäre die falsche Lösung, schon alleine weil es danach noch eine Benutzerinteraktion braucht...
    Rein Theoretisch müsste ich die function submitform() ergänzen z.B. sowas:
    Code:
    if (document.getElementById("check").checked === true) {
    alert("gecheckt");
    }
    Gruss newsletter

  • #2
    Viele Wege führen nach Rom. Deinem Kenntnisstand entsprechend würde ich aber einfach das <form>-Element erst nach der Tabelle zumachen. Und dann die Methode des Formulars auf POST umstellen und du hast all Deine Checkboxen.

    Übrigens: Die id eines HTML-Elements muss einmalig sein. Du hast schon in diesem Schnipsel mit dem Select die id "choice_aktion" Zweimal. Und anschliessend hast du sicher x-mal die id "check". Das ist nicht valide und vor allem wenn du mit JavaScript arbeiten willst sorgt das für Probleme.

    Kommentar


    • #3
      Hallo, erstmal vielen Dank für deine Hilfe (manchmal denkt man einfach zu kompliziert )

      Das ganze funktioniert nun prima:

      Die angepasste Checkbox:
      PHP-Code:
      <td><input type="checkbox" name="Clients[]" value="<?php print($row["id"]) ?>"></td>
      Auswertung:
      PHP-Code:
      <?php if(isset($_POST["CA"]) && (is_numeric($_POST["CA"]))){
        
      $ca htmlentities($_POST["CA"], ENT_QUOTES"UTF-8");

        switch(
      $ca){
          case 
      0:
          
      $ca_str "<h6 style='color: orange;'>Überprüfen</h6>";
          break;
          case 
      1:
          
      $ca_str "<h6 style='color: green;'>Öffentlich</h6>";
          break;
          case 
      2:
          
      $ca_str "<h6 style='color: red;'>Gesperrt</h6>";
          break;
          default:
          
      $ca_str "<h6 style='color: #FF0090;'>Fehler</h6>";
        }

        if(isset(
      $_POST["Clients"])){
          echo 
      "<h6>Vorgenommene Änderungen: </h6>";
          
      $update "UPDATE clients SET status=? WHERE id=?";
          foreach(
      $_POST["Clients"] AS $clientnr){
            
      $stmt $pdo->prepare($update);
            
      $stmt->execute([$ca$clientnr]);
            echo 
      "Setze Status von Id ".$clientnr."➔".$ca_str;
          }
          
      ?>
          <button type="button" class="btn btn-outline-info" onclick="window.location='database.php'">Aktualisieren</button>
          <?php

        
      }else{
          echo 
      "Kein Datensatz ausgewählt";
        }
      }
      Weil ich nun um alles eine <form> habe, kann ich nebenan nicht mehr filtern, resp. kein <form> in der <form> machen:
      PHP-Code:
      <label>Zeige:</label>
            <
      select class="form-control" id="filter">
              <
      option>---</option>
              <
      option value="0">Überprüfen</option>
              <
      option value="1">Öffentlich</option>
              <
      option value="2">Gesperrt</option>
            </
      select
      Wenn hier etwas ausgewählt wird soll es ein GET geben (?View=1), bei der die Tabelle nur noch die "1"= Öffentlichen Datensätze ausgeben soll:
      (sowas: onchange="window.location='database.php?=VALUE'" der select-option ...)

      PHP-Code:
      clients $pdo->query("SELECT * FROM clients ".filter()." ORDER BY id DESC")->fetchall(); 
      PHP-Code:
      function filter(){
      if(isset(
      $_GET["View"]) && (is_numeric($_GET["View"]))){
          
      $view htmlentities($_GET["View"], ENT_QUOTES"UTF-8");

          return 
      " WHERE status="."'".$view."'";

        }

      Hast du eine Idee (ausser, dass man den ganzen Bereich "Zeige:" vor den "Aktion:"-Bereich nimmt (weg aus der <form>), weil wenn ich so weiter mache, habe ich ja bald wieder das selbe problem?

      Kommentar


      • #4
        Zitat von newsletter Beitrag anzeigen
        Wenn hier etwas ausgewählt wird soll es ein GET geben (?View=1), bei der die Tabelle nur noch die "1"= Öffentlichen Datensätze ausgeben soll:
        (sowas: onchange="window.location='database.php?=VALUE'" der select-option ...)
        Ich bin mir nicht sicher ob ich das Problem richtig verstehe, aber: wie soll das funktionieren? Du willst doch über das select-Feld ein Status auswählen auf den die ausgewählten Zeilen in der Tabelle gesetzt werden sollen - wie soll das funktionieren wenn durch die Filter-Funktion immer nur die Zeilen angezeigt werden die einen Status bereits haben? Du brauchst ein Formular mit einem Select als Filter und eines um den zu setzenden Status zu wählen.

        Und noch ein paar Anmerkungen um Code:

        PHP-Code:
        <td><input type="checkbox" name="Clients[]" value="<?php print($row["id"]) ?>"></td>
        Hier fehlt eine id um der Checkbox ein label-Element zuweisen zu können.

        PHP-Code:
        $ca htmlentities($_POST["CA"], ENT_QUOTES"UTF-8"); 
        Vergiss dass es die Funktion htmlentities() gibt, die macht zu viel kaputt. Verwende htmlspecialchars() um den Kontextwechsel zu HTML zu behandeln (siehe auch unten)

        $ca_str = "<h6 style='color: orange;'>Überprüfen</h6>";
        Hast du wirklich schon h1 bis h5 vorher? Wenn nein gehört da auch kein h6 hin. Wobei eine Überschrift hier ohnehin falsch scheint, missbrauche keine Elemente weil sie zufällig standardmäßig die richtige Darstellung liefern - und lass auch inline-Styles weg. Die Darstellung gehört in die externe CSS-Datei.

        PHP-Code:
        $update "UPDATE clients SET status=? WHERE id=?";
        foreach(
        $_POST["Clients"] AS $clientnr){
        $stmt $pdo->prepare($update); 
        das prepare gehört vor die forach-Schleife, das muss nur einmal ausgeführt werden.

        <button type="button" class="btn btn-outline-info" onclick="window.location='database.php'">Aktualisi eren</button>
        Wofür genau aktualisiert werden soll ist mir nicht ganz klar, aber warum machst du dich völlig unnötig von Javascript abhängig? Mach einen richtigen Button (type=submit bzw. ohne type-Attribut) daraus, dann funktioniert das auch ohne Javascript. Ganz korrekt heißt es auch window.location.href was du ändern möchtest. Und wenn Javascript: dann nicht inline sondern nachträglich dem Element zuweisen.

        <label>Zeige:</label>
        <select class="form-control" id="filter">
        Im label-Element fehlt das for-Attribut (alternativ select in label setzten), so hat das keine Funktion.

        PHP-Code:
        clients $pdo->query("SELECT * FROM clients ".filter()." ORDER BY id DESC")->fetchall();

        function 
        filter(){
        if(isset(
        $_GET["View"]) && (is_numeric($_GET["View"]))){
        $view htmlentities($_GET["View"], ENT_QUOTES"UTF-8");

        return 
        " WHERE status="."'".$view."'"
        gleich vier Fehler:
        - vor clients fehlt etwas Geld (evtl. auch einfach nur ein Kopierfehler)
        - verwende nie "SELECT *" sondern führe alle Spalten auf die du brauchst
        - du hast das Prinzip der Behandlung des Kontextwechsels nicht verstanden, htmlentities ist ohnehin schon falsch (siehe oben), aber für den Kontextwechsel zu SQL schon gleich dreimal völlig ungeeignet und falsch.
        - eine ID ist nur dazu da einen Datensatz zu identifizieren - zum Sortieren taugt die Spalte nicht.

        Kommentar


        • #5
          Hallo,

          Ich habe es mal grafisch dargestellt, wie das ganze aussieht:

          Bild gross: https://ibb.co/C2yMQGY

          Die Seiten sind mehr oder wenig identisch bis auf das angezeigte.
          Beide Seiten (Clients.php + Products.php) zeigen beim Aufruf standardmässig alle Datensätze an (bei Clients.php die Kunden, bei Products.php die Produkte).

          Produkte:
          PHP-Code:
          $products $pdo->query("SELECT * FROM products ".filter()." ORDER BY id DESC")->fetchall(); 
          Kunden:
          PHP-Code:
          $clients $pdo->query("SELECT * FROM clients ".filter()."ORDER BY id DESC")->fetchall(); 
          Wird auf der Seite Products.php von einer Datenbankausgabe der Button "link_zeige" angeklickt->
          PHP-Code:
          <button type="button" class="btn btn-link" onclick="window.location.href='clients.php?Id=<?php print($row["userid"]); ?>'">Zeigen</button>
          Greift der Filter von Clients.php und macht einen anderen SQL-Query, welcher nur diesen einen Client anzeigt:
          PHP-Code:
          function filter(){
            if(isset(
          $_GET["Id"]) && (is_numeric($_GET["Id"]))){
              
          $id htmlspecialchars($_GET["Id"], ENT_QUOTES);

              return 
          " WHERE Id="."'".$id."'";
            } 
          hoffe ich habe den htmlspecialchars() korrekt gemacht?
          Ist das erste mal, dass ich htmlentities() oder jetzt neu nur noch htmlspecialchars() verwende.

          umgekehrt greift die filter()-Funktion von Products.php.

          Ich bin mir nicht sicher ob ich das Problem richtig verstehe, aber: wie soll das funktionieren? Du willst doch über das select-Feld ein Status auswählen auf den die ausgewählten Zeilen in der Tabelle gesetzt werden sollen - wie soll das funktionieren wenn durch die Filter-Funktion immer nur die Zeilen angezeigt werden die einen Status bereits haben? Du brauchst ein Formular mit einem Select als Filter und eines um den zu setzenden Status zu wählen.
          Ziel:
          Wenn ich nun beim Select-Menü "Zeige:" hinkriege, dass die Seite neu ladet mit einem GET-Request z.B. products.php?VIEW=1 und danach in die function filter() erweitere mit dem Abrufen von if(isset($_GET["View"]) kann ich einen anderen return im SELECT-SQL-Query ausgeben wie:
          PHP-Code:
          return " WHERE status="."'".$view."'"
          was dazu führt, dass die Tabelle nun nur noch alle Datensätze mit "Öffentlich" (1) anzeigt.



          Nun aktuell sieht es so aus:
          HTML-Code:
          function filter(){
          if(existiert die $_GET(Id)
          return = Zeige die Produkte von diesem Client.
          }
          
          if(existiert der $_POST von Aktion:) && (ist eine nummer){
          $update den Status von dem Datenbankeintrag dort wo die Checkbox ausgewählt wurde.
          }
          
          <form für "Aktion:select options" Method=POST> <!-- FORM wird geöffnet für Aktion: -->
              Aktion:select options
              {
          
              }
              Zeigen:select options <!-- Hier kriege ich nun kein $_GET mehr hin, weil die <form POST> für die aktion: über die Zeigen: select options geht. -->
              {
              }        
          
              Datenbanktabellenausgabe mit checkboxen welche die "Aktion:select options" braucht. Die <form> für das Aktion-Select-Menü funktioniert also.
              {
              }
          </form> <!-- FORM wird geschlossen -->
          Hast du wirklich schon h1 bis h5 vorher? Wenn nein gehört da auch kein h6 hin. Wobei eine Überschrift hier ohnehin falsch scheint, missbrauche keine Elemente weil sie zufällig standardmäßig die richtige Darstellung liefern - und lass auch inline-Styles weg. Die Darstellung gehört in die externe CSS-Datei.
          Okay ich versuchs... ist teilweise bisschen mühsam die korrekte Darstellung zu finden mit <p...></p> oder wäre standardmässig <span></span> richtig? ...

          das prepare gehört vor die forach-Schleife, das muss nur einmal ausgeführt werden.
          habe ich mir nach dem Posten noch gedacht habe es nun angepasst

          Wofür genau aktualisiert werden soll ist mir nicht ganz klar
          Wird die Seite neu geladen ohne GET-Methode (kein GET-Request in der URL) zeigt es die anpassung unten in der ausgegebenen Datenbanktabelle an.

          aber warum machst du dich völlig unnötig von Javascript abhängig? Mach einen richtigen Button (type=submit bzw. ohne type-Attribut) daraus, dann funktioniert das auch ohne Javascript.
          Mich stört einwenig die <form> welche es überall braucht... Aktuell habe ich für die "Aktion:-Select" eine <form> um alle anderen Elemente (um das Zeigen:-Select, um die Tabelle) nur damit ich die Checkboxen innerhalb der <Form> habe um die Statusänderung zu machen. Wenn ich weiter mache habe ich noch viele andere Formularelemente-> Buttons, usw... welche weitere anpassungen vornehmen z.B. das ändern des Vornamens, Nachnamens eines Clients usw.
          Es zwingt mich also dazu, alle anderen Elemente anders zu positionieren-> Hier das "Zeigen:-Select" müsste ich vor den "Aktion:-Select" mit der <form> nehmen. usw.
          Für weitere "Aktionen": im Select-Menü soll es ein $_POST geben, für filterungen $_GET nur kann ich innerhalb einer <form> nicht nochmal eine <form> machen...

          Im label-Element fehlt das for-Attribut (alternativ select in label setzten), so hat das keine Funktion.
          Mache ich zukünftig:
          HTML-Code:
          <label for="filter">Zeige:</label>
          <select class="form-control" id="filter">
          oder
          HTML-Code:
          <label>Zeige:
          <select class="form-control" id="filter">
          </label>
          - vor clients fehlt etwas Geld (evtl. auch einfach nur ein Kopierfehler)
          war ein kopierfehler.
          - verwende nie "SELECT *" sondern führe alle Spalten auf die du brauchst
          Weiss, das ändere ich im nachhinein noch.. Es kann zu fehlverhalten führen. Wollte nicht gleich soviel schreiben für den Test.
          - eine ID ist nur dazu da einen Datensatz zu identifizieren - zum Sortieren taugt die Spalte nicht.
          Die Datensätze werden der Reihe nach eingefügt @Autoincrement. Aus diesem Grund sind die Datensätze durch
          PHP-Code:
          " ORDER BY id DESC" 
          der Reihe nach (=zuletzt eingefügter Datensatz ist zu oberst)?

          Kommentar


          • #6
            Zitat von newsletter Beitrag anzeigen
            Ich habe es mal grafisch dargestellt, wie das ganze aussieht: […]
            Das komplette HTML wäre hilfreicher gewesen, aber ok, du hast also bereits zwei select-Elemente.
            Das Problem mit dem Filter lässt sich umgehen, das form-Attribut existiert:
            HTML-Code:
            <form id="filter"></form>
            <form method="post">
            <p>
             <label>neuer Status:
             <select name="neuerstatus">
              <option>1</option>
              <option>2</option>
              <option>3</option>
             </select></label>
             <button>Status setzen</button>
            </p>
            <p>
             <label>Zeigen:
             <select form="filter" name="zeigen">
              <option>1</option>
              <option>2</option>
              <option>3</option>
             </select></label>
             <button form="filter">filtern</button>
            </p>
            <p>
             <label><input type="checkbox" name="Clients[]" value="123" /> Client 123</label>
            </p>
            </form>
            Als Werte für die Select-Elemente habe ich jetzt einfach mal 1-3 genommen, du kommen natürlich deine Status hin. die beiden select-Elemente stecken jeweils in einem p, das kannst du natürlich noch nach belieben formatieren, auch nebeneinander - grid und flexbox existieren. Die einzelne Checkbox steht symbolisch für deine Tabelle mit den Checkboxen in jeder Zeile.

            Wird auf der Seite Products.php von einer Datenbankausgabe der Button "link_zeige" angeklickt->
            PHP-Code:
            <button type="button" class="btn btn-link" onclick="window.location.href='clients.php?Id=<?php print($row["userid"]); ?>'">Zeigen</button>
            da gehört kein button hin sondern ein handelsüblicher Link:
            PHP-Code:
            <a href="clients.php?Id=<?=htmlspecialchars($row["userid"]);?>">Zeigen</a>
            die Behandlung des Kontextwechsels nicht vergessen, das muss auch hier passieren! Die Darstellung kann dann ggf. noch angepasst werden, evtl. reicht es die Klassen btn und btn-link zuzuweisen.

            function filter(){ […]
            hoffe ich habe den htmlspecialchars() korrekt gemacht?
            Nein! Du hast hier keinen Kontextwechsel nach HTML sondern nach SQL den du entsprechend behandeln musst - lies die in #4 verlinkte Seite.

            Okay ich versuchs... ist teilweise bisschen mühsam die korrekte Darstellung zu finden mit <p...></p> oder wäre standardmässig <span></span> richtig? ...
            Das lässt sich ohne den Zusammenhang zu kennen nicht sagen. Generell gilt aber: es sollte immer das semantisch passende Element verwendet werden, die Darstellung wird dann ggf. über CSS noch angepasst.

            Mich stört einwenig die <form> welche es überall braucht... Aktuell habe ich für die "Aktion:-Select" eine <form> um alle anderen Elemente (um das Zeigen:-Select, um die Tabelle) nur damit ich die Checkboxen innerhalb der <Form> habe um die Statusänderung zu machen. Wenn ich weiter mache habe ich noch viele andere Formularelemente-> Buttons, usw... welche weitere anpassungen vornehmen z.B. das ändern des Vornamens, Nachnamens eines Clients usw.
            Diese Buttons sollten das gleiche Formular abschicken, was dann serverseitig passiert wird über die name-Attribute gesteuert.

            Weiss, das ändere ich im nachhinein noch.. Es kann zu fehlverhalten führen. Wollte nicht gleich soviel schreiben für den Test.
            Nein, nicht im nachhinein, gleich!

            Die Datensätze werden der Reihe nach eingefügt @Autoincrement. Aus diesem Grund sind die Datensätze durch " ORDER BY id DESC" der Reihe nach (=zuletzt eingefügter Datensatz ist zu oberst)?
            Aktuell mag das so sein, ein geeignetes Sortierkriterium sind IDs trotzdem nicht.

            Kommentar

            Lädt...
            X