Form-Elemente aktivieren und deaktivieren

Problem

Ihre Bestellform verfügt über Felder für die Rechnungs- und die Lieferadresse. Sie wollen dem Anwender entgegenkommen und bieten eine Checkbox an, mit der angegeben werden kann, ob beide Adressen gleich sind. Ist die Checkbox markiert, sollten die Felder für die Rechnungsadresse deaktiviert werden:

<fieldset id="shippingInfo">
    <legend>Lieferadresse</legend>

    <label for="shipName">Name</label>
    <input name="shipName" id="shipName" type="text" />

    <label for="shipAddress">Adresse</label>
    <input name="shipAddress" id="shipAddress" type="text" />
</fieldset>

<fieldset id="billingInfo">
    <legend>Rechnungsadresse</legend>

    <label for="sameAsShipping">Wie Lieferadresse</label>
    <input name="sameAsShipping" id="sameAsShipping" type="checkbox" 
value="sameAsShipping" />

    <label for="billName">Name</label>
    <input name="billName" id="billName" type="text" />

    <label for="billAddress">Adresse</label>
    <input name="billAddress" id="billAddress" type="text" />
</fieldset>

Lösung 1

Wollen Sie nur die Felder für die Rechnungsadresse deaktivieren, genügt das Verwenden der jQuery-Methoden .attr() und .removeAttr() , wenn das Event change ausgelöst wird:

// Checkbox "sameAsShipping" selektieren und auf das change-Event warten
$('#sameAsShipping').change(function(){

    if( this.checked ){
        // alle Texteingabefelder innerhalb von billingInfo selektieren und deaktivieren
        $('#billingInfo input:text').attr('disabled','disabled');

    } else {
        // alle Texteingabefelder innerhalb von billingInfo selektieren und aktivieren
        $('#billingInfo input:text').removeAttr('disabled');
    }

}).trigger('change'); // change() schließen und einmalig auslösen

Lösung 2

Das Selektieren einer Checkbox und das Deaktivieren der Form-Felder kann ausreichen, um dem Anwender entgegenzukommen, aber noch besser wäre es, die Felder für die Rechnungsadresse mit denen der Lieferadresse vorzubefüllen.

Der erste Teil dieser Lösung entspricht in seiner Struktur der aus der vorigen Lösung. Aber neben dem Deaktivieren der Felder für die Rechnungsadresse befüllen wir sie auch mit Daten aus der Lieferadresse. Der folgende Code geht davon aus, dass die <fieldset>-Elemente für Rechnungs- und Lieferadresse die gleiche Anzahl und die gleiche Reihenfolge von Feldern enthalten:

// Checkbox "sameAsShipping" selektieren und auf das change-Event warten
$('#sameAsShipping').change(function(){
    if( this.checked ){
        // alle Texteingabefelder innerhalb von billingInfo selektieren, sie deaktivieren und durchlaufen
        $('#billingInfo input:text').attr('disabled',
'disabled').each(function(i){

                // Lieferadressen-Feld finden, das zum Rechnungsadressen-Feld gehört
                var valueFromShippingInput = 
$('#shippingInfo input:text:eq('+i+')').val();
                // Wert für Rechnungsadress-Feld aus Lieferadress-Feld setzen
                $(this).val( valueFromShippingInput );

        }); // Ende von each()

    } else {
        // alle Texteingabefelder innerhalb von billingInfo selektieren und aktivieren
        $('#billingInfo input:text').removeAttr('disabled');
    }
}).trigger('change'); // change() schließen und einmalig auslösen

Der zweite Teil dieser Lösung aktualisiert die Felder für die Rechnungsadresse automatisch, wenn der Anwender Informationen in die Felder für die Lieferadresse eingibt – aber nur, wenn die Rechnungsadresse deaktiviert ist:

// Texteingabefelder von shippingInfo finden und auf die Events keyup und change lauschen
$('#shippingInfo input:text').bind('keyup change',function(){

    // wenn die Checkbox "sameAsShipping" markiert ist
    if ( $('#sameAsShipping:checked').length ){

        // Texteingabefeld ermitteln
        var i = $('#shippingInfo input:text').index( this );
        var valueFromShippingInput = $(this).val();

        $('#billingInfo input:text:eq('+i+')').val( valueFromShippingInput );
    }

}); // Ende von bind()

Diskussion

In der vorigen Lösung habe ich den Selektor input:text genutzt, um zu verhindern, dass die Checkbox selbst deaktiviert wird.

Mit .trigger('change') wird das Event .change() direkt ausgeführt. Damit wird der Status der Checkbox initial geprüft, falls sie automatisch markiert ist. Zudem wird so der Tatsache Rechnung getragen, dass Firefox und andere Browser sich den Status von Radio-Buttons und Checkboxen beim Aktualisieren der Seite merken.

Was geschieht hier, wenn JavaScript abgeschaltet ist? Sie sollten die Checkbox standardmäßig per CSS verbergen. Fügen Sie dann per JavaScript einen Klassennamen zu einem Eltern-Element hinzu, mit dem die vorige CSS-Regel überschrieben wird. Im folgenden Beispiel-Code habe ich ein zusätzliches <div> um die Checkbox und das Label gelegt, so dass man beides leicht verbergen kann:

<style type="text/css" title="text/css">
 #sameAsShippingWrapper { display:none; }
 .jsEnabled #sameAsShippingWrapper { display:block }
</style>

...

// wenn das HTML-DOM bereit ist
$(document).ready(function(){
    $('form').addClass('jsEnabled');
});

...

<form>
 ...
 <div id="sameAsShippingWrapper">
   <label for="sameAsShipping">Same as Shipping</label>
   <input name="sameAsShipping" id="sameAsShipping" type="checkbox" ... />
 </div>
 ....
</form>

Statt die Checkbox per CSS zu verbergen und per JavaScript anzuzeigen können Sie auch die Checkbox selbst per JavaScript dem DOM hinzufügen. Ich bevorzuge es zwar, HTML, CSS und JavaScript getrennt zu halten, aber manchmal ist die erstere die bessere Lösung:

var html_label = '<label for="sameAsShipping">Same as Shipping</label>';
var html_input = '<input name="sameAsShipping" id="sameAsShipping" type="checkbox" 
value="sameAsShipping" />';

$( html_label + html_input ).prependTo('#billingInfo").change( ... ).trigger( ... );
JQuery Kochbuch
titlepage.xhtml
part0000.html
part0001.html
part0002_split_000.html
part0002_split_001.html
part0002_split_002.html
part0003_split_000.html
part0003_split_001.html
part0003_split_002.html
part0003_split_003.html
part0003_split_004.html
part0003_split_005.html
part0003_split_006.html
part0003_split_007.html
part0004_split_000.html
part0004_split_001.html
part0004_split_002.html
part0004_split_003.html
part0004_split_004.html
part0004_split_005.html
part0004_split_006.html
part0004_split_007.html
part0004_split_008.html
part0004_split_009.html
part0004_split_010.html
part0004_split_011.html
part0004_split_012.html
part0004_split_013.html
part0004_split_014.html
part0004_split_015.html
part0004_split_016.html
part0004_split_017.html
part0004_split_018.html
part0005_split_000.html
part0005_split_001.html
part0005_split_002.html
part0005_split_003.html
part0005_split_004.html
part0005_split_005.html
part0005_split_006.html
part0005_split_007.html
part0005_split_008.html
part0005_split_009.html
part0005_split_010.html
part0005_split_011.html
part0005_split_012.html
part0005_split_013.html
part0006_split_000.html
part0006_split_001.html
part0006_split_002.html
part0006_split_003.html
part0006_split_004.html
part0006_split_005.html
part0006_split_006.html
part0006_split_007.html
part0006_split_008.html
part0006_split_009.html
part0006_split_010.html
part0007_split_000.html
part0007_split_001.html
part0007_split_002.html
part0007_split_003.html
part0007_split_004.html
part0007_split_005.html
part0007_split_006.html
part0007_split_007.html
part0007_split_008.html
part0007_split_009.html
part0007_split_010.html
part0007_split_011.html
part0008_split_000.html
part0008_split_001.html
part0008_split_002.html
part0008_split_003.html
part0008_split_004.html
part0008_split_005.html
part0008_split_006.html
part0008_split_007.html
part0008_split_008.html
part0008_split_009.html
part0008_split_010.html
part0008_split_011.html
part0008_split_012.html
part0008_split_013.html
part0008_split_014.html
part0008_split_015.html
part0008_split_016.html
part0008_split_017.html
part0008_split_018.html
part0008_split_019.html
part0008_split_020.html
part0008_split_021.html
part0008_split_022.html
part0009_split_000.html
part0009_split_001.html
part0009_split_002.html
part0009_split_003.html
part0009_split_004.html
part0009_split_005.html
part0009_split_006.html
part0009_split_007.html
part0009_split_008.html
part0009_split_009.html
part0009_split_010.html
part0010_split_000.html
part0010_split_001.html
part0010_split_002.html
part0010_split_003.html
part0010_split_004.html
part0010_split_005.html
part0010_split_006.html
part0010_split_007.html
part0010_split_008.html
part0010_split_009.html
part0010_split_010.html
part0010_split_011.html
part0011_split_000.html
part0011_split_001.html
part0011_split_002.html
part0011_split_003.html
part0011_split_004.html
part0011_split_005.html
part0011_split_006.html
part0011_split_007.html
part0011_split_008.html
part0011_split_009.html
part0011_split_010.html
part0011_split_011.html
part0012_split_000.html
part0012_split_001.html
part0012_split_002.html
part0012_split_003.html
part0012_split_004.html
part0012_split_005.html
part0012_split_006.html
part0012_split_007.html
part0012_split_008.html
part0013_split_000.html
part0013_split_001.html
part0013_split_002.html
part0013_split_003.html
part0013_split_004.html
part0013_split_005.html
part0013_split_006.html
part0013_split_007.html
part0013_split_008.html
part0013_split_009.html
part0013_split_010.html
part0013_split_011.html
part0013_split_012.html
part0014_split_000.html
part0014_split_001.html
part0014_split_002.html
part0014_split_003.html
part0014_split_004.html
part0014_split_005.html
part0014_split_006.html
part0014_split_007.html
part0014_split_008.html
part0014_split_009.html
part0014_split_010.html
part0014_split_011.html
part0015_split_000.html
part0015_split_001.html
part0015_split_002.html
part0015_split_003.html
part0015_split_004.html
part0015_split_005.html
part0015_split_006.html
part0015_split_007.html
part0015_split_008.html
part0015_split_009.html
part0015_split_010.html
part0016_split_000.html
part0016_split_001.html
part0016_split_002.html
part0016_split_003.html
part0016_split_004.html
part0016_split_005.html
part0016_split_006.html
part0016_split_007.html
part0016_split_008.html
part0016_split_009.html
part0017_split_000.html
part0017_split_001.html
part0017_split_002.html
part0017_split_003.html
part0017_split_004.html
part0017_split_005.html
part0017_split_006.html
part0017_split_007.html
part0017_split_008.html
part0017_split_009.html
part0017_split_010.html
part0017_split_011.html
part0018_split_000.html
part0018_split_001.html
part0018_split_002.html
part0018_split_003.html
part0018_split_004.html
part0018_split_005.html
part0018_split_006.html
part0019_split_000.html
part0019_split_001.html
part0019_split_002.html
part0019_split_003.html
part0019_split_004.html
part0019_split_005.html
part0019_split_006.html
part0019_split_007.html
part0019_split_008.html
part0019_split_009.html
part0019_split_010.html
part0020_split_000.html
part0020_split_001.html
part0020_split_002.html
part0020_split_003.html
part0020_split_004.html
part0020_split_005.html
part0020_split_006.html
part0020_split_007.html
part0020_split_008.html
part0021_split_000.html
part0021_split_001.html
part0021_split_002.html
part0021_split_003.html
part0021_split_004.html
part0021_split_005.html
part0021_split_006.html
part0021_split_007.html
part0021_split_008.html
part0021_split_009.html
part0022.html
part0023.html
part0024.html
part0025.html