it:plz_abfrage_ajax [Tergolape.at]

Benutzer-Werkzeuge

Webseiten-Werkzeuge


it:plz_abfrage_ajax

Postleitzahlenabfrage mit AJAX

Kurze Zusammenfassung zur der Sache mit den Postleitzahlen. Es gibt sicher mehrere Möglichkeiten das zu lösen, ich beschreibe hier die für mich funktionierende.

Voraussetzungen

  • Webserver mit PHP
  • Datenbank mit MySQL

Ich gehe davon aus, dass der Webserver mitsamt PHP funktioniert und auf MySQL Rechte zum Anlegen/Ändern von Datenbanken vorhanden sind.

Startseite und Funktionsbeschreibung

Auf der Startseite wird beim Aufruf ein einfaches Eingabefeld präsentiert.

Bei der Eingabe reagiert das <input>-Feld wie folgt (bei Tastendruck, noch bevor Enter gedrückt wird):

Unterhalb des <input>-Feldes erscheint eine Liste. Das zugehörige Objekt heißt „Datalist“. Dokus dazu findet man unter

Wird nach die <Enter>-Taste gedrückt, werden alle Suchergebnisse angezeigt:

<bild>

Dateien

Meine Lösung umfasst die folgenden Dateien:

  • index.php - Startseite und Einsprungpunkt. Darin findet die auch die Abfrage für die Ausgabe in der Tabelle statt.
  • config.php - Informationen zur Datenbankverbindungen. Ausgelagerter Code, damit die Sache ordentlich ist.
  • ajxgt.php - Hier wird meine AJAX Abfrage abgearbeitet und beantwortet. Dieses Script wird von JavaScript-Code aufgerufen.
  • mystyle.css - ein wenig Style muss schon sein.

Programmcode

Ich gebe hier nur die relevanten Teile wieder. Das Rundherum kann sich jeder selbst stricken.

index.php

Oben im Head wird die große Abfrage ausgeführt, jedoch nur wenn auch ein Parameter plzsuche an das Script übergeben wurde.

<?php
// DB connection settings
require "config.php";
 
// Read POST parameters. If no params are found, script
// will just display the input field.
if(isset($_REQUEST["plzsuche"])) {
   // Create connection
   $search = $_REQUEST["plzsuche"];
   $conn = new mysqli($servername, $username, $password, $db);
 
   // Check connection, or abort
   if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); }
 
   // Define Query, exect and close connection
   $sql = "SELECT * FROM plz WHERE plz LIKE '" . $search . "%'";
   $result = $conn->query($sql);
   $conn->close();
} else {
   $result = null;
} // end IF-ELSE
?>

Mein Suchfeld. Zu beachten sind die folgende Dinge

  • Die form action ruft sich selbst auf. Instatt jedesmal den Dateinamen mit der Endung PHP zu verwenden, habe ich das über $_SERVER[„PHP_SELF“] realisiert. Somit verweist das Script immer auf sich selbst. Sehr praktisch. ;)
  • An das <input>-Objekt sind zwei Attribute gekettet: ein onkeyup-Event der weiter unten in der Datei die JavaScript-Funktion showresult() aufruft, sowie ein list-Attribut, das auf eine ID plzliste verweist.
<div id="searchbar" class="container topspace">
 
<!-- 
htmlspecialchars : avoid manipulation of input params for more security $_SERVER["PHP_SELF"]);
Refers to the OWN SCRIPT!
-->
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post">
   <div class="form-group">
      <label for="plzsuche"><strong>Postleitzahlensuche</strong></label>
      <input name="plzsuche" id="plzsuche" class="form-control w-25 p-3" type="text" placeholder="PLZ" onkeyup="showResult(this.value)" list="plzliste">
      <datalist id="plzliste">
      </datalist>
   </div>
</form>
 
<hr>
</div>

Nach dem Suchfeld kommen die Ergebnisse. Nur wenn es auch Ergebnisse gibt, wird die Tabelle aufgebaut. Ich habe das ein wenig erweitert, um auch die Bundesländer etwas hübscher darzustellen und etwas mehr Gefühl für die Syntax von PHP zu bekommen. Der Code dazu sieht wie folgt aus:

<!-- DIV for displaying results -->
<div id="result" class="container topspace">
   <h2>Suchergebnisse</h2>
 
   < ? php
   // Do we even have a result?
    if (($result) && ($result - > num_rows > 0)) {
        $bundesland = "";
        // prepare a table header
        echo "<table class='table table-striped table-hover'>";
        echo "<thead class='thead-dark'>";
        echo "<tr><th>PLZ</th>";
        echo "<th>Ort</th>";
        echo "<th>Bundesland</th>";
        echo "</tr>";
        echo "</thead>";
        // output data of each row
        while ($row = $result - > fetch_assoc()) {
            echo "<tr>";
            echo "<td>".$row["plz"].
            "</td>";
            echo "<td>".$row["ort"].
            "</td>";
            // convert STATE shortcuts to full words
            switch ($row["bundesland"]) {
                case "O":
                    $bundesland = "Oberösterreich";
                    break;
                case "W":
                    $bundesland = "Wien";
                    break;
                case "N":
                    $bundesland = "Niederösterreich";
                    break;
                case "T":
                    $bundesland = "Tirol";
                    break;
                case "K":
                    $bundesland = "Kärnten";
                    break;
                case "V":
                    $bundesland = "Vorarlberg";
                    break;
                case "B":
                    $bundesland = "Burgenland";
                    break;
                case "Sa":
                    $bundesland = "Salzburg";
                    break;
                case "St":
                    $bundesland = "Steiermark";
                    break;
            } // end switch
            echo "<td>".$bundesland.
            "</td>";
            echo "</tr>";
        }
        echo "</table>";
    } else {
        // Tell the user, that we did a query
        // but have no result
        echo "0 results";
    }
    ?>
</div>

Ganz unten natürlich mein JavaScript-Code. Der wurde in zwei funktionen aufgeteilt:

  • Eine Funktion erstellt das XMLHTTPRequest-Objekt (also den AJAX-Aufruf),
  • das andere Wertet die Rückgabewerte aus und befüllt meine Datalist.

Zu beachten ist sind die Teile mit let url = „ajxgt.php“ und req.open(„POST“, url, true). Hier wird auf das andere PHP-Skript verwiesen. Zudem wird ein Parameter für POST festgelegt. In meinem Fall nenne ich ihn schlicht lookup und hänge hinten den Suchstring aus dem <input>-Feld an.

Die Funktion auswerten() befüllt nach einer erfolgreichen Übertragung eigenlich nur mehr das DataList-Objekt. Dazu aber mehr in ajxgt.php.

// my code goes here:
function showResult(str) {
    if (str.length != 0) {
        // we have an input, so we create the AJAX-Request
        let req = new XMLHttpRequest();
        let url = "ajxgt.php";
        let params = "lookup=" + str;
        req.open("POST", url, true);
        req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
        // when the request was succesful,
        // we connect to the callback and
        // fill the datalist
        req.onreadystatechange = auswerten;
        req.send(params);
    } else {
        // Input field is empty - so we have to empty
        // the datalist as well
        document.getElementById("plzliste").innerHTML = "";
    } // end if
} // end showResult
function auswerten(e) {
    // readyState 4 -> DONE. The operation is complete.
    // status 200 -> HTTP Ok
    if (e.target.readyState == 4 && e.target.status == 200) {
        // Add the Response Text (which holds a lot of ECHOs form PHP) to the DataList:
        document.getElementById("plzliste").innerHTML = e.target.responseText;
    } // end if
} // end auswerten

ajxgt.php

Die Datei ist eigentlich recht trivial und wie bereits gesagt: den Code hätte ich auch in der Index.php irgendwo unterbringen können, aber ich wollte ein wenig Trennung.

Gibt es einen Parameter lookup und ist dieser nicht leer, wird eine Abfrage von Postleitzahlen gegen die Datenbank ausgeführt. Gibt es Treffer in der Datenbank wird über die Trefferliste mit eine while-Schleife iteriert. Für jeden Treffer wird mit echo ein <option>-Tag erstellt und zurückgegeben. Das kommt dann wieder im JavaScript (Funktion auswerten() an. Der JS-Code fügt es dann der Liste hinzu. Fertig.

<?php
// DB connection settings
require "config.php";
// we only do the work, when we have a param called LOOKUP
if(array_key_exists('lookup', $_POST)) {
    // Put the $_POST parameter into a variable
    $lookup = $_POST['lookup'];
    // Open the DB-Connection & Check it
    $conn = new mysqli($servername, $username, $password, $db);
    if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); }
    // Define query and execute it
    $sql = "SELECT plz FROM plz WHERE plz LIKE '" . $lookup . "%'";
    $res = $conn->query($sql);
    $conn->close();
 
    // for each item in result:
    while($opt = $res->fetch_assoc()) {
        echo "<option value='" .$opt["plz"] . "' />";
    } // end while
} // end if
 
?>
/home/.sites/23/site9633986/web/data/pages/it/plz_abfrage_ajax.txt · Zuletzt geändert: 2020/06/10 21:47 (Externe Bearbeitung)