Daniel_T: PLZ wird eingegeben -> Ort wird automatisch geladen

Hallo!

Ich weiß nicht wie ich mit JS das machen kann:

Ich hab ein Forumlar, wo man Name, Ort, Plz, usw. eingibt.
Wenn man jetzt die Plz eingibt, würd ich gern den passenden Ort dazu per JS einfügen lassen.

Kann ich das machen, ohne das Dokument neu laden zu lassen?

Danke schonmal!
Daniel

  1. Ich hab ein Forumlar, wo man Name, Ort, Plz, usw. eingibt.
    Wenn man jetzt die Plz eingibt, würd ich gern den passenden Ort dazu per JS einfügen lassen.

    Kann ich das machen, ohne das Dokument neu laden zu lassen?

    Das geht per

    a) AJAX
    b) Flash als Datentransporter
    c) Inkaufnahme von ewig langer Ladezeit, weil Du die gesamte PLZ/Ort-Liste mit dem Dokument lädst
    d) Blind- bzw Blind-Inline-Frame als Datentransporter (siehe dazu auf meiner Website das Script für die dynamische nachladende Tabelle).

    Alles hat Vor- und Nachteile. Selbst evaluieren.

    1. a) AJAX

      Darf man fragen was das ist :) Hab ich noch nicht gehört!

      b) Flash als Datentransporter

      Flash geht nicht

      c) Inkaufnahme von ewig langer Ladezeit, weil Du die gesamte PLZ/Ort-Liste mit dem Dokument lädst

      Wie kann ich das mit JS machen? Das war auch meine Frage :)
      Da das ganze lokal ist, macht die Datenmenge so gut wie ein Problem!

      d) Blind- bzw Blind-Inline-Frame als Datentransporter (siehe dazu auf meiner Website das Script für die dynamische nachladende Tabelle).

      Muss ich mir auch ansehen

      Alles hat Vor- und Nachteile. Selbst evaluieren.

      Danke
      Daniel

      1. Wie kann ich das mit JS machen? Das war auch meine Frage :)
        Da das ganze lokal ist, macht die Datenmenge so gut wie ein Problem!

        Indem Du Dir zum Beispiel über Arrays eine Art Hashtable baust.

  2. Tag Daniel_T.

    Ich hab ein Forumlar, wo man Name, Ort, Plz, usw. eingibt. Wenn man jetzt die Plz eingibt, würd ich gern den passenden Ort dazu per JS einfügen lassen.
    Kann ich das machen, ohne das Dokument neu laden zu lassen?

    Ja, das geht theoretisch schon, birgt aber Risiken:

    • es gibt einige tausend Postleitzahlen
    • nicht jedem Ort ist eindeutig eine PLZ zuordenbar
    • nicht jede PLZ ist eindeutig einem Ort zuordenbar
    • es gibt reservierte PLZ (Postfächer, Großkundenadressen)

    Alles in allem ist das Vorhaben zwar machbar, aber m.E. sehr fragwürdig.

    Siechfred

    1. Tag Daniel_T.

      Ja, das geht theoretisch schon, birgt aber Risiken:

      • es gibt einige tausend Postleitzahlen
      • nicht jedem Ort ist eindeutig eine PLZ zuordenbar
      • nicht jede PLZ ist eindeutig einem Ort zuordenbar
      • es gibt reservierte PLZ (Postfächer, Großkundenadressen)

      Alles in allem ist das Vorhaben zwar machbar, aber m.E. sehr fragwürdig.

      Deine Punkte sind mir klar, leider :) Mein Problem ist, dass ich ein Programm von einer AS400 mit Perl machen muss, und da kann man beim Datenfeldwechseln ja einfach die Sachen prüfen und einfügen. Die einzige Möglichkeit die ich dazu in Perl/HTML kenne, ohne das Formular komplett neu laden zu lassen, ist JS.

      Aber das AJAX muss ich mir jetzt ansehen.

      Siechfred

      Danke Daniel

  3. Hallo!

    Ich weiß nicht wie ich mit JS das machen kann:

    Ich hab ein Forumlar, wo man Name, Ort, Plz, usw. eingibt.
    Wenn man jetzt die Plz eingibt, würd ich gern den passenden Ort dazu per JS einfügen lassen.

    Kann ich das machen, ohne das Dokument neu laden zu lassen?

    Ja, dazu würde ich die AJAX Technologie empfehlen.
    Als Ausgangsbasis zu meiner Recherche hat mir
    http://de.wikipedia.org/wiki/AJAX sehr geholfen.

    Schau dir auch
    http://www.sergiopereira.com/articles/prototype.js.html
    an.

    Aber wie bei sovielen Sachen, kann man damit auch ganz schön viel Blödsinn treiben, also auch gleich mal hier reinschauen:
    http://sourcelabs.com/ajb/archives/2005/05/ajax_mistakes.html

    mfg
      Horst

  4. Hi,

    Ich hab ein Forumlar, wo man Name, Ort, Plz, usw. eingibt.
    Wenn man jetzt die Plz eingibt, würd ich gern den passenden Ort dazu per JS einfügen lassen.

    Das das Mapping nicht ganz sauber funktioniert wurde Dir ja schon gesagt, aber das sind recht wenig Ausnahmen, prinzipiell reicht das durchaus.

    Zuerst brauchst Du einmal die Liste mit den Postleitzahlen, dafür wäre z.B. die OpenGeoDB
    wäre z.B. passend, da die Post die Datenbanken nicht mehr anzubieten scheint (oder jetzt kostenpflichtig, das habe ich nicht kontrolliert). Die Opengeodb gibt es auch als CSV-Dateien (Mit "text" im Dateinamen, die aktuellen sind UTF-8 codiert). Ich habe mir mal die Datei opengeodb-0.2.3e-UTF8-text-plz.txt vorgenommen. Im Feld 7 ist der Ort und im Feld 10 die Postleitzahl. Mit Hilfe von ein wenig Perl (ich habe es mit cat opengeodb-0.2.3e-UTF8-text-plz.txt | sed -e 's/^#.\*$//g' |  perl -F\;  -ane '$plz = @F[9]; $plz =~ s/[\n\r]//;  print "[\"",@F[6], "\",\"", $plz ,"\"],\n"; probiert) kann man daraus ein Javascriptarray basteln (im obigem Falle käme dann obendrüber noch ein "plz = new Array(" und untendrunter, nach der Entfernung des allerletzten Kommas, noch ein ");"). Es ist knappe 200kib groß, bei komprimierter Übergabe knapp 60 kib. Ist zwar hart an der Grenze aber noch akzeptabel.
    Einige Städte haben mehrere Postleitzahlen, die sind durch Komma getrennt. Wem die deshalb erforderliche lineare Suche zu lahm ist, muß sich halt die Mühe machen es aufzudröseln, da sich die Liste sonst nicht nach den Postleitzahlen sortieren läßt.

    Bei entspr. Implementation funktioniert das auch in älteren Browsern. AJAX tut es nicht und erfordert zudem beim IE eingeschaltetes ActiveX, wenn ich mich nicht irre, man möge mich korrigieren.

    so short

    Christoph Zurnieden

    1. Hi,

      ... weil man ja sonst nix besseres zu tun hat ... ;-)

      Ummodeln der o.a. Opengeodb-Postleitzahlenliste in ein JS-Array (Liebe Perl-Gurus: bitte nicht gleich wieder hauen! ;-):

        
      #!/usr/bin/perl -w  
        
      use strict;  
        
      my $opengeodb = "opengeodb-0.2.3e-UTF8-text-plz.txt"; #$ARGV[0];  
      my $jsarray   = "opengeodb-js-array.js"; #$ARGV[1];  
        
      my @line;  
      my $out;  
      my %entries;  
        
      my $zip  = "";  
      my $city = "";  
        
      my $i = 0;  
        
      open OPENGEODB, "< $opengeodb" || die "can't open $opengeodb";  
      open JSARRAY,   "> $jsarray"   || die "can't open $jsarray";  
        
      keys %hash = 8000; # alloziert 8192 Plätze für 8181 Plz.  
        
      print JSARRAY "plz = new Array(\n";  
        
      while(<OPENGEODB>){  
        next if $_ =~ /^\x23/;  
        
        @line = split(/;/,$_);  
        
        $zip  = $line[9];  
        $zip =~ s/[\n\r]//;  
        
        $city = $line[6];  
        
        $entries{$zip} = $city;  
        
      }  
      close OPENGEODB;  
        
      foreach $out (sort(keys %entries)) {  
        print JSARRAY '["', $entries{$out}, '","', $out, '"],',"\n";  
      }  
      print JSARRAY '["",""]);';  
      close JSARRAY;  
      
      

      Kurzes Beispiel zur Nutzung (Liebe Javascript-Gurus: betreffs der Prügelfrage bitte ich euch an die Perl-Gurus zu wenden.):

        
      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
      <html>  
      <head>  
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">  
      <title>Die leidigen Postleitzahlen</title>  
      <!-- Das Array heißt "plz" -->  
      <script type="text/javascript" src="plz-array.js"></script>  
      <script type="text/javascript">  
        
      function binarySearch( needle, haystack){  
        var low    = 0;  
        var high   = haystack.length - 1;  
        var middle = 0;  
        var round  = 0;  
        while(low <= high){  
          round++;  
          middle = Math.floor((low + high)/2);  
          if(needle < haystack[middle][1])  
            high = middle - 1;  
          else if (needle > haystack[middle][1])  
            low = middle + 1;  
          else  
             return middle;  
        }  
        return -1;  
      }  
        
      function linearSearchExactFirst(needle, haystack){  
        
        var len  = haystack.length -1;  
        
        while(len--){  
          if (needle == haystack[len]){  
            return len;  
          }  
        }  
        return -1;  
      }  
        
      function linearSearchRegex(needle, haystack){  
        var len   = haystack.length -1;  
        var regex = new RegExp(needle);  
        var ret   = new Array();  
        var i     = 0;  
        
        while(len--){  
          if (regex.test(haystack[len][0])){  
             ret[i++] = haystack[len][0];  
           }  
         }  
        if(ret.length > 0){  
          return ret;  
        }  
        return -1;  
      }  
        
        
      function searchPLZ(entry){  
        
        var inpCity = document.forms[0].city;  
        /*  
          Eigentlich ist es ja heilige Pflicht nur das  
          zu nehmen, was man benötigt und nicht das  
          wegzuschmeisen, was man _nicht_ benötigt.  
          Soll im Produktionscode geändert werden?  
          Ach, wird doch eh nie!  
        */  
        entry = entry.value.replace(/[^0-9]*/g,"");  
        
        /* PLZ suchen */  
        if(entry.length != 5 && inpCity.value.length > 2){  
          /*  
            Aufgrund der Unsortiertheit der Ortsnamen  
            wäre es wohl besser diese Suche getrennt  
            durchzuführen. Evt sogar auf dem Server.  
            Für Experimentierfreudige trotzdem mal der  
            (ungeprüfte!) Code:  
          */  
          /*  
            Um die Sache zumindest etwas zu beschleunigen  
            wurde oben die Mindestlänge des Ortsnamenanfanges  
            auf drei festgelegt.  
            Für soviele und auch jeden weiteren Buchstaben  
            wird das ganze Array durchsucht und das Ergebnis in  
            einem weiterem Array festgehalten. Ist das Ergebnis-  
            array leer wurde nichts gefunden, ansonsten wird  
            eine Auswahliste gefüllt.  
          */  
          /*  
            linearSearchRegex() ist der Einfachheit halber  
            mittels eines Regex implementiert, wie auch der  
            Name schon anzudeuten versucht. Es wäre also  
            evt der Geschwindigkeit zuträglich vorher ein  
            wenig zu filtern.  
          */  
          /*  
            var ret =  linearSearchRegex(inpCity.value, plz);  
            if(typeof(ret) != "number" ){  
          */  
          /*  
            document.forms[0].city sei bereits eine Auswahlliste.  
            Die Auswahlliste wird bei jedem Aufruf von searchPLZ()  
            neu überschrieben.  
           */  
          /*  
            for(var i=0; i< ret.length;i++){  
              var newEntry = new Option(ret[i],ret[i],false,false);  
              inpCity.options[i] = newEntry;  
            }  
           */  
          /*  
             Code den Klick in die Auswahliste auszwerten ist  
             in dieser Datei nicht enthalten.  
           */  
          /*}  
            else{  
              return false;  
            }  
          */  
          return false;  
        
        }  
        /* Ort suchen */  
        else{  
          if(entry.length == 5){  
            // ermöglicht Korrektur der Plz.  
            inpCity.value = "";  
        
            /* Hier wird jeweils nur der exakte Wert  
               gesucht. Es kann aber auch mittels  
        linearSearchRegex() ein Array gefüllt werden  
        das ähnlich der Beschreibung bei "PLZ suchen"  
        ausgegeben wird.  
             */  
            var tmp = binarySearch(entry,plz);  
            if(tmp >= 0){  
              inpCity.value = plz[tmp][0];  
       return true;  
            }  
            else{  
              /* Aussagekräftige Fehlermeldung wäre  
          natürlich erheblich günstiger.  
        */  
              return false;  
            }  
          }  
          else {  
            /* Wenn das PLZ-Array auf mehrere Dateien  
               aufgeteilt ist, kann hier das Laden erfolgen.  
             */  
            return false;  
          }  
        }  
      }  
        
      function formSubmit(f,s,z,c){  
        alert(  "Es wurde \"submitiert\":\n"  
               + ((f.length > 0)?f:"kein Eintrag") + "\n"  
        + ((s.length > 0)?f:"kein Eintrag") + "\n"  
        + ((z.length > 0)?f:"kein Eintrag") + " "  
        + ((c.length > 0)?f:"kein Eintrag") + "\n");  
      }  
        
      </script>  
      </head>  
      <style type="text/css">  
      fieldset{  
               padding: 1em;  
               margin-top: 1em;  
        width:25em;  
        border: 1px solid black;  
              }  
      legend  {  
               border: 1px solid black;  
        color: black;  
        background-color:#c0c0c0;  
              }  
      </style>  
      <body>  
      <h1>Automatische Postleitzahlensuche</h1>  
      <form id="plzformular"  
            name="plzformular"  
            -- action="pfad/zum/bearbeitungscode" --  
            onsubmit="formSubmit();return false" >  
      <fieldset><legend>Adresse</legend>  
      Name<br>  
      <input name="fullname"  
             id="fullname"  
             type="text"  
             size="50"  
             maxlength="50" /><br>  
      Strasse<br>  
      <input name="streetname"  
             id="streetname"  
             type="text"  
             size="50"  
             maxlength="50" /><br>  
      Postleitzahl/Ort<br>  
      <input name="zip"  
             id="zip"  
             type="text"  
             size="5"  
             maxlength="5"  
             onkeyup="searchPLZ(this);" />  
      <input name="city"  
             id="city"  
             type="text"  
             size="40"  
             maxlength="40" />  
      </fieldset>  
      <fieldset><legend>Daten absenden</legend>  
      <input name="sendbutton"  
             id="sendbutton"  
             type="button"  
             value="Abschicken"  
             onclick="formSubmit(this.form.fullname.value,  
                                 this.form.streetname.value,  
            this.form.zip.value,  
            this.form.city.value);"/>  
      <input name="resetbutton"  
             id="resetbutton"  
             type="button"  
             value="Zur&uuml;cksetzen"  
             onclick="this.form.reset()"/><br>  
      </fieldset>  
      </form>  
      </body>  
      </html>  
      
      

      Ajax:
      Von Pallas Athene mit Wahnsinn belegt nahm er sich das Leben.

      Ist das jetzt ein unpassender Name für das Zeug um XMLHttpRequest()? Nein, ich finde nicht >;->

      so short

      Christoph Zurnieden

      1. Tag Christoph.

        Ajax:
        Von Pallas Athene mit Wahnsinn belegt nahm er sich das Leben.
        Ist das jetzt ein unpassender Name für das Zeug um XMLHttpRequest()? Nein, ich finde nicht >;->

        AJAX ist ein Hype. Lasst uns dabei sein :-)

        Siechfred

        1. Moin!

          AJAX ist ein Hype. Lasst uns dabei sein :-)

          Ich empfinde solche Formulare auch nicht immer als "benutzerfreundlich". Man setzt hier ein Häckchen und trägt dort etwas ein, um zuletzt festzustellen, dass die submit-Taste fehlt und ist, aus Benutzersicht, erstmal irritiert... Wobei ich für den konkreten Anwendungsfall (PLZ eingeben -> Ort oder SELECT-Liste zurückgeben) auch noch auf der Suche nach einer praktikablen Lösung (also einer funktionierenden ohne Frames-oder Popup-Gedöns) bin. Das Übertragen von 60 bis 200 KB ist eben auch nicht der Weisheit letzter Schluss, wenn es um eine echte Webanwendung gehen soll.

          Wobei ich derartigen Horror durchaus schon mal gemacht habe, weil das Projekt im Intranet und von CD laufen sollte: http://www.fastix.de/CBT/office97zuXP/suche.html

          MFFG (Mit freundlich- friedfertigem Grinsen)

          fastix®

          --
          Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Seminare, Training, Development
          1. Hi,

            AJAX ist ein Hype. Lasst uns dabei sein :-)

            Ich empfinde solche Formulare auch nicht immer als "benutzerfreundlich". Man setzt hier ein Häckchen und trägt dort etwas ein, um zuletzt festzustellen, dass die submit-Taste fehlt und ist, aus Benutzersicht, erstmal irritiert...

            Ja, das habe ich auch aus User-Feedback festgestellt, als ich da mal 'was gebastelt hatte (ist schon ein paar Jahre her, war lange vor dem Hype ;-). Der Benutzer ist so sehr an die Eigenarten eines Webformulares, das man sich da in der UI anpassen muß, auch wenn es keinen wirklichen Sinn macht. Meist reicht aber auch schon ein Knöpfchen "Anwenden" o.ä. jedoch _muß_ der Benutzer sein OK geben, aka Submit anklicken  bevor etwas augenscheinliches passiert, d.h. es darf schon alles erledigt sein, nur die optische Rückmeldung darf erst auf Userorder ausgeführt werden.

            Wobei ich für den konkreten Anwendungsfall (PLZ eingeben -> Ort oder SELECT-Liste zurückgeben) auch noch auf der Suche nach einer praktikablen Lösung (also einer funktionierenden ohne Frames-oder Popup-Gedöns) bin. Das Übertragen von 60 bis 200 KB ist eben auch nicht der Weisheit letzter Schluss, wenn es um eine echte Webanwendung gehen soll.

            Aufgrund der AS/400 hörte sich das für mich eher nach Intranet an. Hätte ich vielleicht dabei sagen sollen, stimmt.

            Natürlich ist es hart an der Grenze, insbesondere für den Zweck. Die Leute können sich eher die Orte merken, als die Postleitzahlen und da kämen dann einige MiBs zusammen:
            $ ls -l /usr/share/plz/
            insgesamt 6100
            -rw-r--r-- 1 root root   127792 Dez  7  2003 pofada.plz
            -rw-r--r-- 1 root root  4902511 Dez  7  2003 strada.plz
            -rw-r--r-- 1 root root  1209174 Dez  7  2003 umsda.plz
            Das kann man nicht mehr ordentlich über's Netz schieben, da müßte man dann wieder mit Frames oder JS-Nachladen fummeln, da wäre natürlich ein XmlHttpRequest() günstiger.

            Wenn da nicht die leidigen Sicherheitsprobleme wären und wie E7 sagte ist XmlHttpRequest() auch nur bis vor dem IE6 auf XP per Default eingeschaltet. Ich kenne den Verbreitungsgrad von IE6 auf XP nicht, nehme aber an, das er auf den neuen Kisten drauf ist?

            Wobei ich derartigen Horror durchaus schon mal gemacht habe, weil das Projekt im Intranet und von CD laufen sollte: http://www.fastix.de/CBT/office97zuXP/suche.html

            Je nach zur Verfügung stehenden Browserversionen könnte man sowas aufteilen und nachladen. Ich finde das Konzept auch zu kompliziert, aber das ist natürlich etwas Geschmacksache und viel Browserabhängig. Und außerdem: ich selber hab' schon Schlimmeres verzapft, daher sollte ich das Steinewerfen tunlichst lassen ;-)

            Aber im Intranet hast Du den Durchsatz (wenn nicht, hast Du andere, viel heftigere Probleme ;-) und auf CD kommst Du halt nicht drumherum.
            Zudem ist das auch eine Lösung, wenn der Server aus Sicherheitsgründen (andere Gründe kann ich mir nicht vorstellen ;-) nur statische Seiten ausliefert.

            so short

            Christoph Zurnieden

            1. Moin!

              ich selber hab' schon Schlimmeres verzapft, daher sollte ich das Steinewerfen tunlichst lassen ;-)

              Naja. Das Projekt ist schon ein Weilchen her und auch in den letzten Jahren habe ich Dank dieses Forums eine Menge neues gelernt. Unter anderem, weil ich manche Antwort nicht aus dem Zettelkasten nehme, sondern in den Fragen ein Problem erkenne, dessen Lösung mir selbst interessant oder als irgendwann mal brauchbar oder in eigenen Projekten sogar als bisher hintenangestellt erscheint. Ich denke, das mache nicht nur ich so.

              MFFG (Mit freundlich- friedfertigem Grinsen)

              fastix®

              --
              Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Seminare, Training, Development
    2. Hi,

      Bei entspr. Implementation funktioniert das auch in älteren Browsern. AJAX tut es nicht und erfordert zudem beim IE eingeschaltetes ActiveX, wenn ich mich nicht irre, man möge mich korrigieren.

      genauer gesagt: Das Control für AJAX ist in allen IE's standardmäßig aktiviert, ausgenommen die Kombination WindowsXP + IE6...

      E7

      1. Bei entspr. Implementation funktioniert das auch in älteren Browsern. AJAX tut es nicht und erfordert zudem beim IE eingeschaltetes ActiveX, wenn ich mich nicht irre, man möge mich korrigieren.

        genauer gesagt: Das Control für AJAX ist in allen IE's standardmäßig aktiviert, ausgenommen die Kombination WindowsXP + IE6...

        Äh? Wo sollte man »das Control« denn ein- und ausschalten? Meines Wissens hängt die Nutzung von XMLHttpRequest nur vom eingeschalteten ActiveX ab, und das gilt für alle MSIEs unter allen Windows-Versionen.

        Mathias

        1. Hi,

          Äh? Wo sollte man »das Control« denn ein- und ausschalten? Meines Wissens hängt die Nutzung von XMLHttpRequest nur vom eingeschalteten ActiveX ab, und das gilt für alle MSIEs unter allen Windows-Versionen.

          soweit ich das weiß (hab kein XP hier) kann man zwischen "Als sicher markiert"en Controls und "normalen Controls" unterscheiden, die sicheren sind standardmäßig an, die anderen aus/auf Nachfrage.

          XMLHttpRequest ist scheinbar in WinXP - zumindest zeitweise - von den sicheren zu den unsicheren gerutscht und von daher in vielen Fällen nicht verfügbar, hab schon Erfahrungen damit gemacht (== Beschweren dass es unter WinXP im IE nicht läuft).

          E7