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( ... );