Barrierefreies Webdesign ein zugängliches und nutzbares Internet gestalten

Tri-State-Checkbox veröffentlicht in 2014zuletzt bearbeitet in

HTML-Beispiel mit der indeterminate-Eigenschaft

Welches Gemuese essen Sie?

Hinweise

Wichtig: Das Ergebnis ist nicht barrierefrei, weil der Zwischenzustand "teilweise aktiviert" eine rein visuelle Vermittlung des Zustands ist. Browser stellen den Zwischenzustand außerdem unterschiedlich und manchmal gar nicht dar.

3 Screenshots einer Tri-State-Checkbox mit nicht markierter Checkbox, Checkbox mit einem kleinen Quadrat und Checkbox mit einem horizontalem Strich

Von links nach rechts: Safari (iOS), Internet Explorer und Chrome

Weitere Links

HTML

<div class="tristate">
  <p class="tristate-anweisung">Welches Gemuese essen Sie?</p>
  <p class="tristate-checkbox" data-label="Ich esse alle Gemüsesorten"></p>
  <div class="tristate-optionen">
    <p><label><input type="checkbox" name="checkbox1" value="1" checked>Kartoffel</label></p>
    <p><label><input type="checkbox" name="checkbox2" value="1" checked>Möhren</label></p>
    <p><label><input type="checkbox" name="checkbox3" value="1" checked>Broccoli</label></p>
    <p><label><input type="checkbox" name="checkbox4" value="1">Rosenkohl</label></p>
    <p><label><input type="checkbox" name="checkbox5" value="1">Aubergine</label></p>
    <p><label><input type="checkbox" name="checkbox6" value="1">Bohnen</label></p>
  </div>
</div>

JavaScript (jQuery)

function tristateInit() {
var instructionClass = 'tristate-anweisung',
  widgetClass = 'tristate-checkbox',
  optionsClass = 'tristate-optionen';
$( '.tristate' ) .each( function() {
  var $instruction = $( this ) .children( '.' + instructionClass ),
   $options = $( this ) .children( '.' + optionsClass ) .find('p>label>input[type="checkbox"]' ),
    $widget = $( this ) .children( '.' + widgetClass );
    addInstructions( $instruction, $( this ) .children( '.' +optionsClass ) );
    addTriStateCheckbox( $widget );
  var $tristate = $widget .find( '[type="checkbox"], [role="checkbox"]' ),
   tristateNewValue = checkOptions( $options );
   addTriStateEvents( $tristate, $options );
   setTriStateValue ( $tristate, tristateNewValue );
   addOptionsEvents ( $tristate, $options );
  })
}

function addInstructions( $instruction, $optionsGroup ) {
  $optionsGroup .attr( 'aria-label', $instruction .text() );
  $instruction .append( ' Wählen Sie alle oder keine Optionen mit dem ersten Kontrollkästchen aus. Wenn Sie einzelne Antworten mit den darauffolgenden Kontrollkästchen wählen, wird das erste Kontrollkästchen automatisch aktualisiert.' );
}

function addTriStateCheckbox( $widget ) {
  var tristateLabel = $widget .attr( 'data-label' );
  $widget .html( '<label><input type="checkbox">' + tristateLabel + '</label>' )
          .removeAttr( 'data-label' );
}

function addTriStateEvents ( $tristate, $options ) {
$tristate .change( function() {
  var tristateValue = $tristate .prop( 'checked' );
   if ( tristateValue === true ) {
    $options .prop( 'checked', true );
    }
   else {
    $options .prop( 'checked', false );
    }
    $tristate .prop( 'indeterminate', false );
  })
}

function addOptionsEvents ( $tristate, $options ) {
  $options .change( function() {
    var tristateNewValue = checkOptions( $options );
    setTriStateValue ( $tristate, tristateNewValue );
  });
}

function checkOptions( $options ) {
  var all = 'true', none = 'true';
  $options .each( function() {
    if ( $( this ) .prop( 'checked' ) === true ) {
      none = 'false';
    }
    else if ( $( this ) .prop( 'checked' ) === false ) {
      all = 'false';
    }
  })
    if (all == 'true' ) {
      return 'true';
    }
    else if ( none == 'true' ) {
      return 'false';
    }
    else {
      return 'mixed';
    }
}

function setTriStateValue ( $tristate, tristateNewValue ) {
  if (tristateNewValue === 'true' ) {
    $tristate .prop ({
      'checked': true,
  'indeterminate': false
    });
  }
  else if (tristateNewValue === 'false' ) {
    $tristate .prop ({
      'checked': false,
      'indeterminate': false
    });
  }
  else if (tristateNewValue === 'mixed' ) {
$tristate .prop( 'indeterminate', true );
  }
}
tristateInit();

CSS

.tristate-optionen{
margin-left:1.8em;
}