Indeterminate Checkboxes (Unbestimmte Checkboxen)

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Checkbox-Eingabefelder können nur zwei Zustände haben: ausgewählt oder nicht ausgewählt. Sie können jeden Wert haben, aber sie übermitteln diesen Wert (ausgewählt) oder nicht (nicht ausgewählt) bei einer Formularübermittlung. Der Standard ist nicht ausgewählt. Sie können das in HTML wie folgt steuern

<!-- Default to unchecked -->
<input type="checkbox">

<!-- Default to checked, XHTML -->
<input type="checkbox" checked="checked" />

<!-- Default to checked, HTML5 -->
<input type="checkbox" checked>

Visuell gibt es tatsächlich drei Zustände, in denen sich eine Checkbox befinden kann: ausgewählt, nicht ausgewählt oder unbestimmt. Sie sehen so aus

Hier sind einige Dinge, die Sie über unbestimmte Checkboxen wissen sollten

Sie können eine Checkbox nicht über HTML unbestimmt machen. Es gibt kein Attribut für unbestimmt. Es ist jedoch eine Eigenschaft von Checkboxen, die Sie über JavaScript ändern können.

var checkbox = document.getElementById("some-checkbox");
checkbox.indeterminate = true;

oder im jQuery-Stil

$("#some-checkbox").prop("indeterminate", true); // prop is jQuery 1.6+

Der unbestimmte Zustand ist nur visuell. Die Checkbox hat immer noch entweder den Status ausgewählt oder nicht ausgewählt. Das bedeutet, dass der visuelle unbestimmte Zustand den tatsächlichen Wert der Checkbox verbirgt, also sollte das in Ihrer Benutzeroberfläche Sinn ergeben!

Wie die Checkboxen selbst, **sieht der unbestimmte Zustand in verschiedenen Browsern unterschiedlich aus.** Hier ist Opera 11.50 auf Mac

Anwendungsfall

Der Grund, warum ich das schreibe, ist, dass mir gerade ein Anwendungsfall für diesen Zustand aufgefallen ist: verschachtelte Checkboxen. Jede Checkbox kann Kind-Checkboxen haben. Wenn alle diese Kinder ausgewählt sind, kann sie ausgewählt werden. Wenn keines ausgewählt ist, ist sie nicht ausgewählt. Wenn *einige* davon ausgewählt sind, befindet sie sich in einem unbestimmten Zustand (in diesem Fall symbolisch „teilweise“ ausgewählt).

Hier ist das in jQuery

Siehe den Pen Indeterminate Checkboxes von Chris Coyier (@chriscoyier) auf CodePen.

Hier ist eine alternative jQuery-Version von TheNotary.

Und hier ist eine reine JavaScript-Version von Jakob Eriksen

Siehe den Pen
Indeterminate Checkboxes (Vanilla JS)
von jakob-e (@jakob-e)
auf CodePen.

Und ein paar alternative Ansätze von Alvaro Montoro , Bramus, Gridbuilder, Lewin Probst und Jason Wilson.

Verwendung von StimulusJS von Stephen Margheim

Siehe den Pen
checkbox family
von Stephen Margheim (@smargh)
auf CodePen.

Rotation zwischen den Zuständen

Jon Stuebe hat mit der Idee experimentiert, den Zustand mit einem Klick zwischen nicht ausgewählt, unbestimmt und ausgewählt zu wechseln. Hier ist etwas jQuery, um das zu tun

var $check = $("input[type=checkbox]"), el;
$check
   .data('checked',0)
   .click(function(e) {
       
        el = $(this);
                
        switch(el.data('checked')) {
            
            // unchecked, going indeterminate
            case 0:
                el.data('checked',1);
                el.prop('indeterminate',true);
                break;
            
            // indeterminate, going checked
            case 1:
                el.data('checked',2);
                el.prop('indeterminate',false);
                el.prop('checked',true);                
                break;
            
            // checked, going unchecked
            default:  
                el.data('checked',0);
                el.prop('indeterminate',false);
                el.prop('checked',false);
                
        }
        
    });

Siehe den Pen Rotate Through Indeterminate Checkboxes von Chris Coyier (@chriscoyier) auf CodePen.

Der Leser Casual Trash hat mir eine bibliotheksfreie und wesentlich prägnantere Version zum Durchwechseln aller drei visuellen Zustände geschickt, die das `readonly`-Attribut nutzt, das Checkbox-Eingabefelder haben können.

<!-- Inline click handler, just for demo -->
<input type="checkbox" id="cb1" onclick="ts(this)">
function ts(cb) {
  if (cb.readOnly) cb.checked=cb.readOnly=false;
  else if (!cb.checked) cb.readOnly=cb.indeterminate=true;
}

Siehe den Pen Rotate Through Indeterminate Checkboxes von Chris Coyier (@chriscoyier) auf CodePen.

  • Johnny Simpson
    Permalink to comment#

    Oh mein Gott! Ich wusste nicht einmal, dass das möglich ist! Großartig :D

  • Roflo
    Permalink to comment#

    Chris,

    Das Label für „Short Things“ scheint falsch zu sein
    <label for="tall">Short Things</label>
    Sollte es nicht `<label for="short">...` sein?

    Auf jeden Fall... das Klicken auf den Text „Short Things“ aktiviert die Checkbox „Tall Things“.

  • jason t
    Permalink to comment#

    Funktioniert auf meinem Nexus One mit Android nicht.

  • Amit
    Permalink to comment#

    Toller Artikel und ein großartiges neues Design für die Website, Chris! Wirklich großartiges Design.

  • Jason
    Permalink to comment#

    Neues Design sieht gut aus, mag die Buttons und den Regenbogen-Hover aber nicht

  • Akbar
    Permalink to comment#

    Schönes neues Design!

  • Michael
    Permalink to comment#

    Ich frage mich, ob es irgendeine Möglichkeit gibt, diesen unbestimmten Status nach einer Formularübermittlung abzurufen.
    Dies könnte nützlich sein, wenn Sie eine Art Umfrage interpretieren, um festzustellen, ob die Checkbox überhaupt angeklickt wurde (auf wahr oder falsch gesetzt) oder ob sie vollständig ignoriert wurde und somit nicht einmal angeklickt wurde.

    Chris, hast du Informationen dazu?

    Ich wette, das wäre auch für Wufoo von Vorteil. ;)

  • Freelance Website Development
    Permalink to comment#

    Boolesche Eingabefelder mit mehr als 2 Zuständen?
    Das ist fast so schlimm wie durch Null zu teilen!

  • sourav
    Permalink to comment#
     $(function() {
              // Apparently click is better chan change? Cuz IE?
        $("input[type=checkbox]").click(function() {
    
            var el = $(this); 
    
            el
                .parent()
                .find("ul input[type=checkbox]")
                .prop("indeterminate", false)
                .prop("checked", el.prop("checked"));
    
            var siblings = el.parent().siblings().add(el.parent());
    
            if (siblings.length > 1) {
    
            var parents = el.parents(); 
    
              var numChecked = 0; 
    
              siblings.find("> input[type=checkbox]").each(function(i) {
                  if ($(this).prop("checked")) {
                      numChecked++;
                  }
              });            
    
              if ((numChecked > 0) && (numChecked  level) {
                            el
                            .parent().parent().parents()
                            .find("> input[type=checkbox]")
                            .prop("indeterminate", true)
                            .prop("checked", false);
                            level++;
                      }
              } else if (numChecked == 0) {
                      var level = 0;
                      while (parents.length > level) {
                            el
                            .parent().parent().parents()
                            .find("> input[type=checkbox]")
                            .prop("indeterminate", false)
                            .prop("checked", false);
                            level++;
                      }
              } else {
                      var level = 0;
                      while (parents.length > level) {
                            el
                            .parent().parent().parents()
                            .find("> input[type=checkbox]")
                            .prop("indeterminate", false)
                            .prop("checked", true);
                            level++;
                      }
              }
    
            }
        });
        });
  • nirja sahini
    Permalink to comment#

    Es funktioniert gut in Firefox und IE, aber ich habe Probleme mit Chrome. Gibt es eine schnelle Lösung?

  • Matt
    Permalink to comment#

    Sieht gut aus, das einzige, was mir aufgefallen ist, ist, wenn man auf eine unbestimmte Checkbox klickt, verliert sie ihre „grüne“ Füllung/ihren Zustand, was meiner Meinung nach kein erwünschtes Verhalten ist?

  • Jessy
    Permalink to comment#

    Hallo,

    Ich würde gerne dasselbe finden, aber mit einer „init“-Funktion. Dann, wenn einige Checkboxen „vorab“ ausgewählt sind (Formular vorab ausfüllen, z. B.) => es bestimmt die Zustände der übergeordneten Boxen vor jeder Änderung, mit niedriger zu hoher Priorität.

    Irgendwelche Ideen?

    Vielen Dank!!!

  • yurii
    Permalink to comment#

    Ein Fehler im Zusammenhang mit dem unsachgemäßen Installationsattribut `indeterminate` wurde behoben und der Code optimiert. Jetzt hat er ein kleineres Volumen und unnötige Zyklen wurden entfernt.

    $(function() {
    $('input:checkbox').change(function(e){
    var check = $(this).prop('checked'),
    container = $(this).parent();
    
    container.find('input:checkbox').prop({
    indeterminate: false,
    checked: check
    });
    
    function checkSiblings(el) {
    var all = true,
    parent = el.parent().closest('li');
    el.siblings().each(function(){
    return all = ($(this).children('input:checkbox').prop('checked') === check);
    });
    if(all){
    parent.children('input:checkbox').prop({
    indeterminate: false,
    checked: check
    });
    checkSiblings(parent);
    }else{
    el.parents('li').children('input:checkbox').prop({
    indeterminate: true,
    checked: false
    });
    }
    }
    checkSiblings(container);
    });
    
    });
    
  • Lokesh
    Permalink to comment#

    Wie erreicht man das für das einfache HTML?

    <input type="checkbox" value="something" indeterminate/>
    das funktioniert nicht
    <input type="checkbox" value="something" indeterminate="true"/>
    auch dieses nicht
    <input type="checkbox" value="something" indeterminate="indeterminate"/>
    Wie kann man es zum Funktionieren bringen.

  • Sameer
    Permalink to comment#

    Der Code schlägt in einem Szenario für meinen Code fehl, ich weiß nicht warum……

    http://jsfiddle.net/sameerengg/84ajt/6/
    Bitte helfen Sie.

  • Dieser Kommentarbereich ist geschlossen. Wenn Sie wichtige Informationen teilen möchten, kontaktieren Sie uns bitte.