ruben: Tabulator abfangen

Hallo!

Ich möchte in einem etwas umständlicheren Formular, das "gracefully degraden" soll, eine etwas kompliziertere Tabulator-Reihenfolge umsetzen und stoße auf Browser-Schwierigkeiten, die ich nicht dokumentiert finde.

function klugestab(tastendruck) {  
if(!tastendruck) tastendruck = window.event;  
 if(tastendruck.which) { // Netscape-Syntax  
  tastencode = tastendruck.which; // ü la n  
  }  
 else if(tastendruck.keyCode) { // IE-Syntax  
  tastencode = tastendruck.keyCode; // ü la IE  
  }  
 alert(tastencode);  
 if(tastencode==9) {  
  document.getElementsByName('bekannt')[0].focus();  
  return false;  
  }  
 }  
function waehlneue() {  
 if(document.getElementsByName('sprache')[0].value == 'neueSprache') {  
  document.getElementsByName('neuesprache')[0].focus();  
  }  
 }  

[code lang=html]<select  name="sprache" id="sprache" size="1" tabindex="2" onchange="waehlneue();">
 <option value="Englisch">Englisch</option>
 <option value="neueSprache">Neue Sprache -></option>
</select>
<input type="text" name="neuesprache"  size="24" onkeydown="klugestab()" />
<label for="sprache">Sprache</label>
<textarea  name="bekannt" id="bekannt" rows="4" cols="40" tabindex="3"></textarea><label for="bekannt">Bekannt</label>[/CODE]

Ich hab natürlich schon alle möglichen Variationen ausprobiert, aber in dieser erscheint mir das Problem am deutlichsten:
Eigentlich soll "neuesprache" übersprungen werden, es sei denn, man wählt in dem Select "neuesprache" als Option aus. Dadurch wird nämlich "neuesprache" fokussiert.
Wenn man es wieder verlässt, dann soll man trotzdem zu "bekannt" kommen und nicht zum Ende des Dokuments (wo es ja vom nichtdefinierten Tabindex her steht).

Folgendes passiert:
Der Safari kommt mit der Funktion waehlneue nicht klar, damit beschäftige ich mich später.
Der Firefox fokussiert zwar erst "bekannt", springt danach aber auf das nächste Element, der Tabulator wird also nicht abgebrochen (was ich mit "return false" bezwecke).

Ich bin auch dankbar für einen anderen Ansatz, allerdings will ich dieses Script in anderer Verkleidung auch an anderer Stelle verwenden, wo ein anderer Ansatz wohl kaum möglich ist.

Vielen Dank, stehe vermutlich auf dem Schlauch, hab lang kein JS mehr benutzt,
Ruben

  1. Hi,

    Ich möchte in einem etwas umständlicheren Formular, das "gracefully degraden" soll, eine etwas kompliziertere Tabulator-Reihenfolge umsetzen

    welchen Grund hast Du dafür, etwas anderes als das tabindex-Attribut zu verwenden?

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. Hallo!

      welchen Grund hast Du dafür, etwas anderes als das tabindex-Attribut zu verwenden?

      Ist das eine moralische Frage?
      Ich verwende es ja.
      Allerdings: Man will nur dann eine neueSprache eingeben, wenn man zuvor in dem Select "neue Sprache ->" ausgewählt hat. Ansonsten soll das Eingabefeld neuesprache übersprungen werden. Standardmäßig liegt es also außerhalb der tabindex Reihenfolge, man will es nicht anwählen. Hat man es aber angewählt (entweder per Klick oder als letztes Element in der Reihenfolge oder eben durch "waehlneue()"), dann will man nach dem Verlassen in der ursprünglichen Tabulator-Reihenfolge weitermachen.
      Es handelt sich um eine Eingabemaske.

      Ich würde Tabindex benutzen, wenn es etwas wie "2.5" als Wert gäbe, was soviel heißt "Überspring mich, wenn ich nicht angewählt wurde". Gibt es aber meines Wissens nicht.

      Gruß,
      Ruben

      1. Hi,

        welchen Grund hast Du dafür, etwas anderes als das tabindex-Attribut zu verwenden?
        Ist das eine moralische Frage?

        nein, eher eine rhetorische.

        Allerdings: Man will nur dann eine neueSprache eingeben, wenn man zuvor in dem Select "neue Sprache ->" ausgewählt hat.

        Lies: Wenn "neue Sprache ->" nicht ausgewählt wurde, sollte das Eingabefeld disabled sein, woraufhin - oh Wunder! - es auch nicht mehr angesprungen werden kann.

        Ich würde Tabindex benutzen, wenn es etwas wie "2.5" als Wert gäbe, was soviel heißt "Überspring mich, wenn ich nicht angewählt wurde". Gibt es aber meines Wissens nicht.

        Nein, aber es gibt 2, 3 und 4. Wenn 3 nicht angesprungen werden kann, wohin gelangt man wohl, wenn man in 2 die Tabulator-Taste drückt?

        Cheatah

        --
        X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
        X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
        X-Will-Answer-Email: No
        X-Please-Search-Archive-First: Absolutely Yes
        1. Allerdings: Man will nur dann eine neueSprache eingeben, wenn man zuvor in dem Select "neue Sprache ->" ausgewählt hat.
          Lies: Wenn "neue Sprache ->" nicht ausgewählt wurde, sollte das Eingabefeld disabled sein, woraufhin - oh Wunder! - es auch nicht mehr angesprungen werden kann.

          Gracefully degrade:
          Die Seite soll auch ohne JS nutzbar sein. Also würde ich das Element dynamisch ausgrauen oder auch verstecken.
          Gibt es kein JS passiert also folgendes: der Nutzer hat oder hat nicht "neueSprache" ausgewählt und kommt in jedem Fall trotzdem auf das Eingabefeld.
          Da ich davon ausgehe, dass man selten eine neueSprache festlegt, ist das nicht die erwünschte Funktionalität.

          Eventuelle Lösung: Den Tabindex auch dynamisch setzen, d.h. ursprünglich liegt es außerhalb und wenn JS existiert ändere ich den Tabindex. Ich stelle mir vor, dass das Probleme nach sich zieht.

          Außerdem: Ich will Tab auch an anderer Stelle abfangen (zum Beispiel beim letzten Element) und da helfen solche Problemlösungen nicht weiter.

          Also vielen Dank für den Denkschubser, aber ich möchte immer noch das Problem mit dem JS-Tab-Abfangen lösen,
          Ruben

          1. Moin!

            Gracefully degrade:
            Die Seite soll auch ohne JS nutzbar sein. Also würde ich das Element dynamisch ausgrauen oder auch verstecken.

            Versuchst du gerade, die Benutzbarkeit ohne Javascript durch Programmierung in Javascript herzustellen?

            Ohne Javascript ist die Sache doch absolut klar: Es gibt keine Einflußmöglichkeit durch Javascript, alles was du hast sind nur die HTML-Attribute. Einziges Attribut für die Tabulator-Reihenfolge ist tabindex, und das muß so angepaßt sein, dass jegliche Auswahlmöglichkeit für den Benutzer akzeptabel und zielführend ist.

            Sprich: Wenn man zuerst eine Sprache wählt, und danach eventuell eine neue Sprache eintippen muß, und danach in ein weiteres Feld kommt, ist die tabindex-Reihenfolge ganz klar.

            Dass man das Eingabefeld eventuell inhaltsleer lassen kann, weil vorhergehende Eingaben hier keinen sinnvollen Inhalt zulassen - nun ja, ohne Javascript kannst du da keinerlei Eingabehilfen konstruieren. Der Benutzer wird diesen Fall selbständig erkennen und durch erneutes Tab-Betätigen einfach in das nächste für ihn sinnvoll ausfüllbare Feld springen. Den Finger am Tab auf der Tastatur hat er ja bereits.

            Gibt es kein JS passiert also folgendes: der Nutzer hat oder hat nicht "neueSprache" ausgewählt und kommt in jedem Fall trotzdem auf das Eingabefeld.
            Da ich davon ausgehe, dass man selten eine neueSprache festlegt, ist das nicht die erwünschte Funktionalität.

            Wie erwähnt: Ohne Javascript hast du keinerlei Möglichkeit, dagegen etwas zu tun. Das tabindex-Attribut reagiert, genauso wie alle anderen HTML-Attribute, nicht dynamisch auf irgendeine Formulareingabe.

            Eventuelle Lösung: Den Tabindex auch dynamisch setzen, d.h. ursprünglich liegt es außerhalb und wenn JS existiert ändere ich den Tabindex. Ich stelle mir vor, dass das Probleme nach sich zieht.

            Deine Lösung für den Fall, dass Javascript existiert, hat mit den Tabindices ja nicht zwingend etwas zu tun zu haben. Da würde ich vielmehr onblur reagieren und fallabhängig einen focus neu setzen.

            - Sven Rautenberg

            --
            "Love your nation - respect the others."
            1. Hallo!

              Danke, dass du das nochmal so klar aufgeschlüsselst hast, aber, auch wenn das anscheinend nicht rüberkam: Das war mir KLAR!
              (Ich habe mich anscheinend schlecht ausgedrückt, ich wollte eine Fallunterscheidung JS-Ja-Nein illustrieren).

              Ich gehe nur davon aus, dass im Standardfall der Javascript-freie Nutzer das "neueSprache"-Feld skippen will. Finger bereits auf Tab - meinetwegen. Ergonomietechnisch erscheint mir das einfach die bessere Lösung. Aber all das beiseite:
              Einfach um auch JS auf die Schliche zu kommen, muss ich jetzt einfach VERSTEHEN, wie ich es denn realisieren könnte (und außerdem will ich es ja an anderer Stelle einsetzen).

              Das mit onblur klang interessant, nur habe ich damit auch experimentiert, ohne auf einen grünen Zweig zu kommen. So wie ich das bisher verstehe, muss ich ja trotzdem den Tabulator erkennen (Wenn jemand nur woanders hinklickt, will ich ja nicht meinen Focus aufdrängen). Also, wie kann ich onblur erkennen, dass jemand in diesem Feld den Tabulator gedrückt hat und ein bestimmtes Feld fokussieren. Mir erschien das recht simple Problem eigentlich, dass Firefox zwar fokussiert, aber danach nochmal "tabbt" und Safari eben nur fokussiert und nicht "tabbt" (erwünscht).

              Danke für die Hilfe bei dieser schweren Kopfgeburt,
              Ruben

              1. Das mit onblur klang interessant, nur habe ich damit auch experimentiert, ohne auf einen grünen Zweig zu kommen.

                Nachvollziehbar, denn onblur unterscheidet nicht danach, auf welche Art und Weise das Formularelement "verlassen" wird.

                So wie ich das bisher verstehe, muss ich ja trotzdem den Tabulator erkennen (Wenn jemand nur woanders hinklickt, will ich ja nicht meinen Focus aufdrängen). Also, wie kann ich onblur erkennen, dass jemand in diesem Feld den Tabulator gedrückt hat und ein bestimmtes Feld fokussieren.

                Vorschlag: Prüfe, ob und welche Taste gedrückt wurde (window.event, Tastencode ist IIRC 9) und setze den Fokus nur bei Tab.

                Siechfred

                --
                Ein Selbständiger ist jemand, der bereit ist, 16 Stunden am Tag zu arbeiten, nur um nicht 8 Stunden für einen Anderen arbeiten zu müssen.
                1. Das mit onblur klang interessant, nur habe ich damit auch experimentiert, ohne auf einen grünen Zweig zu kommen.

                  Nachvollziehbar, denn onblur unterscheidet nicht danach, auf welche Art und Weise das Formularelement "verlassen" wird.

                  So wie ich das bisher verstehe, muss ich ja trotzdem den Tabulator erkennen (Wenn jemand nur woanders hinklickt, will ich ja nicht meinen Focus aufdrängen). Also, wie kann ich onblur erkennen, dass jemand in diesem Feld den Tabulator gedrückt hat und ein bestimmtes Feld fokussieren.

                  Vorschlag: Prüfe, ob und welche Taste gedrückt wurde (window.event, Tastencode ist IIRC 9) und setze den Fokus nur bei Tab.

                  Das tue ich bereits, aber da stoße ich auf diese Schwierigkeit:
                  Wie soll ich den Eventhandler setzen? Denn ich will in ja eigentlich für das Input-Feld setzen, das bringt aber die Schwierigkeit mit sich das der Tabulator "onkeyup" schon aus dem Feld raus ist und da kein Event mehr anzeigt. onkeydown ist Tab aber noch nicht ausgeführt. Onblur verstehe ich noch nicht.

                  Außerdem interpretieren Safari und Firefox es anscheinend unterschiedlich (Safari tabbt nach dem Fokussieren nicht weiter, FF wohl, unabhängig von return false;)

                  Vielen Dank,
                  Ruben

                  1. Wie soll ich den Eventhandler setzen?

                    Schau dir mein kleines Beispiel an. Ach, und dazu eine Korrektur: nicht onkeypress, sondern onkeydown, sonst liefert der IE keinen Tastencode für die TAB-Taste.

                    Siechfred

                    --
                    Ein Selbständiger ist jemand, der bereit ist, 16 Stunden am Tag zu arbeiten, nur um nicht 8 Stunden für einen Anderen arbeiten zu müssen.
                    1. Wie soll ich den Eventhandler setzen?
                      Schau dir mein kleines Beispiel an. Ach, und dazu eine Korrektur: nicht onkeypress, sondern onkeydown, sonst liefert der IE keinen Tastencode für die TAB-Taste.

                      Ja, das hatte ich ausprobiert, aber der Safari machte immer noch Zicken. Just for the books:

                        
                      function retabindex() {  
                       document.foo.bar1.tabIndex = 2;  
                       }  
                      function ev_init() {  
                        document.foo.bar1.onfocus = retabindex;  
                      }  
                      window.onload=ev_init;  
                      
                      

                      funktioniert bisher am besten. Ist allerdings permanent und daher nicht unbedingt das erwünschte.

              2. Moin!

                Danke, dass du das nochmal so klar aufgeschlüsselst hast, aber, auch wenn das anscheinend nicht rüberkam: Das war mir KLAR!
                (Ich habe mich anscheinend schlecht ausgedrückt, ich wollte eine Fallunterscheidung JS-Ja-Nein illustrieren).

                Wie so häufig: Die ist dein Problem natürlich klar, und uns natürlich nicht.

                Ich gehe nur davon aus, dass im Standardfall der Javascript-freie Nutzer das "neueSprache"-Feld skippen will. Finger bereits auf Tab - meinetwegen. Ergonomietechnisch erscheint mir das einfach die bessere Lösung.

                Du hast eigentlich eine ganz einfache Situation:

                Die Ausgangslage ist "kein JS". Für diese Lage mußt du eine Entscheidung für's Tab-Springen treffen: Soll dieses ominöse "Feld 3" angesprungen werden, oder nicht. Wenn ja: tabindex vergeben. Wenn nein: Kein Tabindex vergeben.

                Die dadurch geschaffene Bedienbarkeit kannst du durch Javascript nachträglich verbessern. Beispielsweise, indem du dynamisch Attributwerte von HTML-Elementen änderst/zuweist, oder indem du in die Mechanik des Focuswechsels eingreifst, oder sonst in die auftretenden Events, die durch Benutzerinteraktion auftreten. So funktioniert "unobtrusive Javascript" für gewöhnlich.

                Du hast diverse Vorschläge erhalten, wie das zu realisieren ist. Bewerten, was umsetzbar ist (auch im Kontext anderer Anwendungen) mußt du natürlich selbst.

                Einfach um auch JS auf die Schliche zu kommen, muss ich jetzt einfach VERSTEHEN, wie ich es denn realisieren könnte (und außerdem will ich es ja an anderer Stelle einsetzen).

                Das ist nun aber genau der Punkt: Javagescriptete Benutzerhilfen orientieren sich nur selten am Allgemeinfall, sondern gegen in der Regel sehr speziell auf das Detail ein. Und dein Gesamtproblem klingt auch danach, als ob hier ein komplexeres Formular mit diversen Spezialfällen einfacher bearbeitbar gemacht werden soll. Das aber bedingt offensichtlich Sonderbehandlungen - sowohl für die von dir konkretisierte Sprachauswahl, als auch für den noch nicht näher definierten Fall "an anderer Stelle".

                Wir können hier nur dann eine Gesamtlösung erarbeiten, wenn alle Randbedingungen bekannt sind. Wenn du eine Lösung für ein Detailproblem suchst, kriegst du die bestmögliche Lösung für genau dieses Detail. Wenn du eine Lösung für drei oder vier ähnliche, aber dennoch unterschiedliche Detailprobleme suchst, aber nur ein Detailproblem vorstellst, dann liegt es in der Natur der Sache, dass die Lösung nur für das eine Problem optimal paßt, für die anderen Probleme aber nicht wirklich.

                - Sven Rautenberg

                --
                "Love your nation - respect the others."
                1. Wie so häufig: Die ist dein Problem natürlich klar, und uns natürlich nicht.

                  Ich glaube oft, dass das Problem auch darin liegt, dass wir unterschiedliches voneinander wollen. Ich will Hilfe bei einem Problem, du möchtest mir sagen, wie man es richtig macht. Eigentlich liegen da keine Welten zwischen, manchmal aber schon ;-)

                  Die Ausgangslage ist "kein JS". Für diese Lage mußt du eine Entscheidung für's Tab-Springen treffen: Soll dieses ominöse "Feld 3" angesprungen werden, oder nicht. Wenn ja: tabindex vergeben. Wenn nein: Kein Tabindex vergeben.

                  Hab ich doch gesagt. Versucht zu sagen.

                  Die dadurch geschaffene Bedienbarkeit kannst du durch Javascript nachträglich verbessern. Beispielsweise, indem du dynamisch Attributwerte von HTML-Elementen änderst/zuweist, oder indem du in die Mechanik des Focuswechsels eingreifst, oder sonst in die auftretenden Events, die durch Benutzerinteraktion auftreten. So funktioniert "unobtrusive Javascript" für gewöhnlich.

                  Das ist meine erklärte Absicht.

                  Wir können hier nur dann eine Gesamtlösung erarbeiten, wenn alle Randbedingungen bekannt sind. Wenn du eine Lösung für ein Detailproblem suchst, kriegst du die bestmögliche Lösung für genau dieses Detail. Wenn du eine Lösung für drei oder vier ähnliche, aber dennoch unterschiedliche Detailprobleme suchst, aber nur ein Detailproblem vorstellst, dann liegt es in der Natur der Sache, dass die Lösung nur für das eine Problem optimal paßt, für die anderen Probleme aber nicht wirklich.

                  Durchaus. Deswegen habe ich auch geschrieben

                  Ich bin auch dankbar für einen anderen Ansatz, allerdings will ich dieses Script in anderer Verkleidung auch an anderer Stelle verwenden, wo ein anderer Ansatz wohl kaum möglich ist.

                  Damit wollte ich erreichen, dass mir vor allem bei der Browser-Schwierigkeit geholfen wird.
                  Den nicht näher definierten Fall zog ich sozusagen als Hilfsmittel heran, um zu illustrieren, dass ich vor allem dieses Script ans Laufen kriegen will und nicht den Workaround.

                  Danke für deine Zeit,
                  Ruben

              3. Hier noch ein kleines Beispiel:

                Javascript:

                function storeKeycode(e) {  
                  if (!e) e = window.event;  
                  if (e.which) {  
                    window.storedCode = e.which;  
                  }  
                  else if (e.keyCode) {  
                    window.storedCode = e.keyCode;  
                  }  
                }  
                  
                function testForTab() {  
                  if(window.storedCode == 9) document.foo.bar2.focus();  
                }  
                  
                function ev_init() {  
                  document.onkeypress = storeKeycode;  
                  document.foo.bar.onblur = testForTab;  
                  document.foo.bar.focus();  
                }
                

                Und das verkürzte HTML dazu:

                <body onload="ev_init()">  
                <form name="foo">  
                  <input tabindex="1" type="text" name="bar" value="nix"><br>  
                  <input tabindex="2" type="text" name="bar1" value="da"><br>  
                  <input tabindex="3" type="text" name="bar2" value="">  
                </form>  
                </body>
                

                Befindest du dich in Eingabefeld "bar" und drückst den Tabulator, landest du in Eingabefeld "bar2". Bei deaktiviertem Javascript zählt die via tabindex festgelegte Reihenfolge.

                Siechfred

                --
                Ein Selbständiger ist jemand, der bereit ist, 16 Stunden am Tag zu arbeiten, nur um nicht 8 Stunden für einen Anderen arbeiten zu müssen.
                1. Vielen Dank!

                  Der Trick war also, den Tabulator auf Dokument-Ebene auszulesen und somit alle Zeitpunktschwierigkeiten zu umgehen.
                  Ich hab mal dran gedacht, aber war mir zu unsicher, ob nicht doch mein Fehler woanders liegt.
                  Der Safari zickt zwar noch, aber der Firefox führt es immerhin schon aus. Ich übernehme hier :-)

                  1. Der Safari zickt zwar noch, aber der Firefox führt es immerhin schon aus.

                    Es könnte (wie beim IE) am verwendeten Eventhandler liegen, siehe mein Korrekturposting.

                    Siechfred

                    --
                    Ein Selbständiger ist jemand, der bereit ist, 16 Stunden am Tag zu arbeiten, nur um nicht 8 Stunden für einen Anderen arbeiten zu müssen.
        2. Hi Cheatah,

          Nein, aber es gibt 2, 3 und 4. Wenn 3 nicht angesprungen werden kann, wohin gelangt man wohl, wenn man in 2 die Tabulator-Taste drückt?

          das erinnert mich ...
          Vor Jahren kursierte mal ein Screenshot einer MS-Word-Fehlermeldung, die eine Eingabe mit folgendem Hinweis quittierte:

          "2 ist kein gültiger Wert.
            Geben Sie eine Zahl zwischen 1 und 3 ein."

          Ciao,
           Martin

          --
          Niemand lebt allein von seinen Träumen.
          Aber wer träumt, lebt noch.