Andreas Korthaus: Auswahl-Liste nur mit gültigen Tagen eines Monats füllen

Hallo!

Ich überlege gerade wie man sowas mit Javascript machen könnte. Ich habe 3 Auswahlfelder(<select>):

Tag | Monat | Jahr |

Jetzt möchte ich erreichen, das im Auswahl-Feld "Tag" immer nur gültige Tage stehen, also 1-31, 1-30, 1-29, 1-28

Die Frage ist jetzt wie ich das mache. Ich brauche auf alle Fälle eine Prüfung am Anfang (onLoad), wenn das Script geladen wird, und dann jedesmal ein onClick wenn sich was am Monat oder Jahr ändert. Nur wie mache ich das? Wie kann ich in Javascript prüfen wieviele Tage ein Monat hat? Und dann? Soll ich standardmäßig 31 Einträge machen, und bei Bedarf die letzten 1-3 löschen? Kommt mir besser vor als die Liste immer neu zu erzeugen, ist außerdem auch ohne Javascript einsetzbar.

Ich hatte jetzt an http://selfhtml.teamone.de/javascript/objekte/options.htm#elemente_loeschen gedacht, nur weiß ich jetzt nicht wie ich durch das Datum die gültigen Tage ermittle. Hat jemand einen Tipp?

Viele Grüße
Andreas

  1. Halihallo Andreas

    Nur wie mache ich das? Wie kann ich in Javascript prüfen wieviele Tage ein Monat hat?

    eine Schwierigkeit beim Februar ist ja, ob er 28 oder 29 Tage hat (Schaltjahr nein/ja)
    Dies kannst du über ...

    function isLeapYear(y) {
      return ((y % 4 == 0) && ((y % 100!= 0) || (y % 400 == 0)));
    }

    ... rausfinden.
    Ob nun 30 oder 31 Tage geht analog mit der "Finger-Methode", Fingerknoten ist 31, Fingerzwischenstück ist 30 [man möge mir die primitive Formulierung verzeihen und sie nach belieben durch eine bessere ersetzen]; jeder Monat rückt den Fingerpointer eins nach rechts :-)

    Und dann? Soll ich standardmäßig 31 Einträge machen, und bei Bedarf die letzten 1-3 löschen? Kommt mir besser vor als die Liste immer neu zu erzeugen, ist außerdem auch ohne Javascript einsetzbar.

    Guter Gedanke!

    Ich hatte jetzt an http://selfhtml.teamone.de/javascript/objekte/options.htm#elemente_loeschen gedacht, nur weiß ich jetzt nicht wie ich durch das Datum die gültigen Tage ermittle. Hat jemand einen Tipp?

    über d = new Date()
    das Datum setzen, Monat auslesen (getMonth) und dann auf das Zeug von oben untersuchen. Dadurch sollte sich die Anzahl Tage im Monat herleiten lassen.

    hoffe, dass ich dir damit etwas erleichtern konnte.

    Viele Grüsse

    Philipp

    1. Hi Philipp!

      function isLeapYear(y) {
        return ((y % 4 == 0) && ((y % 100!= 0) || (y % 400 == 0)));
      }

      Ich habe das jetzt so gemacht:

      var Stop = 31;
      if(Monat==4 ||Monat==6 || Monat==9 || Monat==11 ) --Stop;
      if(Monat==2) {
       Stop = Stop - 3;
       if(Jahr%4==0) Stop++;
       if(Jahr%100==0) Stop--;
       if(Jahr%400==0) Stop++;
      }

      hoffe, dass ich dir damit etwas erleichtern konnte.

      Ja konntest Du, ich wußte so gar nicht wo ich ansetzen konnte, dabei ist es so einfach ;-)

      Grüße
      Andreas

      1. Halihallo Andreas und Forumer!

        var Stop = 31;
        if(Monat==4 ||Monat==6 || Monat==9 || Monat==11 ) --Stop;
        if(Monat==2) {
         Stop = Stop - 3;
         if(Jahr%4==0) Stop++;
         if(Jahr%100==0) Stop--;
         if(Jahr%400==0) Stop++;
        }

        Ja, das sollte so funktionieren ;)

        Naja, eigentlich wollte ich mit diesem Posting nur Dir und allen Forumern ein schönes
        neues Jahr wünschen ;)

        Viele Grüsse

        Philipp

  2. Hallo Andreas

    Der folgende Code dürfte dein Problem lösen.

    Gruss

    Dani

    ############## Beginn HTML- Seite ##################################
    <html>
    <head>
    <title>DateTest</title>
    <script language="javascript">
    <!--

    var gaintMaxDays = new Array(31,28,31,30,31,30,31,31,30,31,30,31);

    function SetDays()
     {
     var i;
     var datX = new Date();
     var intDay;
     var intMonth;
     var intYear;
     var intMaxDay;
     with (document.frmDate)
      {
      // Den momentan gesetzten Tag ermitteln (wenn möglich), sonst auf 1 setzen
      if ( (cboDays.options.length >0) && (cboDays.selectedIndex != -1) )
       { intDay = cboDays.options[cboDays.selectedIndex].value; }
      else
       { intDay = 1; }

    intMonth = cboMonths.options[cboMonths.selectedIndex].value;
      intYear = cboYears.options[cboYears.selectedIndex].value;

    datX.setMonth(intMonth);
      datX.setFullYear(intYear);
      intMaxDay=gaintMaxDays[intMonth];
      if ( ( intMonth == 1 ) && (IsLeapYear(intYear)) )  // Februar und Schaltjahr
       { intMaxDay++; }
      // Alle Elemente loeschen
      // Dieses Verfahren geht auch beim Opera
      for (i=cboDays.options.length-1; i>=0; i--)
       { cboDays.options[i]= null; }
      // Neue Elemente einfügen
      for (i=1; i<=intMaxDay; i++)
       { cboDays.options[cboDays.length] = new Option(i,i,false,false); }

    // Tag wieder setzen. Wenn zu gross auf max setzen.
      intDay= (intDay<=intMaxDay) ? intDay : intMaxDay;
      cboDays.selectedIndex=intDay-1;
      }
     }

    function IsLeapYear(p_intYear)
      { return ( ((p_intYear%4==0) && (p_intYear%100!=0)) ||  (p_intYear%400==0) ) ? 1 : 0; }

    function Init()
     {
     var i;
     var datX = new Date();
     var intMonth;
     var intYear;

    with (document.frmDate)
      {
      intMonth=datX.getMonth();
      intYear=datX.getFullYear();
      // Aktuelles Jahr setzen
      for(i=0; i<cboYears.options.length; i++) {
       if (cboYears.options[i].value == intYear )
        { cboYears.selectedIndex=i; }
       }
      // Aktuellen Monat setzen
      for(i=0; i<cboMonths.options.length; i++) {
       if (cboMonths.options[i].value == intMonth )
        { cboMonths.selectedIndex=i; }
       }
      }
     alert("war da!");
     SetDays();
     }
    //-->
    </script>
    </head>

    <body>

    <form name="frmDate" method="POST">
      <table border="0" width="420" bgcolor="#C7D5E2" cellspacing="0" cellpadding="10">
        <tr>
          <td><table border="0" width="400" cellspacing="0" cellpadding="3">
            <tr>
              <td width="44"><font face="Arial" size="2" color="#000080"><strong>Tag:</strong></font></td>
              <td width="111"><font face="Arial" size="2" color="#000080"><strong>Monat:</strong></font></td>
              <td width="227"><font face="Arial" size="2" color="#000080"><strong>Jahr:</strong></font></td>
            </tr>
            <tr>
              <td width="44"><select name="cboDays" size="1">
              </select></td>
              <td width="111"><select name="cboMonths" size="1" onChange="SetDays()">
                <option value="0">Januar</option>
                <option value="1">Februar</option>
                <option value="2">März</option>
                <option value="3">April</option>
                <option value="4">Mai</option>
                <option value="5">Juni</option>
                <option value="6">Juli</option>
                <option value="7">August</option>
                <option value="8">September</option>
                <option value="9">Oktober</option>
                <option value="10">November</option>
                <option value="11">Dezember</option>
              </select></td>
              <td width="227"><select name="cboYears" size="1" onChange="SetDays()">
                <option value="1998">1998</option>
                <option value="1999">1999</option>
                <option value="2000">2000</option>
                <option value="2001">2001</option>
                <option value="2002">2002</option>
                <option value="2003">2003</option>
              </select></td>
            </tr>
          </table>
          </td>
        </tr>
      </table>
    </form>
    <script language="javascript">
    <!--
    Init();
    //-->
    </script>

    </body>
    </html>

    ################### Ende HTML- Seite ################################

  3. Moin!

    Ich überlege gerade wie man sowas mit Javascript machen könnte. Ich habe 3 Auswahlfelder(<select>):

    Tag | Monat | Jahr |

    Jetzt möchte ich erreichen, das im Auswahl-Feld "Tag" immer nur gültige Tage stehen, also 1-31, 1-30, 1-29, 1-28

    Och nöö, schon wieder so ein super-unergonomisches Formular mit ganz besonders gut gemeinter Datumsselektion!

    Die beste Datumseingabefunktion ist immer noch: <input type="text"> Mit meinem numerischen Eingabefeld bin ich so schneller, als jeder Selectlisten-Terror!

    Wenn du dem Besucher unbedingt aufdrängen willst, dass er gefälligst Tag, Monat und Jahr in getrennte Felder schreiben soll, dann mach drei Felder hin.

    Ansonsten ist das Prüfen eines korrekten Datums Aufgabe deines Programms. Gerne darfst du mit Javascript schon vorm Abschicken gucken, ob es das eingegebene Datum überhaupt gibt: Einfach ein Datumsobjekt mit dem eingegebenen Datum erstellen, das so erzeugte Datum dann mit dem eingegebenen Datum vergleichen - wenn da Unterschiede auftreten, hat Javascript den 30. Februar in den 1. oder 2. März umgewandelt (das ist der geniale Trick an dieser Vorgehensweise), und du kannst eine Fehlermeldung ausgeben.

    Und auch beim Eingabeformat des Datums könntest du mit ein wenig gutem Willen die Benutzerfreundlichkeit recht hoch setzen, indem du viele Formate erlaubst, die man so eingeben kann: TTMMYYYY, T.M.YYYY, T,M,Y - ganz schlau wäre auch YYYY-MM-TT.

    - Sven Rautenberg

    --
    "Bei einer Geschichte gibt es immer vier Seiten: Deine Seite, ihre Seite, die Wahrheit und das, was wirklich passiert ist." (Rousseau)
    1. Hallo!

      Och nöö, schon wieder so ein super-unergonomisches Formular mit ganz besonders gut gemeinter Datumsselektion!

      Es ist besonders gut und besonders Fehlerresistent gegen Falscheingaben. Guck Dir mal http://www.flydba.com/ an(eine der besten Internetseiten dei ich kenne), was besseres habe ich noch nicht gesehen. Das Du das schnell abtippen kannst ist ja schön und gut, aber  dieses Forumlar wird vermultich nie von einem Programmierer benutzt werden. Und gerade _nicht_ Programmierer stehen auf so 'nen Kram.

      Die beste Datumseingabefunktion ist immer noch: <input type="text"> Mit meinem numerischen Eingabefeld bin ich so schneller, als jeder Selectlisten-Terror!

      ja, Du! Ich bin bei flydba aber schneller als Du 10 Zeichen tippen kannst, ein Mausklick! Was in der Art ist mein Ziel, und daher auch mal wieder meine Abneigung gehen NN4, denn der versteht nicht alles was ich ihm sagen will...

      Wenn du dem Besucher unbedingt aufdrängen willst, dass er gefälligst Tag, Monat und Jahr in getrennte Felder schreiben soll, dann mach drei Felder hin.

      Sowieso!

      Ansonsten ist das Prüfen eines korrekten Datums Aufgabe deines Programms. Gerne darfst du mit Javascript schon vorm Abschicken gucken, ob es das eingegebene Datum überhaupt gibt: Einfach ein Datumsobjekt mit dem eingegebenen Datum erstellen, das so erzeugte Datum dann mit dem eingegebenen Datum vergleichen - wenn da Unterschiede auftreten, hat Javascript den 30. Februar in den 1. oder 2. März umgewandelt (das ist der geniale Trick an dieser Vorgehensweise), und du kannst eine Fehlermeldung ausgeben.

      Auf Korrekthgeit muß ich soweiso auf dem Server prüfen, daher mache ich das nur dort. Das Javascript soll nur die letzten Tage entsprechend des Monats von 31 ausgehend löschen. Eine gute Hilfe war mir http://selfhtml.teamone.de/javascript/beispiele/monatskalender.htm, da steht eine schön einfache Methode die Anzahl der Tage zu errechnen.

      Und auch beim Eingabeformat des Datums könntest du mit ein wenig gutem Willen die Benutzerfreundlichkeit recht hoch setzen, indem du viele Formate erlaubst, die man so eingeben kann: TTMMYYYY, T.M.YYYY, T,M,Y - ganz schlau wäre auch YYYY-MM-TT.

      Da die Leute sich einloggen müssen kann ich für jeden spweichern welches Dateumsformat er bevorzugt, dem enstsprechend wird das Dateum auch überall ausgegeben und auch die Select-Felder sortiert. Wobei sich das ja schon durch deren Namen ergibt. Was ich damit evtl kombiniere ist http://www.totallysmartit.com/examples/calendar/simple.asp, wobei es Dir vermutlich besser so gefällt wie es ist ;-)

      Viele Grüße
      Andreas

      1. Moin!

        Och nöö, schon wieder so ein super-unergonomisches Formular mit ganz besonders gut gemeinter Datumsselektion!
        Es ist besonders gut und besonders Fehlerresistent gegen Falscheingaben.

        Mangelnde Fehlerresistenz liegt an mangelnder Überprüfung der Eingaben, nicht am Formular.

        Guck Dir mal http://www.flydba.com/ an(eine der besten Internetseiten dei ich kenne), was besseres habe ich noch nicht gesehen. Das Du das schnell abtippen kannst ist ja schön und gut, aber  dieses Forumlar wird vermultich nie von einem Programmierer benutzt werden. Und gerade _nicht_ Programmierer stehen auf so 'nen Kram.

        Schalte mal Javascript aus, und schon geht auf dieser "besonders guten" Seite absolut garnichts mehr! Soviel dazu... Ok, man kann es besser machen - muss man dann aber auch wirklich tun.

        Und ohne Javascript kriegst du eben immer noch ungültige Eingaben auf dem Server.

        Die beste Datumseingabefunktion ist immer noch: <input type="text"> Mit meinem numerischen Eingabefeld bin ich so schneller, als jeder Selectlisten-Terror!
        ja, Du! Ich bin bei flydba aber schneller als Du 10 Zeichen tippen kannst, ein Mausklick! Was in der Art ist mein Ziel, und daher auch mal wieder meine Abneigung gehen NN4, denn der versteht nicht alles was ich ihm sagen will...

        Du mußt nicht _einmal_ klicken, sondern mindestens _viermal_: je zweimal pro Feld - einmal Liste öffnen, einmal den Eintrag auswählen. Da bin ich mit Tippen sicherlich schneller.

        Auf Korrekthgeit muß ich soweiso auf dem Server prüfen, daher mache ich das nur dort. Das Javascript soll nur die letzten Tage entsprechend des Monats von 31 ausgehend löschen. Eine gute Hilfe war mir http://selfhtml.teamone.de/javascript/beispiele/monatskalender.htm, da steht eine schön einfache Methode die Anzahl der Tage zu errechnen.

        Klingt inkonsequent. Wenn schon Javascript, dann auch zur Validierung einsetzen.

        Da die Leute sich einloggen müssen kann ich für jeden spweichern welches Dateumsformat er bevorzugt, dem enstsprechend wird das Dateum auch überall ausgegeben und auch die Select-Felder sortiert. Wobei sich das ja schon durch deren Namen ergibt. Was ich damit evtl kombiniere ist http://www.totallysmartit.com/examples/calendar/simple.asp, wobei es Dir vermutlich besser so gefällt wie es ist ;-)

        Auch diese Lösung basiert auf Javascript - und sie funktioniert im Opera nicht. Das sind Ausschlußkriterien!

        - Sven Rautenberg

        --
        "Bei einer Geschichte gibt es immer vier Seiten: Deine Seite, ihre Seite, die Wahrheit und das, was wirklich passiert ist." (Rousseau)
        1. Hi Sven!

          Frohes neues ;-)

          Mangelnde Fehlerresistenz liegt an mangelnder Überprüfung der Eingaben, nicht am Formular.

          OK. Ich habe nur gemeint das der Otto-Normal-User eher Fehler einbaut und so mit hoher Wahrscheinlichkeit seine Eingabe korrigieren darf.

          »» »» Guck Dir mal http://www.flydba.com/

          Schalte mal Javascript aus, und schon geht auf dieser "besonders guten" Seite absolut garnichts mehr!

          OK, das sind Minuspunkte, aber gerade da sieht man was man mit Techniken die nicht alle User akzeptieren erreichen kann. Hast Du Dir das ganze mal im Mozilla oder IE mit Javascript angesehen?

          Soviel dazu... Ok, man kann es besser machen - muss man dann aber auch wirklich tun.

          Wenn ich mir die Seiten der Konkurrenten angucke, das sind KLASSEN die dazwischen liegen. Erstmal gefällt mir das design, mit so wenig Klicks wie möglich kommt man an eine Übersicht der Flüge mit Preis, wählt einen aus, gibt Namen und Kreditkartendaten an und hat sein Ticket. Besser geht es definitiv nicht, in jeglicher Hinsicht, bis auf die 2 kleinen IMHO unnötigen Macken(Opera und JS).
          Dies ist eine der ganz wenigen Internetseiten die einen wirklichen Mehr-Wert hat außer einer reinen Präsentation.

          Du mußt nicht _einmal_ klicken, sondern mindestens _viermal_: je zweimal pro Feld - einmal Liste öffnen, einmal den Eintrag auswählen. Da bin ich mit Tippen sicherlich schneller.

          Nein. Guck Dir den Link nochmal mit JS und Mozilla oder IE an.
          Klick 1 auf den Kalender markiert das Hinflug-Datum
          KLick 2 auf Rückflug
          Klick 3 markiert das Rückflugdatum.

          Und Du?
          Klick 1 auf Feld für Hinflugdatum
          10 Zeichen eingeben
          Klick 2 auf Feld für Rückflugdatum
          10 Zeichen eingeben

          Da mußt Du ehr schnell tippen, und wie gesagt bist Du nicht der Durchschnittsuser!

          Auf Korrekthgeit muß ich soweiso auf dem Server prüfen, daher mache ich das nur dort. Das Javascript soll nur die letzten Tage entsprechend des Monats von 31 ausgehend löschen. Eine gute Hilfe war mir http://selfhtml.teamone.de/javascript/beispiele/monatskalender.htm, da steht eine schön einfache Methode die Anzahl der Tage zu errechnen.

          Klingt inkonsequent. Wenn schon Javascript, dann auch zur Validierung einsetzen.

          Wieso doppelt? OK, hast schon recht, wäre schon schön wenn das mit der Validierung auf Offline ginge, spare ich mir ggfs. ein wenig Wartezeit, nur um die Server-Validierung komme ich nicht herum.

          http://www.totallysmartit.com/examples/calendar/simple.asp, wobei es Dir vermutlich besser so gefällt wie es ist ;-)

          Auch diese Lösung basiert auf Javascript - und sie funktioniert im Opera nicht. Das sind Ausschlußkriterien!

          ? Wieso ist Javascript auf einmal ein Ausschluß-Kriterium? Das ganze ist doch genau das was Du wilst, entweder gibt man es von Hand ein, dazu brauchst Du imho kein Javascript, oder Du nutz den Kalender. Ich bevorzuge aber die flydba - Lösung da die mich einfach fasziniert, durch deren Einfachheit und Ergonomie. Wie jemand das nicht gut finden kann verstehe ich nicht. Das ist IMHO ein an der Realität vorbei gehender Idealismus. Viele Sachen die ich früher nicht verstanden habe verstehe ich heute(Validator...), aber bis auf die beiden berechtigten Kritikpunkte(Welche Lösung ist schon perfekt!) kann ich Deine Abneigung nicht nachvollziehen. Das ist so ein Beispiel wie eine gute Internetseite mit "ausschluß-Techniken" wie Javascript doch den Umsatz steigern kann, seit dem neuen Konzept flydba(nicht nur die Internetseite, das ist nur ein wichtiger Teil des Konzeptes) sind die Passagier-Zahlen dort erheblich gestiegen. Und die Leute sind ja auch nicht blind/blöd, die beobachten ja auch die User auf der Seite und werden schon reagieren wenn zu viele potzentielle Kunden durch die eingesetzten Techniken abgeschreckt würden!

          Viele Grüße
          Andreas