Tri-State-Kontrollkästchen in HTML?

167

Es gibt keine Möglichkeit, eine dreistufige Check-Schaltfläche (Ja, Nein, Null) in HTML zu haben, oder?

Gibt es einfache Tricks oder Workarounds, ohne das Ganze selbst rendern zu müssen?

Pekka
quelle
Was ist funktionell der Unterschied zwischen "Nein" und "Null" in Ihrer Verwendung?
David sagt, Monica
5
Schauen Sie sich die Antworten unten an (außer meinen). "Null" bedeutet so etwas wie "Keine Antwort" ...
Franz
2
Genau. Es ist ein Element mit Vorfahren und "null" bedeutet "übergeordneten Wert verwenden".
Pekka
7
Eine alternative Verwendung für ein Kontrollkästchen mit drei Zuständen ist das Suchen / Filtern. Nehmen wir zum Beispiel an, ich habe eine Schnittstelle zum Durchsuchen einer Liste von Gebrauchtwagen. Eine der Suchoptionen kann sein, ob das Auto ein Schiebedach hat oder nicht. Die drei Zustände könnten wie folgt verwendet werden: Nur Autos mit einem Schiebedach zeigen Nur Autos ohne Schiebedach zeigen Beide anzeigen Nun, dies kann sicherlich auf verschiedene Arten gehandhabt werden ... wir könnten uns ein Dropdown-Menü geben oder wir könnten ein Set verwenden von drei Optionsfeldern ... aber ein Kontrollkästchen mit drei Zuständen (das entweder leer ist, ein grünes Häkchen hat oder ein rotes x enthält) ist auch eine gute Lösung.
Mir
3
Bei einer Liste von Kontrollkästchen mit einem Kontrollkästchen am Anfang der Liste ist es hilfreich, alle verbleibenden Kontrollkästchen zu aktivieren oder zu deaktivieren. Wenn alle aktiviert sind, kann das Kontrollkästchen Header dies widerspiegeln. Wenn alle deaktiviert sind, kann das Kontrollkästchen Header dies auch widerspiegeln. Wenn die Liste eine Kombination aus aktivierten und nicht aktivierten Kontrollkästchen enthält, bietet das Anzeigen des Kontrollkästchens für die Kopfzeile in einem Zwischenzustand eine visuelle Rückmeldung. Dieses Kontrollkästchen für den Header würde niemals einen Wert enthalten - es ist nur ein visueller Hinweis und eine Hilfe für die Benutzeroberfläche. Es wäre auch praktisch, das Kopf-Kontrollkästchen zwischen allen drei Zuständen umschalten zu können.
Jason

Antworten:

121

Bearbeiten - Dank Janus Troelsens Kommentar habe ich eine bessere Lösung gefunden:

HTML5 definiert eine Eigenschaft für aufgerufene Kontrollkästchen indeterminate

Siehe w3c Referenzhandbuch . Um das Kontrollkästchen visuell unbestimmt erscheinen zu lassen, setzen Sie es auf true:

element.indeterminate = true;

Hier ist Janus Troelsens Geige . Beachten Sie jedoch Folgendes:

  • Der indeterminateStatus kann nicht im HTML-Markup festgelegt werden, sondern nur über Javascript (siehe diesen JSfiddle-Test und diesen ausführlichen Artikel in CSS-Tricks ).

  • Dieser Status ändert den Wert des Kontrollkästchens nicht, sondern ist nur ein visueller Hinweis, der den tatsächlichen Status der Eingabe maskiert.

  • Browsertest: Arbeitete für mich in Chrome 22, Firefox 15, Opera 12 und zurück zu IE7. In Bezug auf mobile Browser werden Android 2.0-Browser und Safari Mobile unter iOS 3.1 nicht unterstützt.

Vorherige Antwort

Eine andere Alternative wäre, mit der Transparenz des Kontrollkästchens für den Status "Einige ausgewählte" zu spielen (wie dies in früheren Versionen bei Google Mail der Fall war ). Es erfordert etwas Javascript und eine CSS-Klasse. Hier habe ich ein bestimmtes Beispiel aufgeführt, das eine Liste mit überprüfbaren Elementen und ein Kontrollkästchen behandelt, mit dem alle / keine ausgewählt werden können. Dieses Kontrollkästchen zeigt den Status "Einige ausgewählt" an, wenn einige der Listenelemente ausgewählt sind.

Wenn ein Kontrollkästchen mit einer ID #select_allund mehrere Kontrollkästchen mit einer Klasse angegeben sind .select_one,

Die CSS-Klasse, die das Kontrollkästchen "Alle auswählen" ausblendet, lautet wie folgt:

.some_selected {
    opacity: 0.5;
    filter: alpha(opacity=50);
}

Der JS-Code, der den Tri-Status des Kontrollkästchens Alle auswählen behandelt, lautet wie folgt:

$('#select_all').change (function ()
{
    //Check/uncheck all the list's checkboxes
    $('.select_one').attr('checked', $(this).is(':checked'));
    //Remove the faded state
    $(this).removeClass('some_selected');
});

$('.select_one').change (function ()
{
  if ($('.select_one:checked').length == 0)
      $('#select_all').removeClass('some_selected').attr('checked', false);
  else if ($('.select_one:not(:checked)').length == 0)
      $('#select_all').removeClass('some_selected').attr('checked', true);
  else
      $('#select_all').addClass('some_selected').attr('checked', true);
});

Sie können es hier versuchen: http://jsfiddle.net/98BMK/

Hoffentlich hilft das!

pau.moreno
quelle
1
In Chrome v35 getestet und das Kontrollkästchen "Alle" aktiviert nur die anderen Kontrollkästchen beim ersten Klicken. Danach können nur noch die anderen Kontrollkästchen deaktiviert werden. In dieser Version behoben
rdans
2
.prop('checked', ...)sollte anstelle von verwendet werden .attr('checked', ...).
Luna
Ich habe die Fehler behoben, auf die Ross hingewiesen hat. neue Geige hier .
Mike DeSimone
48

Sie können das indeterminateIDL-Attribut von HTML für inputElemente verwenden.

Ms2ger
quelle
3
Laut Bert Bos in einer E-Mail von 2002 (< lists.w3.org/Archives/Public/www-dom/2002JanMar/0014.html> ) haben IE / Win und IE / Mac dies seit Version 4 unterstützt. Firefox scheint dies zu tun habe es in Version 3.6 implementiert. Es scheint auch in Safari im Jahr 2008 implementiert worden zu sein. Ich denke, das macht nicht viele Endbenutzer.
Ms2ger
Verwenden Sie stattdessen diese URL ( help.dottoro.com/ljuocesd.php ). Es zeigt, wer es unterstützt (jeder Baroper), seit wann und zeigt visuell an, was es ist. Die Leute haben Angst vor den Spezifikationsseiten. +1 für diese Nicht-Plugin-Lösung
Hashbrown
16

Mein Vorschlag würde verwenden

  • drei geeignete Unicode-Zeichen für die drei Zustände, z. B. ❓, ✅, ❌
  • ein Klartext-Eingabefeld (Größe = 1)
  • keine Grenze
  • schreibgeschützt
  • keinen Cursor anzeigen
  • Klicken Sie auf den Handler, um zwischen den drei Zuständen umzuschalten

Siehe Beispiele unter:

/**
 *  loops thru the given 3 values for the given control
 */
function tristate(control, value1, value2, value3) {
  switch (control.value.charAt(0)) {
    case value1:
      control.value = value2;
    break;
    case value2:
      control.value = value3;
    break;
    case value3:
      control.value = value1;
    break;
    default:
      // display the current value if it's unexpected
      alert(control.value);
  }
}
function tristate_Marks(control) {
  tristate(control,'\u2753', '\u2705', '\u274C');
}
function tristate_Circles(control) {
  tristate(control,'\u25EF', '\u25CE', '\u25C9');
}
function tristate_Ballot(control) {
  tristate(control,'\u2610', '\u2611', '\u2612');
}
function tristate_Check(control) {
  tristate(control,'\u25A1', '\u2754', '\u2714');
}
<input type='text' 
       style='border: none;' 
       onfocus='this.blur()' 
       readonly='true' 
       size='1' 
       value='&#x2753;' onclick='tristate_Marks(this)' />

<input style="border: none;"
       id="tristate" 
       type="text"  
       readonly="true" 
       size="1" 
       value="&#x2753;"  
       onclick="switch(this.form.tristate.value.charAt(0)) { 
     case '&#x2753': this.form.tristate.value='&#x2705;'; break;  
     case '&#x2705': this.form.tristate.value='&#x274C;'; break; 
     case '&#x274C': this.form.tristate.value='&#x2753;'; break; 
       };" />  

Wolfgang Fahl
quelle
4

Sie können Funkgruppen verwenden, um diese Funktionalität zu erreichen:

<input type="radio" name="choice" value="yes" />Yes
<input type="radio" name="choice" value="No" />No
<input type="radio" name="choice" value="null" />null
Franz
quelle
1
Ich weiß das, danke. :) Ich verwende derzeit Auswahlmöglichkeiten, aber das Formular wird etwas unübersichtlich.
Pekka
1
Wie genau würde der dritte Staat dann überhaupt aussehen? Genau wie wenn das Kontrollkästchen deaktiviert ist? Wie möchten Sie das auslösen?
Franz
3

Ich denke, dass der semantischste Weg darin besteht, readonlyAttribute zu verwenden, die Checkbox-Eingaben haben können. Kein CSS, keine Bilder usw.; eine eingebaute HTML-Eigenschaft!

Siehe Geige:
http://jsfiddle.net/chriscoyier/mGg85/2/

Wie hier im letzten Trick beschrieben: http://css-tricks.com/indeterminate-checkboxes/

Webinan
quelle
Gute Lösung, aber leider funktioniert dies nicht im IE (Test mit Version 11), da schnellere Klicks nicht mehr erkannt werden.
ViRuSTriNiTy
3

Hier ist ein ausführbares Beispiel mit dem genannten indeterminateAttribut :

const indeterminates = document.getElementsByClassName('indeterminate');
indeterminates['0'].indeterminate  = true;
<form>
  <div>
    <input type="checkbox" checked="checked" />True
  </div>
  <div>
    <input type="checkbox" />False
  </div>
  <div>
    <input type="checkbox" class="indeterminate" />Indeterminate
  </div>
</form>

Führen Sie einfach das Code-Snippet aus, um zu sehen, wie es aussieht.

gil.fernandes
quelle
2

Wie bei @Franz Antwort können Sie dies auch mit einer Auswahl tun. Zum Beispiel:

<select>
  <option></option>
  <option value="Yes">Yes</option>
  <option value="No">No</option>
</select>

Hiermit können Sie auch einen konkreten Wert angeben, der mit dem Formular gesendet wird. Ich denke, dass bei einer unbestimmten Javascript-Version des Kontrollkästchens der Unterstreichungswert des Kontrollkästchens gesendet wird.

Zumindest können Sie es als Rückruf verwenden, wenn Javascript deaktiviert ist. Geben Sie ihm beispielsweise eine ID und ändern Sie sie im Ladeereignis in die Javascript-Version des Kontrollkästchens mit unbestimmtem Status.

PhoneixS
quelle
2

Neben allen oben genannten gibt es jQuery-Plugins, die ebenfalls hilfreich sein können:

für einzelne Kontrollkästchen:

Kontrollkästchen für baumartiges Verhalten:

BEARBEITEN Beide Bibliotheken verwenden das Kontrollkästchen-Attribut ' unbestimmt ', da dieses Attribut in HTML5 nur zum Stylen dient ( https://www.w3.org/TR/2011/WD-html5-20110113/number-state.html#checkbox-state) ) wird der Nullwert niemals an den Server gesendet (Kontrollkästchen können nur zwei Werte haben).

Um diesen Wert an den Server senden zu können, habe ich ausgeblendete Gegenstückfelder erstellt, die beim Senden des Formulars mit etwas Javascript ausgefüllt werden. Auf der Serverseite müssten Sie natürlich diese Gegenstückfelder anstelle der ursprünglichen Kontrollkästchen aktivieren.

Ich habe die erste Bibliothek (eigenständige Kontrollkästchen) verwendet, in der Folgendes wichtig ist:

  • Initialisieren Sie die aktivierten, nicht aktivierten und unbestimmten Werte
  • Verwenden Sie die Funktion .val (), um den tatsächlichen Wert abzurufen
  • Kann nicht arbeiten .state (wahrscheinlich mein Fehler)

Hoffentlich hilft das.

Frank Sebastià
quelle
1

Unter Bezugnahme auf die Antwort von @BoltClock ist hier meine Lösung für eine komplexere rekursive Methode:

http://jsfiddle.net/gx7so2tq/2/

Es ist vielleicht nicht die schönste Lösung, aber es funktioniert gut für mich und ist ziemlich flexibel.

Ich benutze zwei Datenobjekte, die den Container definieren:

data-select-all="chapter1"

und die Elemente selbst:

data-select-some="chapter1"

Beide haben den gleichen Wert. Die Kombination beider Datenobjekte in einem Kontrollkästchen ermöglicht Unterebenen, die rekursiv gescannt werden. Daher werden zwei "Hilfs" -Funktionen benötigt, um den Änderungsauslöser zu verhindern.

MFH
quelle
1

Hier noch ein Beispiel mit einfacher jQuery und Eigenschaft data-checked:

 $("#checkbox")
  .click(function(e) {
    var 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);

    }
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label><input type="checkbox" name="checkbox" value="" checked id="checkbox"> Tri-State Checkbox </label>

Ravi Makwana
quelle
1

Da ich so etwas brauchte - ohne Plug-In für skriptgenerierte Kontrollkästchen in einer Tabelle ..., kam ich zu folgender Lösung:

<!DOCTYPE html>
<html>
<body>

Toto <input type="checkbox" id="myCheck1" onclick="updateChkBx(this)" /><br />
Tutu <input type="checkbox" id="myCheck2" onclick="updateChkBx(this)" /><br />
Tata <input type="checkbox" id="myCheck3" onclick="updateChkBx(this)" /><br />
Tete <input type="checkbox" id="myCheck4" onclick="updateChkBx(this)" /><br />

<script>
var chkBoxState = [];

function updateChkBx(src) {
  var idx = Number(src.id.substring(7)); // 7 to bypass the "myCheck" part in each checkbox id
  if(typeof chkBoxState[idx] == "undefined") chkBoxState[idx] = false; // make sure we can use stored state at first call
  
  // the problem comes from a click on a checkbox both toggles checked attribute and turns inderminate attribute to false
  if(chkBoxState[idx]) {
    src.indeterminate = false;
    src.checked = false;
    chkBoxState[idx] = false;
  }
  else if (!src.checked) { // passing from checked to unchecked
    src.indeterminate = true;
    src.checked = true; // force considering we are in a checked state
    chkBoxState[idx] = true;
  }
}
// to know box state, just test indeterminate, and if not indeterminate, test checked
</script>

</body>
</html>
Faeldihn
quelle
0

Es ist möglich, HTML-Formularelemente zu deaktivieren - würde das nicht reichen? Ihre Benutzer würden es in einem von drei Zuständen sehen, dh aktiviert, deaktiviert und deaktiviert, die ausgegraut und nicht anklickbar wären. Für mich scheint das ähnlich zu sein wie "null" oder "nicht zutreffend" oder was auch immer Sie in diesem dritten Zustand suchen.

AmbroseChapel
quelle
Sehr gute Idee, aber ich brauche den Benutzer, um wieder darauf klicken zu können. Ich befürchte, dass ich bei einem deaktivierten Kontrollkästchen Probleme beim Auslösen von Ereignissen usw. habe.
Pekka
Sie können weiterhin den Wert eines deaktivierten Kontrollkästchens sehen, was für den Benutzer verwirrend ist, wenn der Wert nicht wichtig ist.
Janus Troelsen
Ich denke, 'null' soll den Benutzer darstellen, der keine Antwort auf die Frage liefert. Dies bedeutet nicht unbedingt, dass die Frage nicht zutreffend ist.
BDSL