Formulare/Ausgrauen: disabled vs readonly

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche
Oft ist es aus Gründen der Übersicht nützlich Eingabefelder oder Formulareteile auszugrauen, damit sie (noch) nicht ausgefüllt werden können.

Hierfür gibt es zwei Attribute disabled und readonly. Auf den ersten Blick scheinen beide Attribute gleich - sie deaktivieren Formularfelder und verhindern eine Eingabe.

Allerdings zeigen sich die Unterschiede beim Absenden und in der Bedienung:

readonly disabled
Inhalt kann geändert werden nein nein
Formulardaten werden übertragen ja nein
fokussierbar ja nein
per Tab anspringbar ja nein
Eventhandler auf Klick, Doppelklick, Hover reagieren ja nein

Anwendungsbeispiel disabled

So wäre es beispielsweise sinnvoll, Angaben zum Typ des gefahrenen Autos dynamisch auszugrauen, wenn der Anwender ankreuzt, dass er gar kein Auto besitzt.

ausgegrautes Formularfeld ansehen …
  <form action="" name="testform">
     
   <fieldset id="auto">
     <legend>Besitzen Sie ein Auto?</legend>
     <label for="ja"> ja</label><input type="radio" name="auto" id="ja" >
     <label for="nein">nein</label><input type="radio" name="auto" id="nein" checked> 
   </fieldset>  

   <fieldset id="typ" disabled>
     <legend>Falls ja, was für ein Auto?</legend>
     <input type="radio" name="typenklasse" id="klein" ><label for="klein"> Kleinwagen</label>
     <input type="radio" name="typenklasse" id="kombi" value="kombi"><label for="kombi"> Kombi</label>
     <input type="radio" name="typenklasse" id="limo" value="limousine"><label for="limo"> Limousine</label>
     <input type="radio" name="typenklasse" id="sport" value="sportwagen"><label for="sport"> Sportwagen</label>
     <input type="radio" name="typenklasse" id="klein" value="kbus"><label for="bus"> Kleinbus</label>
     <input type="radio" name="typenklasse" id="sonstiges" value="andere"><label for="sonstiges"> sonstiges</label>
   </fieldset>

</form>

Das Beispiel enthält ein Formular mit zwei Gruppen von Radio-Buttons. In der ersten Gruppe kann der Anwender auswählen, ob er ein Auto besitzt oder nicht. In der zweiten Gruppe kann er, falls er ein Auto besitzt, den Typ angeben. Da die zweite Gruppe nur interessant ist, wenn der Anwender die Frage "Haben Sie ein Auto?" mit "ja" beantwortet hat, werden die Radio-Buttons der zweiten Gruppe mit dem disabled-Attribut ausgegraut.

Pseudoklasse :disabled

Beachten Sie: Beim Firefox ist das Eingabefeld zwar nicht benutzbar, aber nicht vom aktiven Eingabefeld zu unterscheiden. Mit CSS kann das Feld auch optisch ausgegraut werden:
Kennzeichnung durch CSS
  fieldset:disabled {
    color: whitesmoke;
	background: #ddd;
	cursor: not-allowed;
  }
  fieldset:disabled label {
    color: #999;
  }

Über die dynamische Pseudoklasse :disabled wird das betroffene Element selektiert und mit CSS gekennzeichnet:

  • (Text)-Farbe und Hintergrund werden grau
  • Der cursor erhält bei :hover über dem ausgegrauten Eingabefeld ein not-allowed-Symbol.

Umschalten mit JavaScript

Sobald das JavaScript die Elemente sperrt, werden die Radiobuttons und auch die dazugehörenden label ausgegraut.

Beispiel
document.querySelector('#auto').addEventListener('click', abfrage);

function abfrage () { 
  if (document.querySelector('#ja').checked == true) {
    document.querySelector('#typ').disabled = false;
  } else {
    document.querySelector('#typ').disabled = true;   
  }
}

Die Radio-Buttons der ersten Gruppe haben einen Event-Handler click. Beim Klicken auf einen der beiden Radio-Buttons (im fieldset mit der ID auto) wird die Funktion abfrage() ausgeführt. Sie fragt zunächst mit einer bedingten Anweisung ab, ob die Eigenschaft checked des ersten Radio-Buttons einen positiven Wert hat. Falls ja, wird disabled auf false gesetzt und so entfernt.

Im anderen Falle, der nur eintritt, wenn auf nein geklickt wurde, wird disabled wieder auf true gesetzt und per CSS ausgegraut.


Beachte: Man kann sich fragen, warum im Beispiel die Wahl des Event-Handlers auf click und nicht auf change fiel. In der Tat ist change im Allgemeinen passender, um JavaScript auszuführen, wenn sich der Wert eines Formularelements ändert.
Allerdings starten die gängigen Browser auch dann ein Klick-Ereignis, wenn nicht die Maus, sondern die Tastatur zum Ändern des Radio-Buttons verwendet wurde. Somit funktioniert das Beispiel auch bei der Bedienung des Formulars ausschließlich über die Tastatur oder durch einen Touch.

Multistep-Formular

Das Beispiel enthält ein Formular mit zwei Radio-Buttons. Erst wenn Benutzer die AGB akzeptieren, wird das ausgegraute Formular freigeschaltet.

Multistep-Formular ansehen …
<form> 
   <fieldset id="agb">
   <input type="radio" name="agb" id="akzeptieren"  value="ok" ><label for="akzeptieren">unsere AGB akzeptieren</label>

   <input type="radio" name="agb" id="ablehnen" value="no" checked><label for="ablehnen">ablehnen</label>
   </fieldset>
   
   <fieldset id="persAngaben" disabled>
     <label for="input1">Benutzername</label> <input value="Hans" id="input1">
 
     <label for="input2">Passwort</label> <input type="password" value="Passwort" id="input2">
 
     <button type="button" onclick="alert('Hallo und herzlich willkommen!')">Einloggen!</button>
   </fieldset>
 </form>

Das Beispiel enthält ein Formular mit zwei Radio-Buttons. Erst wenn Benutzer die AGB akzeptieren, wird das ausgegraute Formular freigeschaltet.

Script, um disabled zu entfernen
  document.addEventListener('DOMContentLoaded', function () {
    document.getElementById('ablehnen').checked = true;
    document.querySelector('#agb').addEventListener('click', weiter);
 
    function weiter() {	  
      if (document.getElementById('akzeptieren').checked  == true) {
        document.getElementById('persAngaben').removeAttribute('disabled');
      }
      if (document.getElementById('ablehnen').checked  == true) {
        document.getElementById('persAngaben').setAttribute('disabled','disabled');
      }
    }
  
  });

document.getElementById('ablehnen').checked = true; setzt den Ablehnen-Button auch beim Neuladen wieder auf true , d.h. auf AGB ablehnen.

Mit addEventListener wird an das fieldset mit der id agb ein Event-Handler angehängt, der bei einem Klick die Funktion weiter() aufruft.

In dieser Funktion wird überprüft, ob der Akzeptieren-Radio-Button angeklickt wurde. Dann wird das ausgegraute fieldset aktiviert, indem das disabled-Attribut mit der Methode removeAttribute entfernt wird. Wenn der Benutzer wieder auf "Ablehnen" geht, wird das disabled-Attribut mit setAttribute wieder gesetzt.

Anwendungsbeispiel readonly

Das readonly-Attribut legt fest, dass der vorgeschlagene Wert nur ausgelesen und nicht verändert werden können soll. So kann man die aktell gültige AGB dem Formular beifügen und durch den Nutzer bestätigen lassen. Text und Bestätigung werden beim Absenden des Formulars im Auftrag mitgesendet.

Ausgrauen mit readonly ansehen …
<fieldset id="agb">
    <textarea id="agb-text" name="agb-text" readonly cols="80" rows="18" > I. Geltungsbereich

1. Diese Verkaufsbedingungen gelten ausschließlich gegenüber Unternehmern, juristischen Personen des öffentlichen Rechts oder öffentlich-rechtlichen Sondervermögen im Sinne von Paragraf 310 Absatz 1 BGB. Entgegenstehende oder von unseren Verkaufsbedingungen abweichende Bedingungen des Bestellers erkennen wir nur an, wenn wir ausdrücklich schriftlich der Geltung zustimmen.
2. Diese Verkaufsbedingungen gelten auch für alle zukünftigen Geschäfte mit dem Besteller, soweit es sich um Rechtsgeschäfte verwandter Art handelt (vorsorglich sollten die Verkaufsbedingungen in jedem Fall der Auftragsbestätigung beigefügt werden)
3. Im Einzelfall getroffene, individuelle Vereinbarungen mit dem Käufer (einschließlich Nebenabreden, Ergänzungen und Änderungen) haben in jedem Fall Vorrang vor diesen Verkaufsbedingungen. Für den Inhalt derartiger Vereinbarungen ist, vorbehaltlich des Gegenbeweises, ein schriftlicher Vertrag bzw. unsere schriftliche Bestätigung maßgebend.
...
</textarea>
    <input type="radio" name="agb" id="akzeptieren"  value="ok" ><label for="akzeptieren">unsere AGB akzeptieren</label><br>
    <input type="radio" name="agb" id="ablehnen" value="no" checked><label for="ablehnen">ablehnen</label>
    </fieldset>

Das readonly-Attribut kann gesetzt werden, um Nutzer davon abzuhalten den Wert des Eingabefeldes zu verändern, bevor eine bestimmte Bedingung (wie das Ankreuzen einer Checkbox mit z. B. einer AGB) erfüllt ist.

Schreibweisen readonly, :read-only und readOnly

Das readonly-Attribut hat einige Entsprechungen:

  • Falls die Bedingung erfüllt ist, kann das Attribut mit der JavaScript-Eigenschaft elements.readOnly geändert werden. Dabei wird es in CamelCase zwingend mit großem O geschrieben!
  • Um ein Element mit diesem Attribut zu selektieren, kann man entweder
    • die Attributpräsenz mit [readonly] selektieren oder
    • die Pseudoklasse :read-only verwenden.
      Hierbei wird ein Bindestrich eingefügt.
Hinweis:
Du solltest keinesfalls darauf vertrauen, dass der Inhalt des Eingabefeldes tatsächlich unverändert abgeschickt wird, da es grundsätzlich Möglichkeiten gibt, die Wirkung des readonly-Attributs zu umgehen!