czRIpper: Radiobutton abwählen/demarkieren/unchecken

Hallo,

da ich jetzt stundenlange Recherche zum Thema "Wie kann ich einen Radiobutton beim zweiten Klick wieder abwählen?" hinter mir und keine zufriedenstellende Lösung gefunden habe,

(die meinsten sagen sowas geht nicht, oder nur mit Doppelklick, oder Radiobuttons seien nicht dafür vorgesehen [letzteres mag zwar stimmen, aber es gibt manchmal Situationen, in denen man sowas haben möchte, z.B. auf Kundenwunsch])

werde ich nun hier meine selbstgeschriebene Lösung posten, damit sich andere nicht so ewig lang den A... absuchen müssen, ohne ein Ergebnis zu erhalten:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Radiotest</title>

<script type="text/javascript">
 var klick = 0;
 var radiotype =0;
 function uncheck(radio){
  if (radiotype == radio){
   klick = klick + 1;
   if (klick % 2 == 0) {
    radio.checked = false;
   } else
    radio.checked = true;
  }else{
   radiotype = radio;
  }
 }
</script>
</head>

<body>
<form>
 <input type="radio" name="radio" id="radio1" onclick="javascript:uncheck(radio1)">
 <input type="radio" name="radio" id="radio2" onclick="javascript:uncheck(radio2)">
</form>
</body>
</html>

Greetz

  1. Hi

    Das ist genau der Sinn von Radiobuttons. Wenn du etwas zum ab und anwählen brauchst, sind Checkboxen die richtige wahl. Alternativ kannst ja auch einen Radiobutton "Nichts anwählen" einfügen, also z.b.

    • Blau
    • Grün
    • Keines von beidem

    gruss

    chris

    1. Das ist genau der Sinn von Radiobuttons. Wenn du etwas zum ab und anwählen brauchst, sind Checkboxen die richtige wahl. Alternativ kannst ja auch einen Radiobutton "Nichts anwählen" einfügen, also z.b.

      • Blau
      • Grün
      • Keines von beidem

      Wie schon gesagt: wenn es ein Kundenwunsch ist, abwählbare Radiobuttons zu implementieren, dann sollte dieser in Anbetracht der Devise "Der Kunde ist König" auch getan werden, egal, wofür Radiobuttons ursprünglich mal vorgesehen waren. Und das mit dem "Nichts anwählen" ist ja auch nicht wirklich eine 'schöne' Lösung.

      Gruß und nicht für ungut

      1. Wie schon gesagt: wenn es ein Kundenwunsch ist, abwählbare Radiobuttons zu implementieren, dann sollte dieser in Anbetracht der Devise "Der Kunde ist König" auch getan werden, egal, wofür Radiobuttons ursprünglich mal vorgesehen waren. Und das mit dem "Nichts anwählen" ist ja auch nicht wirklich eine 'schöne' Lösung.

        Gruß und nicht für ungut

        Hi

        Selbstverständlich ist der Kunde König - Aber es ist deine Aufgabe als Fachkundiger dem Kunden eine saubere / korrekte Lösung vorzuschlagen / abzuliefern und nicht einfach jeden Kundenwusch 1:1 nachzubasteln. Man nennt das dann Beratung.

        Radios deselektieren ist eine sehr unschöne Lösung, weil es niemand erwartet. Nirgends kann man Radios deselektieren. Man kommt gar nicht auf die Idee es zu versuchen. -> Das ist übrigens eine der wichtigsten Regeln der UI Programmierung: überasche deinen User nicht.

        gruss

        chris

        1. Selbstverständlich ist der Kunde König - Aber es ist deine Aufgabe als Fachkundiger dem Kunden eine saubere / korrekte Lösung vorzuschlagen / abzuliefern und nicht einfach jeden Kundenwusch 1:1 nachzubasteln. Man nennt das dann Beratung.

          Radios deselektieren ist eine sehr unschöne Lösung, weil es niemand erwartet. Nirgends kann man Radios deselektieren. Man kommt gar nicht auf die Idee es zu versuchen. -> Das ist übrigens eine der wichtigsten Regeln der UI Programmierung: überasche deinen User nicht.

          Ist es so schwer zu verstehen, dass man das eben manchmal trotzdem braucht? Lasst mal eure Fantasie spielen ;)

          In meinem aktuellen Fall ist es aber aufgrund des generellen Layouts der Website nicht schön, an einer Stelle Checkboxes zu verwenden, obwohl die ganze andere Seite nur Radiobuttons beinhaltet. (klar wäre mein Problem sofort gelöst, wenn mir jemand sagt, wie ich runde Checkboxes mache ;) )
          Und das Abwählen der Radios ist in diesem Falle auch nur dazu da, dass man eine Radiogroup abwählen kann, wenn man in dieser aus Versehen einen Radio gechecked hat.

          Lasst mal gut sein nun, ich habe die für mich beste Lösung in diesem Forum durch euch gefunden. Danke dafür

          Greetz

          1. Hallo czRIpper,

            In meinem aktuellen Fall ist es aber aufgrund des generellen Layouts der Website nicht schön, an einer Stelle Checkboxes zu verwenden, obwohl die ganze andere Seite nur Radiobuttons beinhaltet.

            Verzichtest du etwa in deiner Küche auf eine Pfanne, nur weil da sonst nur Kochtöpfe sind?

            Über eine zusätzliche Abwahlmöglichkeit bei Radiobuttons kann man meines Erachtens noch streiten, aber dass so viele "Designer" gegen den ursprünglich aus ihrer eigenen Ecke kommenden Grundsatz Form follows function verstoßen, ist mittlerweile eine echte Seuche.

            Du kannst Checkboxen, indem du ihnen dasselbe Namensattribut gibst, auch dazu bringen, sich wie Radiobuttons zu verhalten, aber für sich gegenseitig ausschließende Auswahlmöglichkeiten nimmt man nun mal Radiobuttons und für sich gegenseitig nicht ausschließende Checkboxen, basta!

            Ansonsten wäre das genauso unverständlich wie ein mit Deppenleerzeichen geschriebenes Wort,

            genauso unbrauchbar wie eine Zitruspresse für den Mars. Zitruspresse für den Mars

            Gruß Gernot

          2. gruss czRIpper,

            ... (klar wäre mein Problem sofort gelöst, wenn mir jemand sagt, wie ich runde Checkboxes mache ;) )

            ... guckst Du hier: »maßgeschneiderte Checkboxen und Radiobuttons«.
               lies aber bitte auch die beiden abschliessend gestellten fragen des
               eben verlinkten postings.

            so long - peterS. - pseliger@gmx.net

            --
            »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
            Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
            ie:( fl:) br:> va:( ls:& fo:) rl:| n3;} n4:} ss:} de:µ js:} mo:? zu:]
      2. Wie schon gesagt: wenn es ein Kundenwunsch ist, abwählbare Radiobuttons zu implementieren, dann sollte dieser in Anbetracht der Devise "Der Kunde ist König" auch getan werden, ....

        Was in dem Falle ja i.d.R. auch für die Kunden des Kundens gelten sollte, aber es ist meistens zu müßig Fachfremden sowas zu erklären, vor allem wenn's Leute sind die so sehr am Design hängen.

        Struppi.

        --
        Javascript ist toll (Perl auch!)
  2. Hallo,

    die Lösung funktioniert anscheinend nicht zuverlässig - oder ich verstehe nicht, wie sie funktionieren soll. Anfangs muss ich zweimal klicken, damit die Auswahl aufgehoben wird, im Folgenden nur einmal. Bei der Auswahl des anderen Radio-Buttons dann wieder erst zweimal usw.

    Mathias

    1. Hallo,

      Schnellschuss meinerseits:

      <html><head>  
      <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">  
      <title>Radiotest</title>  
      <script type="text/javascript">  
      [code lang=javascript]window.onload = init;  
      function init () {  
       var inputs = document.getElementsByTagName("input");  
       for (var i = 0, input; input = inputs[i]; i++) {  
        if (input.type != "radio")  
         continue;  
        input.onclick = click;  
       }  
      }  
      function click (e) {  
       if (typeof this.checkedStatus == "undefined")  
        this.checkedStatus = false;  
       if (this.checkedStatus) {  
        this.checked = false;  
        this.checkedStatus = false;  
        if (window.ChromeWindow)  
         return false;  
       } else {  
        if (window.lastCheckedRadio && window.lastCheckedRadio !== this) {  
         window.lastCheckedRadio.checkedStatus = false;  
        }  
        window.lastCheckedRadio = this;  
        this.checkedStatus = true;  
       }  
      }
      

      </script>
      </head>
      <body>
      <form>
      <p><input type="radio" name="radio" value="a"> a</p>
      <p><input type="radio" name="radio" value="b"> b</p>
      </form>
      </body>
      </html>[/code]

      IE 6, Opera 9, Firefox 2.
      Browsererkennung (ChromeWindow = Gecko-Browser) scheint mir notwendig.
      Verwendung von ordentlichen label-Elementen funktioniert dabei natürlich nicht, da müsste man noch eine Verknüpfungslogik zwischen label und input einbauen, bis dahin werden nur Direktklicks auf die Radio-Buttons gewertet.

      Daran weiterarbeiten will ich eigentlich nicht, produktiv einsetzen würde ich ein solches Script ebensowenig - man wird es wahrscheinlich nie robust und kompatibel kriegen. Solches JavaScript gehört eigentlich aus der Welt geschafft, weil es einem morgen um die Ohren fliegen kann. Dafür halte ich die Funktion für zu essentiell, als dass ich einem solchen Script vertrauen würde. Sowieso halte ich die Problemstellung für ein Nicht-Problem (bessere, hundertprozentig zuverlässige Lösung existiert bereits) und das Unternehmen daher für nutzlosen, in Hinsicht auf Funktionsfähigkeit aussichtslosen JavaScript-Einsatz.

      Mathias

      1. if (window.lastCheckedRadio && window.lastCheckedRadio !== this) {
           window.lastCheckedRadio.checkedStatus = false;

        Da müsste man noch den Radionamen einbinden, eigentlich auch den Formularnamen, sonst funktionieren mehrere Radio-Button-Sets nicht korrekt.

  3. Hi,

    <script type="text/javascript">
    var klick = 0;
    var radiotype =0;
    function uncheck(radio){
      if (radiotype == radio){
       klick = klick + 1;
       if (klick % 2 == 0) {
        radio.checked = false;
       } else
        radio.checked = true;
      }else{
       radiotype = radio;
      }
    }
    </script>
    </head>

    <body>
    <form>
    <input type="radio" name="radio" id="radio1" onclick="javascript:uncheck(radio1)">
    <input type="radio" name="radio" id="radio2" onclick="javascript:uncheck(radio2)">
    </form>
    </body>
    </html>

    hm, das geht doch auch viel einfacher:

    function uncheck(r)
    {
       if(typeof(r.c) == "undefined") r.c = r.checked;
       r.c = !r.c;
       r.checked = !r.c;
    }
    </script>

    <input type="radio" onclick="uncheck(this)">

    musste da auch kurz rumprobieren. FF und IE verhalten sich ohne das r.c sondern stattdessen r.checked = !r.checked unterschiedlich.

    Außerdem funktioniert deine Lösung bei mir auch erst beim zweiten Klick.

    Gruß
    Christian

    1. Hallo Christian,

      hm, das geht doch auch viel einfacher:

      function uncheck(r)
      {
         if(typeof(r.c) == "undefined") r.c = r.checked;
         r.c = !r.c;
         r.checked = !r.c;
      }
      </script>

      <input type="radio" onclick="uncheck(this)">

      Außerdem funktioniert deine Lösung bei mir auch erst beim zweiten Klick.

      Wenn man bei deiner Lösung zuerst den ersten, dann den zweiten und dann wieder den ersten Radiobutton anwählt, ist auch keiner mehr angewählt, was ja wohl nicht sein soll.

      Meine Lösung:

        
      function checkUncheck(obj) {  
         myRadioGroup = obj.form[obj.name];  
         if (myRadioGroup.checkedBefore) {  
            for (i=1; i<=myRadioGroup.length; i++ ){  
                if(myRadioGroup.checkedBefore == i){  
                   myRadioGroup[i-1].checked = false;  
                   myRadioGroup.checkedBefore = null;  
                }  
            }  
         } else {  
            for (i=0; i<myRadioGroup.length; i++ ){  
                if(obj==myRadioGroup[i]){  
                   myRadioGroup.checkedBefore = i+1;  
                   return;  
                }  
            }  
         }  
      }  
      
      

      Gruß Gernot

    2. Hallo,

      hm, das geht doch auch viel einfacher:

      Das funktioniert bei mir im Firefox 2.0 gar nicht und berücksichtigt nicht das Durchschalten durch mehrere Radiobuttons.

      Mathias

  4. gruss czRIpper,

    ...

    function uncheck(radio){

    if (radiotype == radio){
      klick = klick + 1;
      if (klick % 2 == 0) {
       radio.checked = false;
      } else
       radio.checked = true;
    }else{
      radiotype = radio;
    }
    }

    
    > ...  
    > ~~~html
    
    <input type="radio" name="radio" id="radio1" onclick="javascript:uncheck(radio1)">  
    
    > <input type="radio" name="radio" id="radio2" onclick="javascript:uncheck(radio2)">
    
    

    -------------------------------------------------------^^^^^^^^^^^
      das pseudoprotokoll >>javascript:<< hat in einem eventhandler nichts verloren.

    ausserdem ist es schon aus gruenden der wartbarkeit und pflege nicht ratsam,
      jedem element diesen handler explizit schon im html-code zuzuweisen.

    deshalb versuch ich mich mal, nicht nur zu Deinem besten, sondern moeglichst zum
      wohle aller, die spaeter ueber die archivsuche auf diesen thread stossen werden,
      in einer *plug and play* loesung unter beruecksichtigung folgender quellen:

    »Der sinnvolle Einsatz von JavaScript« - SELFHTML aktuell Weblog / Mathias Schäfer (molily) / 17.12.2005
      »DOM-getter und array-iteratoren - scripte schneller entwickeln« - SELFHTML Forumsarchiv / peterS. / 13.03.2007

    ~~~javascript var enableRadiogroupUncheck = function () {

    Array.filter(document.getElementsByTagName("input"), (function (elm/, idx, arr/) {

    return (elm.type == "radio");

    })).forEach(function (elm/, idx, arr/) {

    elm.onclick = function () {

    this.checked = !this.mostRecentlyChecked;

    Array.filter(this.form.elements[this.name], (function (elm/, idx, arr/) {
              return (elm.type == "radio");
            })).forEach(function (elm/, idx, arr/) {
              elm.mostRecentlyChecked = false;
            });
            this.mostRecentlyChecked = this.checked;
          };

    elm.mostRecentlyChecked = elm.checked;
        });
      };
      if (window.addEventListener) {
        window.addEventListener("load", enableRadiogroupUncheck, true);
      } else if (window.attachEvent) {
        window.attachEvent("onload", enableRadiogroupUncheck);
      }

      
      
      durch eingabe folgender zeile in die location-bar eines halbwegs modernen mozillas  
      (natuerlich auf einer formularseite), ist dieser ansatz auch sofort ueberpruefbar:  
      
      javascript:`(function () {Array.filter(document.getElementsByTagName("input"), (function (elm) {return (elm.type == "radio");})).forEach(function (elm) {elm.onclick = function () {this.checked = !this.mostRecentlyChecked;Array.filter(this.form.elements[this.name], (function (elm) {return (elm.type == "radio");})).forEach(function (elm) {elm.mostRecentlyChecked = false;});this.mostRecentlyChecked = this.checked;};elm.mostRecentlyChecked = elm.checked;});})();`{:.language-javascript}  
      
      
       so long - peterS. - pseliger@gmx.net  
      
      
    
    -- 
    »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.  
    Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - [Douglas Crockford](http://javascript.crockford.com/)  
      
    ie:( fl:) br:> va:( ls:& fo:) rl:| n3;} n4:} ss:} de:µ js:} mo:? zu:]
    
    1. Hallo Peter,

      also dein Skript funktioniert zwar im Firefox 2.0.0.3, aber sonst in keinem meiner Browser, weder IE7, noch Opera 9.00, noch im dem Firefox verwandten Netscape 7.1.

      ausserdem ist es schon aus gruenden der wartbarkeit und pflege nicht ratsam,
        jedem element diesen handler explizit schon im html-code zuzuweisen.

      Ebenso wenig ratsam könnte es sein, dieses ungewöhnliche Radiobutton-Verhalten unterschiedslos allen Radiobuttons eines Dokuments bei onload zuzuweisen.

      Als Aufruf beim Inline-onclick-Handler reicht ja auch ein schlichtes "uncheck(this)". Das ist sprechend genug, sodass damit selbst Javascript-Noobs bei der Pflege nicht überfordert sein dürften.

      Gruß Gernot

      1. Hallo,

        also dein Skript funktioniert zwar im Firefox 2.0.0.3, aber sonst in keinem meiner Browser, weder IE7, noch Opera 9.00, noch im dem Firefox verwandten Netscape 7.1.

        Du musst auch vorher http://www.pseliger.de/jsExtendedApi/jsApi.bundles.DOM.getters.js einbinden.

        Wenn ich mich nicht täusche sieht das Script ohne die JavaScript-1.7-Funktionen (etwas vereinfacht) so aus:

        window.onload = init;  
        function init () {  
         var inputs = document.getElementsByTagName("input");  
         for (var i = 0, input; input = inputs[i]; i++) {  
          if (input.type != "radio")  
           continue;  
          input.onclick = radioclick;  
          input.mostRecentlyChecked = input.checked;  
         }  
        }  
        function radioclick () {  
         this.checked = !this.mostRecentlyChecked;  
         var arr = this.form.elements[this.name];  
         for (var i = 0; i < arr.length; i++) {  
          arr[i].mostRecentlyChecked = false;  
         }  
         this.mostRecentlyChecked = this.checked;  
        }
        

        Mathias

        1. Hallo molily,

          Du musst auch vorher http://www.pseliger.de/jsExtendedApi/jsApi.bundles.DOM.getters.js einbinden.

          Oh, das übersah ich. Mein Einwand, dass es vielleicht nicht gewünscht sein könnte, allen Radiobuttons dieses Verhalten zuzuweisen, bleibt aber bestehen.

          window.onload = init;

          function init () {
          var inputs = document.getElementsByTagName("input");
          for (var i = 0, input; input = inputs[i]; i++) {
            if (input.type != "radio")
             continue;
            input.onclick = radioclick;
            input.mostRecentlyChecked = input.checked;
          }
          }
          function radioclick () {
          this.checked = !this.mostRecentlyChecked;
          var arr = this.form.elements[this.name];
          for (var i = 0; i < arr.length; i++) {
            arr[i].mostRecentlyChecked = false;
          }
          this.mostRecentlyChecked = this.checked;
          }

            
          Ja, das funktioniert auch ohne Einbindung von Peters Bibliothek.  
            
          Gruß Gernot
          
      2. gruss Gernot,

        also dein Skript funktioniert zwar im Firefox 2.0.0.3, aber sonst in
        keinem meiner Browser, weder IE7, noch Opera 9.00, noch im dem Firefox
        verwandten Netscape 7.1.

        gut, alles andere haette mich sehr verwundert - aus diesem grund leitete
           ich mein posting ja auch mit folgenden worten ein:

        ... deshalb versuch ich mich mal, ...  in einer *plug and play*
        loesung unter beruecksichtigung folgender quellen:
        ...
        »DOM-getter und array-iteratoren - scripte schneller entwickeln« - SELFHTML Forumsarchiv / peterS. / 13.03.2007

        nur moderne mozillas bringen von haus aus die neuen array-methoden mit.
           aber das macht nichts, denn es steht jedem offen, sich fuer eine der
           inzwischen vielfach vorhandenen implementierungen zu entscheiden, die
           diese fehlenden funktionalitaeten auch fuer die sonst *benachteiligten*
           browser zur verfuegung stellen - damit ist der weg frei hin zur schoenen
           neuen welt des ausdrucksstarken dom-scriptings.

        Ebenso wenig ratsam könnte es sein, dieses ungewöhnliche Radiobutton-Verhalten
        unterschiedslos allen Radiobuttons eines Dokuments bei onload zuzuweisen.

        richtig. ich hab' ja auch nur einen moeglichst universalen ansatz in die
           runde schmeissen wollen, um Euch wiedermal diesen ganzen iteratoren-/
           accessoren-kram schmackhaft zu machen.

        so long - peterS. - pseliger@gmx.net

        --
        »Because objects in JavaScript are so flexible, you will want to think differently about class hierarchies.
        Deep hierarchies are inappropriate. Shallow hierarchies are efficient and expressive.« - Douglas Crockford
        ie:( fl:) br:> va:( ls:& fo:) rl:| n3;} n4:} ss:} de:µ js:} mo:? zu:]
        1. Hallo Peter,

          gut, alles andere haette mich sehr verwundert - aus diesem grund leitete
             ich mein posting ja auch mit folgenden worten ein:

          ... deshalb versuch ich mich mal, ...  in einer *plug and play*
          loesung unter beruecksichtigung folgender quellen:
          ...

          Das war für mich nicht deutlich genug, zumal dein Posting von vor zwei Wochen -Schande über mich!- an mir vorbeigegangen ist:

          »DOM-getter und array-iteratoren - scripte schneller entwickeln« - SELFHTML Forumsarchiv / peterS. / 13.03.2007

          Aber jetzt hat sich mir deine Library ins Hirn gebrannt und bestimmt habe ich demnächst auch Verwendung dafür.

          Danke!

          Gruß Gernot